Home > Mobile >  Why 'val arr: Int => Int = Array(1,2,3)' is allowed in scala
Why 'val arr: Int => Int = Array(1,2,3)' is allowed in scala

Time:11-17

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.

  • Related