type inference in argument list in combination with setter not working

Let's imagine the following items in scope:

object Thing { 
  var data: Box[String] = Empty
}

def perform[T](setter: Box[T] => Unit) {
  // doesn't matter
}

The following fails to compile:

perform(Thing.data = _)

The error message is:

<console>:12: error: missing parameter type for expanded function ((x$1) => Thing.data = x$1)
              perform(Thing.data = _)
                                   ^
<console>:12: warning: a type was inferred to be `Any`; this may indicate a programming error.
              perform(Thing.data = _)
                                 ^

While the following compiles:

perform(Thing.data_=)

I have since surpassed this issue by creating a better abstraction, but my curiosity still remains.

Can anyone explain why this is?


Let's expand out what you're doing in the first example:

Thing.data = _

is shorthand for defining an anonymous function, which looks like:

def anon[T](x: Box[T]) {
  Thing.data = x
}

So when you call

perform(Thing.data = _)

it's the same as

perform(anon)

The problem is anon and perform take a type parameter T and at no point are you declaring what T is. The compiler can only infer type parameters in a function call from passed arguments, not from within the function body, so it cannot infer in anon that T should be String .

Notice that if you call

perform[String](Thing.data = _)

the compiler has no issue because it now knows what T should be, and if you try to use any type besides string, you'll get a type mismatch error, but the error occurs in the body of the anonymous function, not on the call to perform .

However, when you call

perform(Thing.data_=)

you are passing the method Thing.data_= , which is explicitly defined as Box[String] => Unit , so the compiler can infer perform 's type parameter because it is coming from a function argument.

链接地址: http://www.djcxy.com/p/11340.html

上一篇: 在Node.js中使用Sinon.js模拟Postgres进行单元测试

下一篇: 在参数列表中输入推理结合setter不工作