所以我一直试图通过twitter Scala school学习Scala。但我现在卡在他们的一个type bound examples。
特别是,使用<%<
类型关系运算符,可以将类型作为特定类型进行查看。
当我在Scala控制台中执行以下代码时:
scala> class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value }
...我收到以下错误:
<console>:7: error: not found: type <%<
class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value }
^
<console>:7: error: overloaded method value + with alternatives:
(x: Double)Double <and>
(x: Float)Float <and>
(x: Long)Long <and>
(x: Int)Int <and>
(x: Char)Int <and>
(x: Short)Int <and>
(x: Byte)Int <and>
(x: String)String
cannot be applied to (A)
class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value }
我的问题是,为什么Scala解释器会抱怨?
我一直在尝试查看Scala文档,但我无法在任何地方找到运营商的信息。我可以看到Scala学校是在Scala 2.8.0的基础上创建的,我正在运行Scala 2.10.0 - 所以这可能已被删除了?如果是这种情况,为什么这似乎是一个有用的运算符?
答案 0 :(得分:8)
Scala 2.8中的约束A <%< B
定义为
sealed abstract class <%<[-From, +To] extends (From => To)
object <%< {
implicit def conformsOrViewsAs[A <% B, B]: A <%< B = new (A <%< B) {def apply(x: A) = x}
}
所以你总能以这种方式把它带回来。但是,我猜测它被弃用的原因是视图绑定只是要求从A
到B
的隐式函数,并且有一种非常好的方法来表达广义上的特定约束方式已经:
class Container[A](value: A) { def addIt(implicit evidence: A => Int) = 123 + value }
顺便说一下,值得注意的是,不是运算符,而是从定义中可以看到的中缀位置。 =>
也是如此,这只是引用Function1
类型构造函数的另一种方式。
答案 1 :(得分:2)
在this site上,它表示在Scala 2.9中已弃用A <%< B
。我不知道为什么,我同意它似乎有点奇怪,因为它对我来说也看起来像一个非常有用的运算符。
答案 2 :(得分:-1)
正确的用法似乎是
class Container[A](value: A) { def addIt[A <% Int] = 123 + value }
对于重载值,scala
选择不解决歧义;在这种情况下,你必须决定。
您可以尝试使用:-Xprint:typer
或者您可以使用A
或已建议的Int
来确定class Container[A](value: A) { def addIt = 123 + value.asInstanceOf[Int] }
确实是class Container[A](value: A) { def addIt(implicit evidence: A => Int) = 123 + value }
。它们是等价的。但在此您要说A
是Int
的一种类型;与A
相对的Int
可以被视为<%
scala> class Container[A](value: A) { def printIt[A <% Int] = println( 123+" could be " + value) }
defined class Container
scala> val x = new Container("Love")
x: Container[String] = Container@21ebfd82
scala> x.printIt
123 could be Love
。
第二种选择并非微不足道。请考虑以下
"love"
显然Int
不是String
的一种类型,因为它是A => Int
,但在这种情况下它完全没问题:这就是为什么你应该小心使用{{1}}