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$ofInt
implements 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.