У меня создалось впечатление, что 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
.Contains (String
) возвращает истину для себя, но если это называется в то же время интерпретируются с как Containable
типа, несмотря на то, что совпадает с определенным методом в класс StringOps.
У меня есть ощущение, это связанно с реализацией ==
после .contains
документации говорит:
верно, если эта последовательность имеет элемент, который равен (как определено ==) для Эля, иначе лжи ,
это чувство усугубляется результатами проверки типа с помощью 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 я получаю missmatch типа в строке, где вы создаете экземпляр карты. Это связано с тем, что ни String, ни Seq, содержащие метод, не содержат (Any). Их методы содержат разные подписи. Так что если это typechecks в scala 2.10, это будет ошибкой. – dth
Это работает в scala 2.10.3, версия отмечена в REPL – EdgeCaseBerg
@dth Я добавил видеоролик моего REPL для вас – EdgeCaseBerg