gpt4 book ai didi

Scala - 用边界覆盖类型成员

转载 作者:行者123 更新时间:2023-12-04 18:55:52 25 4
gpt4 key购买 nike

我在 Scala 代码中的特征层次结构存在以下问题:

首先,我有一个基本特征MyTrait[A]有这样的定义:

trait MyTrait[A] {
def v1: A
}

然后是特征的定义 Base使用类型成员:
trait Base[A] {
type T <: MyTrait[A]
val baseV: T
}

最后,一个特征 Gen覆盖 Base的类型成员。
trait Gen[A, X <: MyTrait[A]] extends Base[A] {
type T = X
}

问题是在 Gen trait 似乎类型成员的边界丢失了。这可以通过以下测试来证明:

编译:
trait Test1 {
val x: Base[_]
println(x.baseV.v1)
}

不编译( value v1 is not a member of Test2.this.x.T ):
trait Test2 {
val x: Gen[_, _]
println(x.baseV.v1)
}

我想知道这是语言的限制还是有解决方法。关于stackowerflow( 12 )的类似主题的问题似乎集中在与我不同的方面,我真的很茫然,因为我在 Scala 中找不到关于此类行为的太多信息。

这个问题的Scala代码模板可以在 scastie上找到。

最佳答案

这有效:

trait Test2 {
val x: Gen[A, X] forSome { type A; type X <: MyTrait[A] }
println(x.baseV.v1)
}

我相信问题是
Gen[_, _]

Has to mean
Gen[_ >: Nothing <: Any, _ >: Nothing <: Any]

这与
Gen[A, X] forSome { type A; type X }

也就是说,即使 Gen 的边界说 X <: MyTrait[A] ,通配符不继承该界限。您可以在这里看到类似的问题:
trait Data { def data: String }
trait Box[A <: Data] { def data: A }
def unbox(b: Box[_]): String = b.data.data // nope; the wildcard is not <: Data

我们可以明确地为通配符添加边界。然而,因为第二个通配符的界限取决于第一个,我们被迫使用扩展 forSome存在的语法,所以我们可以命名 A并使用它两次。
Gen[A, _ <: MyTrait[A]] forSome { type A }

我选择将所有内容都放在存在条款中,这等效于:
Gen[A, X] forSome { type A; type X <: MyTrait[A] }

你也可以使用
Gen[_, _ <: MyTrait[_]]

但这并不等效,因为它不涉及左右参数。如 Gen[A, _]包含一个 A除了 MyTrait[A] ,然后使用 x: Gen[_, _ <: MyTrait[_]]将使用不兼容的类型呈现“裸”值和“包装”值。

关于Scala - 用边界覆盖类型成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53875742/

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