简体   繁体   English

下界 Scala

[英]Lower Bound Scala

  class Animal
  class Cat extends Animal
  class Dog extends Animal
   

Upper bound上限

  class CageUP[A <: Animal](animal: A)

Lower bound下限

  class CageLB[A >: Animal](animal: A)

As per the upper bound definition, it can accept A must be either same as Animal or Sub-Type of Animal.根据上限定义,它可以接受 A 必须与 Animal 或 Sub-Type of Animal 相同。

  val cageup = new CageUP(new Dog)

As per the lower bound definition, it can accept A must be either same as Animal or Super-Type of Animal.根据下限定义,它可以接受 A 必须与 Animal 或 Super-Type of Animal 相同。

  val cagelb = new CageLB(new Dog) 
   

Why lower bound is accepting and compiling even dog instance is passed, which is not a supertype of Animal.为什么下界是接受和编译甚至传递了狗实例,这不是Animal的超类型。

Type bounds effect methods at both the call site and the definition site, sometimes in surprising ways.类型边界在调用站点和定义站点都影响方法,有时以令人惊讶的方式。

Let's set up a type hierarchy.让我们建立一个类型层次结构。

class Base             {val base = 'B'}
class Mid extends Base {val mid  = 'M'}
class End extends Mid  {val end  = 'E'}

Now let's start with the more common upper bounding.现在让我们从更常见的上限开始。

def f[T <: Mid](t:T):Int = {
  val x = t.base
  val y = t.mid
//val z = t.end  <--won't compile
  42
}
//f(new Base)  <--doesn't conform to bounds
f(new Mid)  //OK  
f(new End)  //OK, promoted to Mid in the f() code

As expected, there is no t.end because that's not a part of type Mid , and you can't invoke it with type Base because that won't have the mid member expected in every type Mid .正如预期的那样,没有t.end因为它不是Mid类型的一部分,并且您不能使用Base类型调用它,因为这不会在每个Mid类型Mid都期望mid成员。

Now let's flip it to lower bounding.现在让我们将其翻转到下边界。

def f[T >: Mid](t:T):Int = {
//val x = t.base <--won't compile
//val y = t.mid  <--won't compile
//val z = t.end  <--won't compile
  42
}
f(new Base)  //OK
f(new Mid)   //OK
f(new End)   //OK
f(List(9))   //OK!!

As you can see, a received parameter with no upper bound isn't terribly useful because the compiler sees that it might be type Mid , but it might be type Any , and since anything and everything can be promoted to type Any then anything is permitted at the call site but almost nothing is known about it at the method definition site.如您所见,没有上限的接收参数并不是非常有用,因为编译器认为它可能Mid类型,但它可能Any类型,并且因为任何东西都可以提升为Any类型,所以Any东西都是允许的在调用站点,但在方法定义站点几乎一无所知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM