trait Function1[-T1, +R] extends AnyRef { self => /** Apply the body of this function to the argument. * @return the result of function application. */defapply(v1: T1): R...overridedeftoString() ="<function1>"}
我们知道类似 A=>B 的形式在scala中是可以自动被转换为Function1的形式。
实际上其会被转换成为如下的形式:
假如我们定义了三个class 如下:
我们可以定义如下几个f:
根据Function1[-T1, +R]的定义,2-5可以通过编译,而6会编译失败。
怎么理解6呢? 这里我们要区分两个概念,函数的定义类型和函数的运行类型。
这里f的定义类型是 C=>C。 当f = (c: CSub) => new CSuper时,它的实际apply方法就是:
scala> var f: Int=>Int = i=>i+1
f: Int => Int = <function1>
val f: Int => Int = new Function1[Int,Int] {
def apply(i: Int): Int = i + 1
}
class CSuper { def msuper() = println("CSuper") }
class C extends CSuper { def m() = println("C") }
class CSub extends C { def msub() = println("CSub") }
var f: C => C = (c: C) => new C // ➋
f = (c: CSuper) => new CSub // ➌
f = (c: CSuper) => new C // ➍
f = (c: C) => new CSub // ➎
f = (c: CSub) => new CSuper // ➏ 编译错误!
def apply(i: CSub): CSuper = new CSuper
scala> trait MyFunction2[+T1, +T2, -R] {
| def apply(v1:T1, v2:T2): R = ???
| }
<console>:37: error: contravariant type R occurs in covariant position
in type (v1: T1, v2: T2)R of method apply
def apply(v1:T1, v2:T2): R = ???
^
<console>:37: error: covariant type T1 occurs in contravariant position
in type T1 of value v1
def apply(v1:T1, v2:T2): R = ???
^
<console>:37: error: covariant type T2 occurs in contravariant position
in type T2 of value v2
def apply(v1:T1, v2:T2): R = ???
^
scala> class ContainerPlus[+A](var value: A)
<console>:34: error: covariant type A occurs in contravariant position
in type A of value value_=
class ContainerPlus[+A](var value: A)
^
scala> class ContainerMinus[-A](var value: A)
<console>:34: error: contravariant type A occurs in covariant position
in type => A of method value
class ContainerMinus[-A](var value: A)
val cp: ContainerPlus[C]=new ContainerPlus(new CSub)
val cm: ContainerMinus[C] = new ContainerMinus(new CSuper)