加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala中的结构类型调度

发布时间:2020-12-16 18:10:17 所属栏目:安全 来源:网络整理
导读:我正在努力更好地掌握结构类型的调度.例如,假设我有一个可迭代对象,其中包含计算均值的汇总方法.所以o.summary()给出了列表的平均值.我可能想使用结构类型调度来启用摘要(o). 是否有一组关于o.summary()与summary(o)的最佳实践? 如果我有方法摘要(o:Object
我正在努力更好地掌握结构类型的调度.例如,假设我有一个可迭代对象,其中包含计算均值的汇总方法.所以o.summary()给出了列表的平均值.我可能想使用结构类型调度来启用摘要(o).

>是否有一组关于o.summary()与summary(o)的最佳实践?
>如果我有方法摘要(o:ObjectType)和摘要(o:{def summary:Double}),scala如何解析摘要(o)
>结构类型调度与多方法或通用函数有何不同?

迈克尔·加尔平(Michael Galpin)给出following discription约structural type调度:

结构类型是Scala的“响应式”编程版本,如许多动态语言所示.所以喜欢

def sayName ( x : { def name:String }){
    println(x.name)
}

然后任何带有名为name的方法的对象都不会传递给sayName:

case class Person(name:String)
val dean = Person("Dean")
sayName(dean) // Dean

解决方法

– 1.在您的示例中,我不会使用summary(o)版本,因为这不是一种非常面向对象的编程风格.当调用o.summary时(你可以删除括号,因为它没有副作用),你要求的摘要属性为o.在调用summary(o)时,您将o传递给计算o的摘要的方法.我相信第一种方法更好:).

我没有多少使用结构类型调度,但我认为它最适合(在大型系统中),因为一个方法需要一个定义了某个方法的类型,因此你必须编写一个接口.有时创建该接口并强制客户端实现它可能很尴尬.有时您希望使用在另一个API中定义的客户端,该客户端符合您的接口但未明确实现它.因此,在我看来,结构类型调度是一种隐式地生成适配器模式的好方法(保存在样板上,是的!).

– 2.显然,如果你调用summary(o)而o是ObjectType,则调用summary(o:ObjectType)(这确实有意义).如果你调用summary(bar),其中bar不是ObjectType,可能会发生两件事.如果bar具有正确签名和名称的方法summary(),则调用编译,否则调用不编译.

例:

scala> case class ObjectType(summary: Double)
defined class ObjectType

scala> val o = ObjectType(1.2)
o: ObjectType = ObjectType(1.2)

scala> object Test {
     | def summary(o: ObjectType)  { println("1") }
     | def summary(o: { def summary: Double}) { println("2")}
     | }
defined module Test

scala> Test.summary(o)
1

不幸的是,由于类型擦除,以下内容无法编译:

scala> object Test{
     | def foo(a: {def a: Int}) { println("A") }
     | def foo(b: {def b: Int}) { println("B") }
     | }
:6: error: double definition:
method foo:(AnyRef{def b(): Int})Unit and
method foo:(AnyRef{def a(): Int})Unit at line 5
have same type after erasure: (java.lang.Object)Unit
       def foo(b: {def b: Int}) { println("B") }

– 3.从某种意义上说,结构类型调度比泛型方法更具动态性,也有不同的用途.在通用方法中,您可以说:a.我想要任何类型的东西;湾我想要一种类型为A的子类型; C.我会拿一些超B型的东西; d.我将采用隐式转换为C类的东西.所有这些都比“我想要一个具有正确签名的方法foo的类型”更严格.此外,结构类型调度确实使用反射,因为它们是通过类型擦除实现的.

我对多方法知之甚少,但是看看wikipedia article,似乎可以使用模式匹配来实现Scala中的多方法.例:

def collide(a: Collider,b: Collider) = (a,b) match {
    case (asteroid: Asteroid,spaceship: Spaceship) => // ...
    case (asteroid1: Asteroid,asteroid2: Asteroid) => // ...
...

同样,您可以使用结构类型dispatch-def collide(a:{def processCollision()}),但这取决于设计决策(我将在此示例中创建一个接口).

– Flaviu Cipcigan

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读