gpt4 book ai didi

scala - Scala中的结构类型调度

转载 作者:行者123 更新时间:2023-12-05 00:43:05 25 4
gpt4 key购买 nike

我试图更好地掌握结构类型调度。例如,假设我有一个带有 summary 的可迭代对象。计算平均值的方法。所以o.summary()给出列表的平均值.我可能想使用结构类型调度来启用 summary(o) .

  • 是否有一套关于 o.summary() 的最佳实践?与 summary(o) ?
  • scala如何解决summary(o)如果我有方法summary(o: ObjectType)summary(o: { def summary: Double})
  • 结构类型调度与多方法或泛型函数有何不同?

  • Michael Galpin 给出 following discription关于 structural type dispatch :

    结构类型是 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时(你可以去掉括号,因为它没有副作用),你要求 summary o 的属性(property).调用summary(o)时,你正在通过 o到计算 o 的摘要的方法.我相信第一种方法更好:)。

    我没有过多地使用结构类型分派(dispatch),但我认为它最适合(在大型系统中)仅因为一个方法想要一个定义了某个方法的类型而必须编写接口(interface)的情况。有时创建该接口(interface)并强制客户端实现它可能会很尴尬。有时您想使用在另一个 API 中定义的客户端,该客户端符合您的接口(interface)但没有显式实现它。因此,在我看来,结构类型分派(dispatch)是一种隐式制作适配器模式的好方法(节省样板文件,耶!)。
    -- 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 的子类型; C。我将采用 B 的父类(super class)型; 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) => // ...
    ...

    同样,您可以使用结构类型调度 - def collide(a: {def processCollision()}) ,但这取决于设计决策(我将在此示例中创建一个界面)。
    -- Flaviu Cipcigan

    关于scala - Scala中的结构类型调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1435170/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com