<:<斯卡拉运算符
任何人都可以在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的某些实例的方法提供证据参数(所给出的示例是只能在Tuple2
的Traversable
上使用的toMap
方法)。 正如在注释中指出的那样,这个概念泛化了一个普通的genericstypes约束来允许它引用任何范围内的抽象types/types参数。 使用这个( implicit ev : T1 <:< T2
)比单纯使用证据参数( implicit ev: T1 => T2
)的优势在于后者可能会导致意外的范围内隐式值被用于转换。
我确信我曾经在Scala邮件列表上看到过这样的讨论,但目前找不到。
我问周围,这是我得到的解释:
通常用<:<
作为证据参数。 例如在TraversableOnce
, toMap
被声明为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。