Scala课堂(13):高级类型(一)

jerry Scala 2015年11月25日 收藏

这里我们转载Twitter的Scala课堂  ,转载的内容基本来自Twitter的Scala课堂中文翻译,部分有小改动.
视界(“View”)

有时候,你并不需要指定一个类型是等/子/超于另一个类,你可以通过转换这个类来伪装这种关联关系。一个视界指定一个类型可以被“看作是”另一个类型。这对对象的只读操作是很有用的。
隐 函数允许类型自动转换。更确切地说,在隐式函数可以帮助满足类型推断时,它们允许按需的函数应用。例如:

scala> implicit def strToInt(x: String) = x.toInt
strToInt: (x: String)Int

scala>  "123"
res0: String = 123

scala> val y:Int="123"
y: Int = 123

scala>  math.max("123", 111)
res1: Int = 123

视界,就像类型边界,要求对给定的类型存在这样一个函数。您可以使用<%指定类型限制,例如

scala> class Container[A <% Int] { def addIt(x: A) = 123 + x }
defined class Container

这是说 A 必须“可被视”为 Int 。让我们试试

scala> class Container[A <% Int] { def addIt(x: A) = 123 + x }
defined class Container

scala>  (new Container[String]).addIt("123")
res2: Int = 246

scala>  (new Container[Int]).addIt(123) 
res3: Int = 246

scala> (new Container[Float]).addIt(123.2F)
<console>:10: error: No implicit view available from Float => Int.
              (new Container[Float]).addIt(123.2F)
               ^

其他类型限制
方法可以通过隐含参数执行更复杂的类型限制。例如,List支持对数字内容执行sum,但对其他内容却不行。可是Scala的数字类型并不都共享一个超类,所以我们不能使用T

sum[B >: A](implicit num: Numeric[B]): B

如果你调用List(1,2).sum(),你并不需要传入一个 num 参数;它是隐式设置的。但如果你调用List(?whoop?).sum(),它会抱怨无法设置num。
在没有设定陌生的对象为Numeric的时候,方法可能会要求某种特定类型的“证据”。这时可以使用以下类型-关系运算符:

A =:= B A 必须和 B相等
A <:< B A 必须是 B的子类
A <%< B A 必须可以被看做是 B