With the following code:
object Foo {
val arr: Int => Int = Array(1,2,3)
}
We can call Foo.arr(1), then get 2. However, arr in object Foo should be a Function. The arr is an instance of Class WrappedArray$ofInt, which is obviously not a Function.
I guess maybe the reason is WrappedArray$ofIntimplements apply(i: Int), because the call Array(1,2,3)(1) will be translated into Array(1,2,3).apply(1). But the following code would be error:
class Bar {
def apply(i: Int): Int = {
Array(1,2,3)(i)
}
}
object Foo {
val arr: Int => Int = new Bar() //Type mismatch:
// Required: Int => Int
// Found: Bar
}
Now, why val arr: Int => Int = Array(1,2,3) is allowed in scala?
CodePudding user response:
Array(1,2,3) is of type Array[Int], and generic type Array[T] declares a method apply(index: Int): T with signature Int => T, considering that any type with an apply method can be considered as a function of same signature, then Array[Int] is a valid Int => Int.
CodePudding user response:
The second part of your question is one of the rarest cases where you should explicitly use apply.
val elem: Int => Int = new Bar().apply(_)
Usually written as
val bar = new Bar()
val elem: Int => Int = bar(_)
or
val elem: Int => Int = x => new Bar()(x)
I vaguely remember reading somewhere the reason as "it is so" or "specification says so", can't remember which. Tried to find that post, but was not able to.
