什么是Scala <:<,=:=和<%<类?

Kar*_*tný 4 scala

可能重复:
Scala 2.8中<:<,<%<和=:=表示什么,它们在哪里记录?

我很好奇,因为我在Scala库代码中看到了它们,但我发现谷歌很难对它们说些什么,因为它们的名字不是单词.

Geo*_*edy 10

这些类用于限制方法适用性的隐式参数.以下是每个班级的说明.通常,它们可用于在单个方法的上下文中约束封闭类的类型参数.

<:<[A,B] 要么 A <:< B

仅当A是B的子类型时,编译器才能提供此类型的隐式实例.这类似于A <: B类型参数列表.

当您想要在特定方法的上下文中对类类型参数添加其他约束时,这可能很有用.例如,Foo下面的类可以用于任何类型,但该方法bar仅在T子类型为的时有效Number.

class Foo[T](x: T) {
  // In general T could be any type
  def bar(implicit ev: T <:< Number) = {
    // This method can now only be used when T is a subtype of Number
    // also, you can use ev to convert a T to number
    ev(x).doubleValue
  }
}

new Foo(123 : java.lang.Integer).bar // returns 123.0: Double
new Foo("123").bar // compile error: Cannot prove java.lang.String <:< java.lang.Number
Run Code Online (Sandbox Code Playgroud)

=:=[A,B] 要么 A =:= B

仅当A与B的类型相同时,编译器才能提供此类型的隐式实例.这在类型参数列表中没有等效语法,您只需使用相同的类型参数两次.

<:<除了要求类型完全匹配之外,可以使用它.这可以用于使一对方法互斥.

class Foo[T<:Number](x:T) {
  def numOnly(implicit ev: T =:= Number) = ()
  def floatOnly(implicit ev: T =:= Float) = ()
}

val asFloat = new Foo(123.0f:java.lang.Float)
asFloat.numOnly // Compile error
asFloat.floatOnly // Ok
val asNum = new Foo(123.0f:java.lang.Number)
asFloat.floatOnly // Ok
asFloat.numOnly // Compile error
Run Code Online (Sandbox Code Playgroud)

基本上,如果类型参数比约束更具体,则可以强制使用更具体的方法.

<%<[A,B] 要么 A <%< B

只有当A可以转换为B时,编译器才能提供此类型的隐式实例.这类似于A <% B类型参数列表.

这要求有一个隐式函数可用于将A转换为B. A <: B由于隐式A <:< B满足此约束,因此总是可行的.

该类实际上标记为已弃用.它说你应该只使用A => B.