【问题标题】:What is structure match in scala什么是scala中的结构匹配
【发布时间】:2019-11-09 03:35:39
【问题描述】:

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

问题 1) 在下面的代码中,我是否能够将 BirdPlane 传递给 takeOff,因为 BirdPlane 在结构上匹配起飞所需的对象 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) 什么是反射调用?我必须导入 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) takeOff中的r是什么类型。

【问题讨论】:

    标签: scala structural-typing


    【解决方案1】:
    1. 是(见 #4)

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

    3. 当您添加细化 { val callsign = name } 时,您扩展您键入带有额外字段 callsignBird,所以现在它的类型匹配 r,因为它同时具有 callsignfly

      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 typingstructural type

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

    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 }]
    

    【讨论】:

    • 3.1 并不是一个很好的演示,因为这也适用于val bird2 = new Bird("")
    【解决方案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

    注意来自docs的警告

    结构类型在运行时通过反射实现,并且是 本质上不如标称类型的性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-07
      • 2022-11-01
      • 2018-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      相关资源
      最近更新 更多