Может кто-либо предоставлять некоторую подробную информацию о <:<
оператор в scala. Я думаю:
if(apple <:< fruit) //checks if apple is a subclass of fruit.
Есть ли какие-либо другие объяснения? Я вижу много определений в scala исходном файле.
<: <
это не оператор - это идентификатор и, следовательно, одно из:
В этом случае <: <
появляется дважды в библиотеке, один раз в Predef
как класс и один раз как метод в Manifest
.
Для метода в манифесте
он проверяет, является ли тип, представленный этим манифестом, подтипом, представленного аргументом manifest.
Для типа в Predef
он относительно новый, и меня это немного смущает, потому что он, кажется, является частью триумвирата идентичных объявлений!
class <%<[-From, +To] extends (From) ⇒ To
class <:<[-From, +To] extends (From) ⇒ To
class =:=[From, To] extends (From) ⇒ To
На самом деле, проверяется, является ли класс представленный в Manifest
apple подклассом класса, представленного в manifest fruit.
Например:
manifest[java.util.List[String]] <:< manifest[java.util.ArrayList[String]] == false
manifest[java.util.ArrayList[String]] <:< manifest[java.util.List[String]] == true
Хмм .. . Кажется, я тоже нигде не могу найти "<: <", но "<:" обозначает подтипы. Из http://jim-mcbeath.blogspot.com/2008/09/ scala-syntax-primer.html # types :
List[T] forSome { type T <: Component }
В приведенном выше примере мы говорим, что T - это некоторый тип, который является подтипом компонента.
Скопировано из 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}
Я поспрашивал, и получил следующее объяснение:
<: <
обычно используется в качестве параметра доказательства. Например, в TraversableOnce
, toMap
объявлен как def toMap [T, U] (неявное ev: A <: <(T, U)): immutable.Map [ T, U]
. Это выражает ограничение, заключающееся в том, что метод toMap
работает только в том случае, если traversable содержит 2-кортежи. Flatten
- еще один пример. <: <
используется для выражения ограничения, заключающегося в том, что вы можете сглаживать только возможность обхода перемещаемых объектов.
Тип <: <
определен в Predef.scala вместе со связанными типами =: =
и <% <
следующим образом:
// 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)
Здесь используется функция Scala, которая является универсальным типом op [T1, T2]
можно записать T1 op T2
. Это может использоваться, как отмечает aioobe, для предоставления параметра свидетельства для методов, которые применяются только к некоторым экземплярам универсального типа (приведенный пример - метод toMap
, который может использоваться только в ] Traversable
из Tuple2
). Как отмечено в комментарии, это обобщает обычное ограничение универсального типа, позволяющее ему ссылаться на любой параметр абстрактного типа / типа в области видимости. Использование этого ( неявного ev: T1 <:
неявное ev: T1 => T2
), в том, что последний может привести к для преобразования используются непреднамеренные неявные значения, входящие в область видимости.
Я уверен, что видел обсуждение этого вопроса в одном из списков рассылки Scala, но пока не могу найти его.