'Array[Int]'在scala中隐式转换为'Int => Int'的地方在哪里?

Where is the place that 'Array[Int]' is implicitly converted to 'Int => Int' in scala?

后面是一道题。
现在我们已经证明了 Array[Int] 可以隐式转换为 Int => Int,但是 哪里有 发生的地方呢?
显然,Int => Int 是一个函数:

scala> var fun = (i: Int) => Array(1,2,3)(i)
fun: Int => Int = <function1>

Array[Int]是一个class:

scala> var arr = Array(1,2,3)
arr: Array[Int] = Array(1, 2, 3)

但是arr可以赋值给fun:

scala> fun = arr
fun: Int => Int = WrappedArray(1, 2, 3)

反之则不行:

scala> arr = fun
<console>:34: error: type mismatch;
 found   : Int => Int
 required: Array[Int]
       arr = fun
             ^

现在,隐式 转换发生的地方在哪里?

当您将 Array(1) 分配给 Int => Int 类型的 val 时,将调用隐式转换 scala.LowPriorityImplicits#wrapIntArray

它将Array包装成ArraySeq,然后实现Function1Int => Int

既然你有 WrappedArray I'm guessing you have Scala 2.12 or earlier - Scala 2.13 has ArrayOps.

存在从ArrayWrappedArray的隐式转换(实际上是a whole family o conversions)。所以你有一个从 Array[T]WrappedArray[T].

的隐式转换

现在,WrappedArray 实现了 Scala 的各种集合特征。其中之一是 Seq 实施 PartialFunction(进而扩展 Function)。这意味着 Scala 中的所有集合都是来自某个键的函数(Int 在序列的情况下,可能是其他的在 Maps 的情况下)。这包括 WrappedArray.

因此,您对 WrappedArray 的转换会自动将 Array[T] 转换为(a 的子类型)函数 Int => T

事实上,这就是为什么你应该避免将任何集合(或在 2.13 之前可隐式转换为集合的东西,如 Array )放入隐式范围的原因:隐式范围中的集合自动成为隐式转换本身。此问题仅在 Scala 3 中得到解决,其中隐式转换变为 a separate subtype of Function interface.

but where is the place that happens?

隐式转换在必要时发生,在本例中是在赋值本身。

看看我在另一个答案中的 reify 块:

val foo: Function1[Int, Int] = Predef.wrapIntArray(Array.apply(1, 2, 3));

这就是转换,调用方法:Predef 对象中的 wrapIntArray

Obviously, Int => Int is a Function:
And Array[Int] is a class:
But arr can be assigned to fun:
Conversely, it will not work:

看来你不知道/不明白 Scala functions 也是 objects Scala 是一个 object,任何值都是 object).

所以我们不能直接将一个Array[Int]赋给一个应该是Int => Int的值;因为 Array[Int] 不是 Int => Int 的子类型(如我之前的回答所示).
但是我们可以将 Array[Int] 转换为 ArraySeq[Int],它是 Int => Int 的子类型,因此我们可以进行赋值。

相反的方法不起作用,因为 Int => Int 不是 Array[Int] 也不是 ArraySeq[Int]
请注意,这只是基本子类型,DogPet 的子类型,但 Pet 不是 Dog

的子类型

Which one is the class/trait related to Function[Int, Int]? I have checked the link you mentioned: sealed abstract class ArraySeq[+A] extends AbstractSeq[A] with IndexedSeq[A] with IndexedSeqOps[A, ArraySeq, ArraySeq[A]] with StrictOptimizedSeqOps[A, ArraySeq, ArraySeq[A]] with EvidenceIterableFactoryDefaults[A, ArraySeq, ClassTag] with Serializable

那些是类 / traits ArraySeq直接扩展的,在Scaladoc link中有一个按钮可以看到所有的supper类型您会看到 (Int) => A

中的广告

编辑

The last question is which super type does the (Int) => A come from? There are too many types ArraySeq extended.

您需要遍历层级:

  1. immutable.ArraySeq 扩展 immutable.AbstractSeq
  2. immutable.AbstractSeq 扩展 immutable.Seq
  3. immutable.Seq 扩展 collection.Seq
  4. collection.Seq 扩展 PartialFunction[Int, A]
  5. PartialFunction[Int, A] extends Function1[Int, A]