我的印象是,Structural Types使用反射罩下方(表示需要tell the compiler啓用"-language:reflectiveCalls"
),並且任何匹配類型的對象都將使用它自己的函數版本。例如,如果我叫.contains
在Seq
比它將使用Seq
版本,如果我把它叫做一個String
那麼它將使用StringOps它從SeqLike
結構類型不調用正確的實現?
變得如此斯卡拉2.10.3中定義的版本,爲什麼會發生這種情況:
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).
Type in expressions to have them evaluated.
Type :help for more information.
scala> type Containable = { def contains(elem:Any):Boolean }
defined type alias Containable
scala> val myMap: Map[String, Containable] = Map("A" -> "B", "C" -> Seq("A","B"))
myMap: Map[String,Containable] = Map(A -> B, C -> List(A, B))
scala> myMap("A").contains("B")
res0: Boolean = false
scala> myMap("C").contains("B")
res1: Boolean = true
scala> "B".contains("B")
res3: Boolean = true
正如你所看到的,String
。載有(String
)返回自身真實的,但如果它被稱爲同時interpretted作爲Containable
類型,即使該定義的方法匹配StringOps類。
我有感覺這與自.contains
文件==
實施做說:
如果是真的該序列具有相等的元素(如==確定),以ELEM,否則爲false 。
這種感覺是由檢查型的結果通過isInstanceOf
scala> val aVal = myMap("A")
aVal: Containable = B
scala> aVal.isInstanceOf[String]
res5: Boolean = false
scala> aVal.isInstanceOf[Seq[_]]
res6: Boolean = true
複合在回答關於編譯器錯誤的評論,這裏是一個screencast of my terminal showing this working
你確定你已經嘗試過嗎?在Scala 2.11中,我在你實例化地圖的行中遇到類型錯配。這是由於既沒有String也沒有Seq擁有一個包含(Any)的方法。他們包含的方法有不同的簽名。所以如果這個類型在scala 2.10中會出現這個bug。 – dth
這運行在斯卡拉2.10.3,該版本是在REPL – EdgeCaseBerg
@dth中註明的我已經爲您添加了我的REPL的視頻截屏 – EdgeCaseBerg