我的印象是结构类型在底层使用反射(需要告诉编译器启用"-language:reflectiveCalls"
),并且任何与类型匹配的对象都将使用它自己的函数版本。例如,如果我调用.contains
aSeq
它将使用Seq
版本,如果我调用它 aString
那么它将使用它从StringOps中定义的版本SeqLike
所以在 scala 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
正如你所看到的,a String
.contains( String
) 为自己返回 true,但如果它在被解释为Containable
类型时被调用,则不会返回 true,即使它与 StringOps 类中定义的方法匹配。
我觉得这与实施有关,==
因为.contains
文档说:
如果此序列有一个元素等于(由 == 确定)elem,则为 true,否则为 false。
通过检查类型的结果使这种感觉更加复杂isInstanceOf
scala> val aVal = myMap("A")
aVal: Containable = B
scala> aVal.isInstanceOf[String]
res5: Boolean = false
scala> aVal.isInstanceOf[Seq[_]]
res6: Boolean = true
为了回应关于编译器错误的评论,这是我的终端的截屏视频,显示了这个工作