+- Знаки в родовой декларации в Scala
Я искал документацию для PartialFunction по этой ссылке:
trait PartialFunction[-A, +B] extends (A) ⇒ B
Может быть, кто-то может помочь прояснить значение знаков плюс и минус в общей декларации?
3 ответа
"+" и "-" означают ковариантный и контравариантный типы соответственно. Короче говоря, это означает, что:
PartialFunction[-A1, +B1]
<: PartialFunction[-A2, +B2]
только если A1 :> A2
а также B1 <: B2
, где <:
это подтип отношений.
"-" обычно применяется для входных параметров, "+" для вывода - в C# они даже используют соответствующие ключевые слова in
а также out
, В Java также есть более примитивная универсальная поддержка отклонений, построенная на экзистенциальных типах - на самом деле вы можете сделать это, используя _ <: SomeType
(ковариация) или члены абстрактного типа type T <: SomeType
в Скале тоже.
Без модификаторов PartialFunction[A1, B1]
не будет иметь прямого отношения к PartialFunction[A2, B2]
(другими словами, это будет инвариант).
PS Есть также некоторые ограничения, применяемые к таким типам, например, ковариантный ("+") тип не может находиться в контравариантной позиции (вы можете только вернуть его из метода) и наоборот. Это сделано для того, чтобы поддержать принцип подстановки Лискова и, естественно, понятным путем интерпретации "in" / "out".
Также стоит отметить, что A => B
(синтаксис сахара для Function1
) сам использует ко / противо-дисперсию:
trait Function1 [-T1, +R] extends AnyRef
Это ковариация и контравариантность. https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
В основном, для родовых типов сказано, как будет работать наследование. Простой образец из Scala - trait Seq[+A]
Из-за +, код
val s: Seq[Person] = Seq[Student]()
будет компилироваться, потому что Student расширяет Person. Без + это не сработает
Немного более сложный образец -
class C[-A, +B] {
def foo(param: A): B = ???
}
class Person(val name: String)
class Student(name: String, val university: String) extends Person(name)
val sample: C[Student, Person] = new C[Person, Student]
Чтобы дополнить другие ответы, вот ссылка на документацию по отклонениям на сайте scala-lang: