<:<斯卡拉运算符

任何人都可以在scala中提供<:<运算符的一些细节。 我认为:

 if(apple <:< fruit) //checks if apple is a subclass of fruit. 

还有其他解释吗? 我在scala源文件中看到很多定义。

<:< 不是操作员 – 它是一个标识符 ,因此是下列之一:

  • 一个types的名字(类,特质,types别名等)
  • 方法的名称/ val或var

在这种情况下, <:<在库中出现两次,在Predef作为类出现一次,在Manifest一次。

对于Manifest上的方法,它检查由此清单表示的types是否是由清单参数表示的types的子types。

对于Predef中的这种types,这是相对较新的,我也对此稍加困惑,因为它似乎是同一个声明三重奏的一部分!

 class <%<[-From, +To] extends (From) ⇒ To class <:<[-From, +To] extends (From) ⇒ To class =:=[From, To] extends (From) ⇒ To 

Predef.scala中定义的<:<types以及相关的types=:=<%<如下所示:

 // used, for example, in the encoding of generalized constraints // we need a new type constructor `<:<` and evidence `conforms`, as // reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred) // to constrain any abstract type T that's in scope in a method's argument list (not just the method's own type parameters) // simply add an implicit argument of type `T <:< U`, where U is the required upper bound (for lower-bounds, use: `U <: T`) // in part contributed by Jason Zaugg sealed abstract class <:<[-From, +To] extends (From => To) implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x} // not in the <:< companion object because it is also intended to subsume identity (which is no longer implicit) 

这使用Scalafunction,可以将通用typesop[T1, T2]写入T1 op T2 。 如aioobe所述,可以使用这个方法为仅适用于genericstypes的某些实例的方法提供证据参数(所给出的示例是只能在Tuple2Traversable上使用的toMap方法)。 正如在注释中指出的那样,这个概念泛化了一个普通的genericstypes约束来允许它引用任何范围内的抽象types/types参数。 使用这个( implicit ev : T1 <:< T2 )比单纯使用证据参数( implicit ev: T1 => T2 )的优势在于后者可能会导致意外的范围内隐式值被用于转换。

我确信我曾经在Scala邮件列表上看到过这样的讨论,但目前找不到。

我问周围,这是我得到的解释:

通常用<:<作为证据参数。 例如在TraversableOncetoMap被声明为def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U] 。 这表示了toMap方法只有在遍历包含2元组的情况下才起作用的约束。 另一个例子是flatten<:<用于表示约束条件,只能展平可遍历的遍历。

实际上,它检查由Manifest苹果代表的类是否是清单水果代表的类的子类。

例如:

 manifest[java.util.List[String]] <:< manifest[java.util.ArrayList[String]] == false manifest[java.util.ArrayList[String]] <:< manifest[java.util.List[String]] == true 

从scala.Predef.scala复制:

 // Type Constraints -------------------------------------------------------------- // used, for example, in the encoding of generalized constraints // we need a new type constructor `<:<` and evidence `conforms`, as // reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred) // to constrain any abstract type T that's in scope in a method's argument list (not just the method's own type parameters) // simply add an implicit argument of type `T <:< U`, where U is the required upper bound (for lower-bounds, use: `U <: T`) // in part contributed by Jason Zaugg sealed abstract class <:<[-From, +To] extends (From => To) implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x} 

为了更好地理解实施 。

 sealed abstract class <:<[-From, +To] extends (From => To) implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x} 

我试图devise一个更简单的实现。 以下没有工作。

 sealed class <:<[-From <: To, +To] implicit def conforms[A <: B, B]: A <:< B = new (A <:< B) 

至less因为它不会input所有有效的用例。

 case class L[+A]( elem: A ) { def contains[B](x: B)(implicit ev: A <:< B) = elem == x } error: type arguments [A,B] do not conform to class <:<'s type parameter bounds [-From <: To,+To] def contains[B](x: B)(implicit ev: A <:< B) = elem == x ^ 

嗯…我似乎无法find“<:<”任何地方,但“<:”表示子types。 从http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html#types

 List[T] forSome { type T <: Component } 

在上面的例子中,我们说T是Component的一个子types。