gpt4 book ai didi

Scala:如何两次继承相同的特征?

转载 作者:行者123 更新时间:2023-12-05 03:15:23 24 4
gpt4 key购买 nike

我正在关注 Odersky 的“Programming in Scala”第 2 版,在第 12.5 节“Traits as stackable modifications”中,他介绍了一个 IntQueue 以及一个可以将您插入的任何值加倍的特征进入队列:

import scala.collection.mutable.ArrayBuffer
abstract class IntQueue {
def get(): Int
def put(x: Int)
}

class BasicIntQueue extends IntQueue {
private val buf = new ArrayBuffer[Int]
def get() = buf.remove(0)
def put(x: Int) { buf += x }
}

trait Doubling extends IntQueue {
abstract override def put(x: Int) {
super.put(2 * x)
}
}

本书随后表明您可以实例化一个队列,该队列通过 new BasicIntQueue with Doubling 将您插入其中的每个整数加倍。我想做的是创建一个类似的队列,它将每个整数乘以 4,如下所示:new BasicIntQueue with Doubling with Doubling。但是,这会触发编译错误“trait Doubling is inherited twice”。仔细研究一下,我想这与线性化的局限性有关;具体而言,给定特征不能在类层次结构的线性化中出现两次。

那么,达到我想要的效果的最佳方法是什么?

这里有一些关于我的“真实世界”用例的更多信息,以防答案取决于此:

我有一个 SoundFile 类,它读取一个 .wav 文件,并生成一个 SoundFile 对象,它扩展了一个 WaveForm 特征。 SoundFile 类类似于上面的 BasicIntQueueWaveForm 特性类似于上面的 IntQueue

我有 2 个类似于 Doubling 的特征,一个叫做 Echo,一个叫做 Reverse

我想编写 new SoundFile("myFile.wav") with Reverse with Echo with Reverse,但我遇到了关于从 Reverse 继承的相同编译错误特性两次。

最佳答案

不幸的是,您不能从同一特征继承两次。相反,您应该使用其他一些机制。例如,ReverseEcho 都是对波形的操作。你可以有

val reverse = (w: Waveform) => // produce a reverse waveform
val echo = (w: Waveform) => // copy the waveform onto itself with delay
new SoundFile("myFile.wav", reverse andThen echo andThen reverse)

或类似的东西。

如果您需要的不仅仅是一个简单的功能,您需要将对功能的修改封装到您自己的类中:

trait Transform { self =>
def apply(w: Waveform): Waveform
def time: Double
def andThen(t: Transform) = new Transform {
def apply(w: Waveform) = t(self(w))
def time = self.time + t.time
}
}
val reverse = new Transform { def time = 0.0; def apply ... }
val echo = new Transform { def time = 1.0; def apply ... }
// Same deal after here

关于Scala:如何两次继承相同的特征?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17287395/

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