scala – 为什么在查看隐式转换时,类型推断仅选择最具体类型的目
请考虑以下简单代码来创建typesafe等号.第一部分允许我为任何类型创建一个Identity类型类.
scala> trait Equals[A] { def equal(a1 : A,a2 : A) : Boolean } defined trait Equals scala> sealed trait Identity[A] { | def value : A | def ===(b : A)(implicit e : Equals[A]) = e.equal(value,b) | } defined trait Identity scala> implicit def ToIdentity[A](a : A) = new Identity[A] { val value = a } ToIdentity: [A](a: A)java.lang.Object with Identity[A] 所以,如果我为Equals [Int]创建一个类型类,我现在应该可以使用我的typesafe equals: scala> implicit val EqualsInt = new Equals[Int] { def equal(i1 : Int,i2 : Int) = i1 == i2 } EqualsInt: java.lang.Object with Equals[Int] = $anon$1@7e199049 scala> 1 === 2 res1: Boolean = false scala> 1 === 1 res2: Boolean = true scala> 1 === 1D <console>:10: error: type mismatch; found : Double(1.0) required: Int 1 === 1D ^ 好的,到目前为止一切顺利.如果我现在创建一个Equals [Any]会发生什么? scala> implicit val EqualsAny = new Equals[Any] { def equal(a1 : Any,a2 : Any) = a1 == a2 } EqualsAny: java.lang.Object with Equals[Any] = $anon$1@141d19 scala> 1 === 1D <console>:11: error: type mismatch; found : Double(1.0) required: Int 1 === 1D ^ 但是如果我告诉编译器我的类型是Any,而不是Int …… scala> (1 : Any) === 1D res6: Boolean = true 所以我的问题是“为什么编译器不考虑逻辑上具有的所有类型?” 也就是说,我的理解是Int类型的引用逻辑上具有Int,AnyVal和Any类型.无论如何,我探讨了一点,假设问题与协方差有关.我改变了我对身份的定义: scala> sealed trait Identity[+A] { | def value : A | def ===[B >: A : Equals](b : B) = implicitly[Equals[B]].equal(value,b) | } defined trait Identity 这次我得到了错误: scala> 1 === 1D <console>:10: error: could not find implicit value for evidence parameter of type Equals[AnyVal] 1 === 1D ^ 所以如果我创建一个Equals [AnyVal],那么这也有效: scala> implicit val EqualsAnyVal = new Equals[AnyVal] { def equal(a1 : AnyVal,a2 : AnyVal) = a1 == a2 } EqualsAnyVal: java.lang.Object with Equals[AnyVal] = $anon$1@67ce08c7 scala> 1 === 1D res4: Boolean = true 所以在这里我假设问题是Equals的非逆变性.所以我再试一次(但没有创建Equals [AnyVal]): scala> trait Equals[-A] { def equal(a1 : A,a2 : A) : Boolean } defined trait Equals scala> 1 === 1D res3: Boolean = true 所以,我可以看看这里有什么样的东西.但我的问题看起来像这样:为什么typer没有问这个问题(对于我的第一个例子): > 1是Int;对于范围中的含义,我可以创建一个Identity [Int],然后使用===方法.但这不起作用,因为参数不是Int.再次尝试考虑1的替代类型. 为什么类型推断只考虑最严格的1(即Int)? 解决方法
您在这里看到的是优先级隐式转换,在Scala 2.8中添加.
根据Language Specification(pdf),第7.2节:
这也是在2.8 collections中支持CanBuildFrom行为的机制. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |