什么是scala中的结构匹配
What is structure match in scala
关于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) takeOff
.
中r
的类型是什么
- 关于问题 1:是的,它们在结构上匹配
r
的类型
- 关于第 2 季度,请参阅
- 关于 Q3 和 3.1,参见
- 关于 Q4
r
的类型是
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
的警告
Structural types are implemented with reflection at runtime, and are
inherently less performant than nominal types.
是(参见#4)
结构类型在后台使用反射,所以速度很慢。 reflectiveCalls
导入用于警告用户此问题。
当您添加细化 { val callsign = name }
时,您会使用额外字段 callsign
扩展您键入 Bird
,因此现在它的类型与 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
它在 Scala 中被称为 Duck typing
or structural 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 }]
关于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) takeOff
.
r
的类型是什么
- 关于问题 1:是的,它们在结构上匹配
r
的类型
- 关于第 2 季度,请参阅
- 关于 Q3 和 3.1,参见
- 关于 Q4
r
的类型是
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
的警告Structural types are implemented with reflection at runtime, and are inherently less performant than nominal types.
是(参见#4)
结构类型在后台使用反射,所以速度很慢。
reflectiveCalls
导入用于警告用户此问题。当您添加细化
{ val callsign = name }
时,您会使用额外字段callsign
扩展您键入Bird
,因此现在它的类型与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
它在 Scala 中被称为
Duck typing
or structural 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 }]