gpt4 book ai didi

scala - Scala 中用于具有继承返回类型的集合的最小框架

转载 作者:行者123 更新时间:2023-12-03 03:36:37 25 4
gpt4 key购买 nike

假设有人想要构建一个新颖的泛型类,Novel[A]。该类将包含许多有用的方法——也许它是一种集合类型——因此您希望对其进行子类化。但您希望这些方法返回子类的类型,而不是原始类型。在 Scala 2.8 中,要使该类的方法返回相关子类而不是原始子类,需要做的最少工作量是多少?例如,

class Novel[A] /* What goes here? */ {
/* Must you have stuff here? */
def reverse/* What goes here instead of :Novel[A]? */ = //...
def revrev/*?*/ = reverse.reverse
}
class ShortStory[A] extends Novel[A] /* What goes here? */ {
override def reverse: /*?*/ = //...
}
val ss = new ShortStory[String]
val ss2 = ss.revrev // Type had better be ShortStory[String], not Novel[String]

如果您希望 Novel 协变,这个最小量会改变吗?

(2.8 集合除其他外,还执行此操作,但它们还以更奇特(且有用)的方式处理返回类型 - 问题是,如果只想要这种子类型,那么可以摆脱的框架有多么少 - 总是 -返回子类型功能。)

编辑:假设在上面的代码中,reverse 进行了复制。如果进行就地修改然后返回自己,则可以使用 this.type,但这不起作用,因为副本不是 this

Arjan 链接到另一个问题,该问题提出了以下解决方案:

def reverse: this.type = {
/*creation of new object*/.asInstanceOf[this.type]
}

这基本上是为了得到我们想要的东西而欺骗类型系统。但这并不是真正的解决方案,因为现在我们对类型系统撒了谎,编译器无法帮助我们确保我们确实确实得到一个ShortStory 回到我们认为我们可以做到的时候。 (例如,我们不必在上面的示例中重写 reverse 来让编译器满意,但我们的类型不会是我们想要的。)

最佳答案

编辑:我刚刚意识到雷克斯在他的示例中有一个具体的小说类,而不是我在下面使用的特征。因此,trait 的实现有点太简单了,无法解决 Rex 的问题。它也可以使用具体的类来完成(见下文),但我可以实现该工作的唯一方法是通过一些转换,这使得这并不是真正的“编译时类型安全”。这所以这不符合解决方案。

也许不是最漂亮的,但使用抽象成员类型的简单示例可以实现如下:


trait Novel[A] {
type T <: Novel[A]
def reverse : T
def revrev : T#T = reverse.reverse
}

class ShortStory[A](var story: String) extends Novel[A] {
type T = ShortStory[A]
def reverse : T = new ShortStory[A](story reverse)
def myMethod: Unit = println("a short story method")
}

scala> val ss1 = new ShortStory[String]("the story so far")
ss1: ShortStory[String] = ShortStory@5debf305

scala> val ssRev = ss1 reverse
ssRev: ss1.T = ShortStory@5ae9581b

scala> ssRev story
res0: String = raf os yrots eht

scala> val ssRevRev = ss1 revrev
ssRevRev: ss1.T#T = ShortStory@2429de03

scala> ssRevRev story
res1: String = the story so far

scala> ssRevRev myMethod
a short story method

这当然是最小的,但我怀疑这是否足以用作一种框架。当然,返回的类型并不像 Scala 集合框架中那样清晰,所以这可能有点太简单了。 对于给定的情况,它似乎可以完成这项工作。 如上所述,这不能完成给定的情况,因此这里需要一些其他解决方案。

另一个编辑:也可以使用具体类来完成类似的操作,尽管这也不足以保证类型安全:


class Novel[A](var story: String) {
type T <: Novel[A]
def reverse: T = new Novel[A](story reverse).asInstanceOf[T]
def revrev : T#T = reverse.reverse
}
class ShortStory[A](var s: String) extends Novel[A](s) {
type T = ShortStory[A]
override def reverse : T = new ShortStory(story reverse)
def myMethod: Unit = println("a short story method")
}

代码将按照特征示例中的方式工作。但它也遇到了雷克斯在他的编辑中提到的同样的问题。编译时不需要覆盖 ShortStory。但是,如果您不这样做并在 ShortStory 实例上调用反向方法,它将在运行时失败。

关于scala - Scala 中用于具有继承返回类型的集合的最小框架,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3007464/

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