gpt4 book ai didi

斯卡拉。通用类声明麻烦

转载 作者:行者123 更新时间:2023-12-01 06:52:46 25 4
gpt4 key购买 nike

我在 Scala 中的类声明遇到了麻烦:

   class Class2[
A,
B <: Class2[A,B,C],
C <: Class3[A,C]
]


class Class3[
A,
C <: Class3[A,C]
]

class Class1[
A,
B <: Class2[A,B,C],
C <: Class3[A,C]
](obj : B) { ... }

这是正确的声明,但每次我想创建该类的实例时,我都需要手动指定参数 A 和 C。喜欢:

val X = Class1[Type1, Type2, Type3](correct_object_of_Type2)

如果我尝试 val X = Class1(OBJ) 它将导致错误 ...types [Nothing, B, Nothing] do not conform to [A, B, C] ...

为什么 Scala 不从 B 推断类型 A 和 C?以及如何为 Scala 编译器声明类,以便它能够自己指定 A、C?谢谢

编辑

我很抱歉公式化,最初的任务是正确定义 Class1 如下:

   class Class2[
A,
B <: Class2[A,B,C],
C <: Class3[A,C]
]


class Class3[
A,
C <: Class2[A,C]
]

??class Class1(obj : Class2) { ... }??

... 这样调用 val x = Class1(obj) 是正确的,其中 obj: Class2。当我尝试按上述方式定义它时,出现错误 Class2 takes type parameters。有什么想法吗?

抱歉不准确。

最佳答案

可以通过将约束编码为隐式参数来推断类型参数:

class Class2[X, Y, Z]
class Class3[X, y]

class Class1[A, B, C](obj: B)(implicit
evB: B <:< Class2[A, B, C],
evC: C <:< Class3[A, C]
)

然后:

scala> class Foo extends Class3[String, Foo]
defined class Foo

scala> class Bar extends Class2[String, Bar, Foo]
defined class Bar

scala> new Class1(new Bar)
res0: Class1[String,Bar,Foo] = Class1@ff5b51f

如果您需要使用 BC 的实例作为 Class2[A, B, C]Class3[A , C]Class1 的定义中,您可以对它们应用适当的证据参数(evBevC)。

您的版本不起作用,因为 Scala 的类型推断系统非常有限。它将首先求解 A 并以 Nothing 结束,因为构造函数的参数中没有 A。接下来它将尝试求解 B,但无法找到满足约束的值,因为它已经确定 ANothing

因此您必须决定类型推断是否值得增加一点复杂性和运行时开销。有时是这样,但根据我的经验,当你拥有这样的类且关系已经相当复杂时,通常不是这样。

关于斯卡拉。通用类声明麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35585968/

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