Я смотрел документацию для PartialFunction в эту ссылку:
trait PartialFunction[-A, +B] extends (A) ⇒ B
Может кто-то может помочь прояснить значение знаков плюс и минус в общей декларации?
Я смотрел документацию для PartialFunction в эту ссылку:
trait PartialFunction[-A, +B] extends (A) ⇒ B
Может кто-то может помочь прояснить значение знаков плюс и минус в общей декларации?
"+" и "-" означают ковариантные и контравариантные типы соответственно. Короче говоря, это означает, что:
PartialFunction[-A1, +B1] <: PartialFunction[-A2, +B2], только если A1 :> A2 и B1 <: B2, где <: - отношение подтипирования.
"-" обычно применяется для входных параметров, "+" для вывода - на С# они даже используют соответствующие ключевые слова in и out. Существует также более примитивная общая поддержка дисперсии в Java, построенная на экзистенциальных типах - на самом деле вы можете сделать это, используя _ <: SomeType (ковариация) или абстрактные члены типа type T <: SomeType в Scala.
Без модификаторов PartialFunction[A1, B1] не будет иметь прямого отношения к PartialFunction[A2, B2] (другими словами, он будет инвариантным).
P.S. Существуют также некоторые ограничения, применяемые к таким типам, такие как ковариантный ( "+" ) тип не могут находиться в контравариантном положении (вы можете вернуть его только из метода) и наоборот. Это делается для поддержки Принципа замены Лискова и, естественно, понятно из-за интерпретации "in" / "out".
Кроме того, стоит заметить, что A => B (синтаксический сахар для Function1) сам использует co-/contra-variance:
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: