Не удается ограничить метод по правилу нижней границы - PullRequest
0 голосов
/ 28 декабря 2018

Я начал читать о дженериках скалы.Кто может объяснить мне, почему работает этот код?

sealed abstract class Animal

class Cat extends Animal
class Dog extends Animal

class Box[A >: Animal] {
  def set(a: A): A = ???
}

val catBox: Box[Animal] = new Box[Animal]
val dog = new Dog
catBox.set(dog)

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Я предполагаю здесь, что вы подразумеваете под "не работает", что вы не ожидали, что сможете set a Dog в ваш catBox, потому что Dog не является суперклассомAnimal.

Это ожидается, хотя.Ваше определение Box[Animal].set становится def set(a: Animal): Animal.Теперь Dog равен , а Animal, поэтому он удовлетворяет определению.

Я не совсем понимаю, каково ваше намерение здесь.Тип, связанный с Box, ограничивает типы ящиков, которые вы можете создавать:

 new Box[Animal] // compiles
 new Box[Dog]    // does not compile - Dog is not a superclass of Animal
 new Box[Any]    // compiles - Any is a superclass of everything 

, но почему вы хотите ограничить его, так как это не имеет особого смысла.Возможно, вам нужна верхняя граница:

 class AnimalBox[A <: Animal]
 val animalBox = new AnimalBox[Animal] // compiles
 val dogBox = new AnimalBox[Dog] // compiles: Dog is a subclass of Animal
 val catBox = new AnimalBox[Cat] // compiles: Cat is a subclass of Animal
 val badBox = new AnimalBox[Any] // does not compile: Any is not a subclass

 animalBox.set(new Dog) // compiles: Dog is an Animal
 animalBox.set(new Cat) // compiles: Cat is an Animal
 animalBox.set(new Pear) // does not compile: Pear is not an Animal

 dogBox.set(new Dog) // compiles
 dogBox.set(new Cat) // does not compile: cat is not a dog
0 голосов
/ 28 декабря 2018

Оператор ??? эквивалентен throw new NotImplementedError.

Итак, когда вы вызываете catBox.set(dog), вы вызываете исключение.

...