gpt4 book ai didi

scala - 在 Scala 中使用类型参数和混合

转载 作者:行者123 更新时间:2023-12-01 11:59:09 25 4
gpt4 key购买 nike

编辑 2:

在使用 RomanNumerals 的练习中,我使用混合宏和类型参数以及下面的代码成功实现了我想要的类型安全。本质上,它所做的是在将所有内容导入 RomanNumerals 之后,我能够编写 L X V I,但不能编写 L LX L X 因为然后我得到一个类型不匹配的编译器错误(因为这些是罗马数字的非法组合)。现在我想知道这种使用 traits、mixins 和类型参数的方式是否被认为是正确的,或者我是否在滥用语言 :) 是否有更好的方法通过一些更简单/更清洁的方式实现相同类型的安全代码?

object RomanNumerals {
trait Numeral {
def num:Int
}
trait NumeralI[N<:Numeral] extends Numeral
trait NumeralV[N<:Numeral] extends NumeralI[N] {
def I = new RomanNumeral[Numeral](1 + this.num) with Numeral
def II = new RomanNumeral[Numeral](2 + this.num) with Numeral
def III = new RomanNumeral[Numeral](3 + this.num) with Numeral
}

trait NumeralX[N<:Numeral] extends NumeralV[N] {
def IV = new RomanNumeral[Numeral](4
+ this.num) with Numeral
def V = new RomanNumeral[NumeralI[Numeral]](5
+ this.num) with NumeralV[NumeralI[Numeral]]
def IX = new RomanNumeral[Numeral](9
+ this.num) with Numeral
}

trait NumeralL[N<:Numeral] extends NumeralX[N] {
def X = new RomanNumeral[NumeralV[Numeral]](10
+ this.num) with NumeralX[NumeralV[Numeral]]
def XX = new RomanNumeral[NumeralV[Numeral]](20
+ this.num) with NumeralX[NumeralV[Numeral]]
def XXX = new RomanNumeral[NumeralV[Numeral]](30
+ this.num) with NumeralX[NumeralV[Numeral]]
}

class RomanNumeral[T <: Numeral](val num:Int) {
override def toString = num toString
def apply[N >: T <: Numeral](rn:NumeralI[N]) =
new RomanNumeral[Numeral](rn.num + num) with Numeral

def apply[N >: T <: Numeral](rn:NumeralV[N]) =
new RomanNumeral[NumeralI[Numeral]](rn.num
+ num) with NumeralV[NumeralI[Numeral]]

def apply[N >: T <: Numeral](rn:NumeralX[N]) =
new RomanNumeral[NumeralV[Numeral]](rn.num
+ num) with NumeralX[NumeralV[Numeral]]

def apply[N >: T <: Numeral](rn:NumeralL[N]) =
new RomanNumeral[NumeralX[Numeral]](rn.num
+ num) with NumeralL[NumeralX[Numeral]]

}

val I = new RomanNumeral[NumeralI[Numeral]](1) with NumeralI[Numeral]
val II = new RomanNumeral[NumeralI[Numeral]](2) with NumeralI[Numeral]
val III = new RomanNumeral[NumeralI[Numeral]](3) with NumeralI[Numeral]
val IV = new RomanNumeral[NumeralI[Numeral]](4) with NumeralI[Numeral]
val V = new RomanNumeral[NumeralI[Numeral]](5) with NumeralV[NumeralV[Numeral]]
val IX = new RomanNumeral[NumeralI[Numeral]](9) with NumeralI[Numeral]
val X = new RomanNumeral[NumeralV[Numeral]](10) with NumeralX[NumeralX[Numeral]]
val XX = new RomanNumeral[NumeralV[Numeral]](20) with NumeralX[NumeralX[Numeral]]
val XXX = new RomanNumeral[NumeralV[Numeral]](30) with NumeralX[NumeralX[Numeral]]
val XL = new RomanNumeral[NumeralV[Numeral]](40) with NumeralX[NumeralX[Numeral]]
val L = new RomanNumeral[NumeralX[Numeral]](50) with NumeralL[NumeralL[Numeral]]
}

编辑:

基于胜利者回答的进一步问题。好的,但是如果我为类型参数添加上限和下限以使 B 成为特征呢?例如

trait Bar
class Foo[T<:Bar](n:Int) {
def apply[B >: T <: Bar](f:Foo[B]) = {
new Foo[B](n + f.n) with B
}
}

或者在这种情况下 B 仍然可以是一个类?如果我知道 f 参数 too apply 的类型是 Foo[B] with B 怎么办?有没有办法使用它来将 B 与返回类型混合?

下面是原始问题

当我在 Scala 中创建对象时,我想混合一个作为类型参数获得的特征:

class Foo(val num:Int) { 
def withM[B](foo:Foo) = new Foo(foo.num) with B
}

这会导致编译错误:

error: class type required but B found
def withM[B](foo:Foo) = new Foo(foo.num) with B
^

我也试过:

class Foo(val num:Int) { 
def withM[B](foo:Foo) = new Foo(foo.num) with classOf[B]
}

但这不起作用:

error: not found: type classOf
def withM[B](foo:Foo) = new Foo(foo.num) with classOf[B]
^

有办法解决这个问题吗?这样 withM 的返回类型就变成了 Foo with B 其中 B 是传递给 withM

的类型参数

最佳答案

这种功能根本不可能(或不可用)此外,只能混合特征(和接口(interface)),并且你的类型参数可以是编译器所知的 Int。

您需要指定一个具体的特征或接口(interface)类型:

trait T
class Foo
object Test {
def apply = new Foo with T
}

关于scala - 在 Scala 中使用类型参数和混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3307404/

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