Zav*_*ava 15 types scala implicit
我已经知道了:
<: 是Scala语法类型约束<:<是利用Scala隐式到达类型constrait的类型例如:
object Test {
// the function foo and bar can have the same effect
def foo[A](i:A)(implicit ev : A <:< java.io.Serializable) = i
foo(1) // compile error
foo("hi")
def bar[A <: java.io.Serializable](i:A) = i
bar(1) // compile error
bar("hi")
}
Run Code Online (Sandbox Code Playgroud)
但我想知道什么时候需要使用<:和<:<?
如果我们已经拥有<:,我们为什么需要<:<?
谢谢!
dre*_*xin 20
两者之间的主要区别在于,它<:是对类型的约束,而<:<当用作隐式参数时,编译器必须找到证据的类型.这对我们的程序意味着,在这种<:情况下,类型推断器将尝试找到满足此约束的类型.例如
def foo[A, B <: A](a: A, b: B) = (a,b)
scala> foo(1, List(1,2,3))
res1: (Any, List[Int]) = (1,List(1, 2, 3))
Run Code Online (Sandbox Code Playgroud)
这里推理器发现Int并且List[Int]具有共同的超类型Any,因此它推断A为了满足B <: A.
<:<限制性更强,因为类型推断器在隐式解析之前运行.因此,当编译器试图找到证据时,类型已经修复.例如
def bar[A,B](a: A, b: B)(implicit ev: B <:< A) = (a,b)
scala> bar(1,1)
res2: (Int, Int) = (1,1)
scala> bar(1,List(1,2,3))
<console>:9: error: Cannot prove that List[Int] <:< Int.
bar(1,List(1,2,3))
^
Run Code Online (Sandbox Code Playgroud)
1. def bar[A <: java.io.Serializable](i:A) = i
Run Code Online (Sandbox Code Playgroud)
<: - 保证类型参数A的i实例将是Serializable的子类型
2. def foo[A](i:A)(implicit ev : A <:< java.io.Serializable) = i
Run Code Online (Sandbox Code Playgroud)
<:< - 保证执行上下文将包含类型A的隐式值(对于ev参数),什么是Serializable的子类型.这隐式在Predef.scala和foo方法中定义,并证明类型参数A的实例是否是Serializable的子类型:
implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]
Run Code Online (Sandbox Code Playgroud)
使用<:<运算符的虚构情况:
class Boo[A](x: A) {
def get: A = x
def div(implicit ev : A <:< Double) = x / 2
def inc(implicit ev : A <:< Int) = x + 1
}
val a = new Boo("hi")
a.get // - OK
a.div // - compile time error String not subtype of Double
a.inc // - compile tile error String not subtype of Int
val b = new Boo(10.0)
b.get // - OK
b.div // - OK
b.inc // - compile time error Double not subtype of Int
val c = new Boo(10)
c.get // - OK
c.div // - compile time error Int not subtype of Double
c.inc // - OK
Run Code Online (Sandbox Code Playgroud)