Типы Scala: зависимые от пути типы Scala компилируются, даже ожидая ошибки времени компиляции. - PullRequest
0 голосов
/ 23 октября 2018

Я изучаю типы, зависящие от пути, и типы уточнения.Но путают со сценарием, зависящим от пути.Ниже приведены примеры кодов этих типов:

abstract class SuperHero { val team: String }

abstract class Marvel extends SuperHero

case class DrStrange(team: String) extends Marvel
case class Hulk(team: String) extends Marvel

abstract class DC extends SuperHero

case class BatMan(team: String) extends DC
case class Flash(team: String) extends DC

abstract class Tower {
    type SH <: SuperHero
    val superHero: SH
    def teamName: String = s"I am ${superHero.team}"
}

class HulkTower(val superHero: Hulk) extends Tower {
    type SH = Hulk
}

object TowerOfHero{
    def apply[F <: SuperHero](f: F) : Tower { type SH = F } = new Tower {
        override type SH = F
        override val superHero : SH = f
    }
}

val drStrangeTower = TowerOfHero(DrStrange("Avengers"))

val hulkTower : Tower { type SH = Hulk } = TowerOfHero(Hulk("Avengers"))

val hulkTower2 : HulkTower = new HulkTower(Hulk("Avengers"))

Ниже приведены ссылки, которые меня смущают:

val dtStrange5: drStrangeTower.SH = hulkTower2.superHero

Приведенный выше код генерирует ошибку времени компиляции, что вполне нормально, поскольку относится к разнымТипы.

val hulk5: HulkTower#SH = hulkTower.superHero
val hulk6: HulkTower#SH = hulkTower2.superHero

Выше код успешно компилируется, что хорошо, из-за проекции типа.В проекции типа путь типа не зависит.

val hulk7: hulkTower.SH = hulkTower2.superHero

Выше код успешно скомпилирован, но я ожидаю ошибки времени компиляции.Из-за того, что путь типа hulkTower.SH отличается от пути типа hulkTower2.superHero.

Почему выполняется этот последний фрагмент кода?

1 Ответ

0 голосов
/ 23 октября 2018

Вам понадобится внутренний класс для этого.Во-первых, давайте рассмотрим ваш пример:

class HulkTower(val superHero: Hulk) extends Tower {
    type SH = Hulk
}

Вы говорите: «Любой HulkTower имеет тип SH, определенный как Hulk».Два экземпляра HulkTower будут иметь одинаковый тип SH, поэтому компилятор не будет жаловаться.

Внутренний класс предполагает определение класса внутри другого:

class A {
  class B {

  }
}

val a1 = new A
val a2 = new A

val a1_b = new a1.B
val a2_b = new a2.B

val x: a1.B = a2_b // compile error

https://scastie.scala -lang.org / O8qE6LKBSU6tL9RytKZn5w

Обратите внимание на вложенное определение class.По сути, вы говорите, что «каждый экземпляр A имеет свой экземпляр класса B»

...