這是一個問題,其次是這個。
現在我們已經證明Array[Int]可以隱式轉換為Int => Int,但是發生的地方在哪里?
顯然,Int => Int是一個函式:
scala> var fun = (i: Int) => Array(1,2,3)(i)
fun: Int => Int = <function1>
并且Array[Int]是一個類:
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
^
現在,隱式轉換發生的地方在哪里?
uj5u.com熱心網友回復:
既然你有,WrappedArray我猜你有 Scala 2.12 或更早版本 - Scala 2.13 有ArrayOps.
有一個從to的隱式轉換(實際上是整個系列的轉換)。所以你有一個從到的隱式轉換。ArrayWrappedArrayArray[T]WrappedArray[T]
現在,WrappedArray實作各種 Scala 的集合特征。其中之一是Seq實施PartialFunction(反過來擴展Function)。這意味著 Scala 中的所有集合都是來自某個鍵的函式(Int在序列的情況下,在Maps 的情況下可能是其他東西)。這包括WrappedArray.
因此,您轉換為WrappedArray自動將 anArray[T]轉換為 (a) function 的子型別Int => T。
事實上,這就是為什么你應該避免將任何集合(或像Array2.13 之前那樣隱式轉換為集合的東西)放入隱式范圍的原因:隱式范圍內的集合會自動變成隱式轉換本身。這個問題僅在 Scala 3 中得到解決,其中隱式轉換成為interface 的一個單獨子型別Function。
uj5u.com熱心網友回復:
但發生的地方在哪里?
隱式轉換在必要時發生,在這種情況下是在賦值本身中。
reify在我的另一個答案中查看我的塊:
val foo: Function1[Int, Int] = Predef.wrapIntArray(Array.apply(1, 2, 3));
那就是在那里進行轉換,呼叫方法:wrapIntArray在Predef物件中。
顯然, Int => Int 是一個函式:
而 Array[Int] 是一個類:
但是 arr 可以賦值給 fun:
反之,則行不通:
看來你不知道/了解,在斯卡拉 functions也objects (幾乎所有的Scala的是object,任何一個值將是一個object)。
所以我們不能直接將 an 賦給一個Array[Int]應該是 an 的值Int => Int;因為Array[Int]不是Int => Int (如我之前的回答所示)的子型別。
但是我們可以將 an 轉換Array[Int]為 an ArraySeq[Int],它是an的子型別,Int => Int因此我們可以進行賦值。
相反的將不起作用,因為 anInt => Int不是 anArray[Int]也不是 aArraySeq[Int]
注意這只是基本的子型別,aDog是 的子型別Pet但 aPet不是的子型別Dog
哪一個是與 Function[Int, Int] 相關的類/特征?我檢查了你提到的鏈接:密封抽象類 ArraySeq[ A] extends AbstractSeq[A] with IndexedSeq[A] with IndexedSeqOps[A, ArraySeq, ArraySeq[A]] with StrictOptimizedSeqOps[A, ArraySeq, ArraySeq[A]]帶有 EvidenceIterableFactoryDe??faults[A, ArraySeq, ClassTag] 和 Serializable
這些是ArraySeq直接擴展的類/特征,在Scaladoc鏈接中有一個按鈕可以查看您將看到的所有晚餐型別廣告(Int) => A
編輯
最后一個問題是 (Int) => A 來自哪個超型別?ArraySeq 擴展的型別太多。
您需要遍歷層次結構:
- immutable.ArraySeq 擴展 immutable.AbstractSeq
- immutable.AbstractSeq 擴展 immutable.Seq
- immutable.Seq 擴展了 collection.Seq
- collection.Seq 擴展 PartialFunction[Int, A]
- PartialFunction[Int, A] 擴展 Function1[Int, A]
uj5u.com熱心網友回復:
當您分配Array(1)給 a valof type 時Int => Int,將scala.LowPriorityImplicits#wrapIntArray呼叫隱式轉換。
它包裝Array成ArraySeq和后期器具Function1或Int => Int
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/361519.html
標籤:斯卡拉
