在scala中<:<和<:之间有什么不同

Zav*_*ava 15 types scala implicit

我已经知道了:

  • <: 是Scala语法类型约束
  • while <:<是利用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)

  • 真的,谢谢,这是一个很大的不同.第一种情况,编译器将帮助我们,第二种情况,编译器将为我们证明. (2认同)

Yur*_*riy 7

1.  def bar[A <: java.io.Serializable](i:A) = i
Run Code Online (Sandbox Code Playgroud)

<: - 保证类型参数Ai实例将是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)
  • 如果我们不调用不符合<:<条件而不是所有编译和执行的方法.