1

关于scala中结构匹配的几个问题

问题 1)在下面的代码中,我是否能够传递BirdPlane到,因为takeOff在结构上匹配起飞所需的对象?BirdPlaner

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) 什么是反射调用?我必须导入,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) in 的类型是r什么takeOff

4

2 回答 2

3
  1. 是(见#4)

  2. 结构类型在后台使用反射,所以速度很慢。reflectiveCallsimport 用于警告用户这个问题。

  3. 当您添加细化时,您使用额外的字段{ val callsign = name }扩展您的类型,所以现在它的类型匹配,因为它同时具有和Birdcallsignrcallsignfly

    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. 它在scala中被称为Duck typing结构类型。

您可能也对此子类型关系感兴趣

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 }]
于 2019-06-27T07:33:04.413 回答
2
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

请注意文档中的警告

结构类型在运行时通过反射实现,本质上比名义类型的性能低。

于 2019-06-27T07:31:39.903 回答