我刚开始使用Scala,想要清除一些基础知识。在下面的函数中,下限设置为Puppy。为什么在下面的代码中允许使用Puppy1和Puppy2。
class Animal
class Dog extends Animal
class Puppy extends Animal
class Puppy1 extends Animal
class Puppy2 extends Puppy
class AnimalCarer{
def display [T >: Puppy](t: T){
println(t)
}
}
val animal = new Animal
val dog = new Dog
val puppy = new Puppy
val puppy1 = new Puppy1
val puppy2 = new Puppy2
val animalCarer = new AnimalCarer
animalCarer.display(animal)
animalCarer.display(puppy)
animalCarer.display(puppy1)
animalCarer.display(puppy2)
animalCarer.display(dog)
答案 0 :(得分:1)
由于您没有明确填写T
,因此编译器会尝试使用正确的类型为您推断它:
animalCarer.display[testing.ParamTest.Animal](ParamTest.this.puppy1);
animalCarer.display[testing.ParamTest.Puppy](ParamTest.this.puppy2);
animalCarer.display[testing.ParamTest.Animal](ParamTest.this.dog)
这是Scala的Local Type Inference算法的一部分。如您所见,每个方法调用都是T
,例如,puppy1: Animal
,它遵循下限约束。
答案 1 :(得分:1)
这是Scala类型推断的典型例子,它与常见的概念(直觉)相混淆。
def foo[T >: Puppy](t: T) = t
foo(new Puppy1) //compiles
foo[Puppy1](new Puppy1) //give compilation error
Scala REPL
scala> def foo[T >: Puppy](t: T) = t
foo: [T >: Puppy](t: T)T
scala> foo(new Puppy1)
res9: Animal = Puppy1@4d49af10
scala> foo[Puppy1](new Puppy1)
<console>:16: error: type arguments [Puppy1] do not conform to method foo's type parameter bounds [T >: Puppy]
foo[Puppy1](new Puppy1)
^