Что такое структура соответствия в Scala - PullRequest
1 голос
/ 27 июня 2019

Несколько вопросов, касающихся сопоставления структур в scala

Вопрос 1) В следующем фрагменте кода я могу передать Bird и Plane takeOff, поскольку Bird и Plane структурно соответствует объекту r требуется для взлета?

import scala.language.reflectiveCalls 

case class Bird (val name: String) extends Object {
        def fly(height: Int):Unit = {println("bird fly")}
}

case class Plane (val callsign: String) extends Object {
        def fly(height: Int):Unit = {println("plane fly")}
}

def takeoff(
            runway: Int,
      r: { val callsign: String; def fly(height: Int):Unit }) = {
  println(r.callsign + " requests take-off on runway " + runway)
  println(r.callsign + " is clear for take-off")
  r.fly(1000)
}
val bird = new Bird("Polly the parrot"){ val callsign = name }
val a380 = new Plane("TZ-987")
takeoff(42, bird)
takeoff(89, a380)

Вопрос 2) Что такое reflectiveCalls?Мне пришлось импортировать scala.language.reflectiveCalls, иначе я получаю предупреждение reflective access of structural type member value callsign should be enabled by making the implicit value scala.language.reflectiveCalls visible.

Вопрос 3) Как мне создать Bird следующим образом: val bird = new Bird("Polly the parrot"){ val callsign = name }.Разве это не должно быть только val bird = new Bird("Polly the parrot").Как это получается.

Вопрос 3.1).bird все еще имеет тип Bird или это какой-то другой тип, потому что я передал дополнительные {...}

4) Что такое тип r в takeOff.

Ответы [ 2 ]

3 голосов
/ 27 июня 2019
  1. Да (см. № 4)

  2. Структурная типизация использует отражение в фоновом режиме, поэтому она медленная. reflectiveCalls Импорт используется для предупреждения пользователя об этой проблеме.

  3. Когда вы добавляете уточнение { val callsign = name }, вы расширяете свой тип Bird дополнительным полем callsign, поэтому теперь его тип соответствует r, так как он имеет callsign и fly

    3.1 Тип bird является как Bird, так и структурным

    val bird: Bird = new Bird("Polly the parrot"){ val callsign = name }
    val birdRefined: Bird{ val callsign:String } = new Bird("Polly the parrot"){ val callsign = name }
    val structuralBird: { val callsign: String; def fly(height: Int): Unit } = birdRefined
    
  4. Его называют Duck typing или структурный тип в scala.

Вас также могут заинтересовать эти подтипы отношений

implicitly[Bird <:< { def fly(height: Int):Unit }]
//implicitly[Bird <:< { val callsign: String; def fly(height: Int):Unit }] -- fails. Not sybtype. 
implicitly[Plane <:< { val callsign: String; def fly(height: Int):Unit }]
implicitly[Bird {val callsign:String} <:< { val callsign: String; def fly(height: Int):Unit }]
2 голосов
/ 27 июня 2019
r: AnyRef{val callsign: String; def fly(height: Int): Unit}

Например, следующее назначение не скомпилирует

val r: { val callsign: String; def fly(height: Int): Unit } = Bird("pigeon")

потому что Bird("pigeon") отсутствует callsign.

Обратите внимание на предупреждение из документов

Структурные типы реализуются с отражением во время выполнения и по своей природе менее производительный, чем номинальные типы.

...