gpt4 book ai didi

Scala:没有明确已知类型参数的类型转换

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

考虑以下示例:

case class C[T](x:T) {
def f(t:T) = println(t)
type ValueType = T
}

val list = List(1 -> C(2), "hello" -> C("goodbye"))

for ((a,b) <- list) {
b.f(a)
}

在这个例子中,我知道(运行时保证) a 的类型将是一些 T , 和 b将有类型 C[T]T .当然,编译器无法知道这一点,因此我们在 b.f(a) 中得到一个输入错误。 .

为了告诉编译器这个调用没问题,我们需要做一个 typecast à la b.f(a.asInstanceOf[T]) .不幸的是, T这里不知道。所以我的问题是:如何重写 b.f(a)为了使这段代码编译?

我正在寻找一种不涉及复杂结构(以保持代码可读性)的解决方案,并且这是“干净”的,因为我们不应该依赖代码删除来使其工作(参见下面的第一种方法)。

我有一些工作方法,但由于各种原因,我发现它们并不令人满意。

我尝试过的方法:
b.asInstanceOf[C[Any]].f(a)

这有效,并且具有合理的可读性,但它基于“谎言”。 b不是 C[Any] 类型,我们没有得到运行时错误的唯一原因是因为我们依赖于 JVM 的限制(类型删除)。我认为只使用 x.asInstanceOf[X] 是一种很好的风格当我们知道 x真的是 X 类型.
  b.f(a.asInstanceOf[b.ValueType])

这应该根据我对类型系统的理解起作用。我已添加成员 ValueType上课 C为了能够显式引用类型参数 T .但是,在这种方法中,我们会收到一条神秘的错误消息:
Error:(9, 22) type mismatch;
found : b.ValueType
(which expands to) _1
required: _1
b.f(a.asInstanceOf[b.ValueType])
^

为什么?似乎提示我们期望类型 _1但输入 _1 ! (但即使这种方法有效,它也仅限于我们可以将成员 ValueType 添加到 C 的情况。如果 C 是某个现有的库类,我们也不能这样做。)
for ((a,b) <- list.asInstanceOf[List[(T,C[T]) forSome {type T}]]) {
b.f(a)
}

这个有效,并且在语义上是正确的(即,我们在调用 asInstanceOf 时不会“撒谎”)。限制是这有点不可读。此外,它在某种程度上是针对当前情况的:如果 a,b不来自同一个迭代器,那么我们可以在哪里应用这种类型转换? (此代码还有一个副作用,即对于 Intelli/J IDEA 2016.2 来说过于复杂,这会在编辑器中将其突出显示为错误。)
  val (a2,b2) = (a,b).asInstanceOf[(T,C[T]) forSome {type T}]
b2.f(a2)

a2,b2 开始,我就希望这个可以工作。现在应该有类型 TC[T]对于相同的存在 T .但是我们得到一个编译错误:
Error:(10, 9) type mismatch;
found : a2.type (with underlying type Any)
required: T
b2.f(a2)
^

为什么? (除此之外,该方法的缺点是由于创建和销毁一对而产生运行时成本(我认为)。)
  b match {
case b : C[t] => b.f(a.asInstanceOf[t])
}

这行得通。但是用匹配来封闭代码会使代码的可读性大大降低。 (而且对于 Intelli/J 来说也太复杂了。)

最佳答案

最干净的解决方案是 IMO,您使用类型捕获模式匹配找到的解决方案。通过将模式直接集成到 for 理解中,您可以使其简洁,并希望具有可读性,如下所示:

for ((a, b: C[t]) <- list) {
b.f(a.asInstanceOf[t])
}

fiddle : http://www.scala-js-fiddle.com/gist/b9030033133ee94e8c18ad772f3461a0

如果您还没有理解 for ,不幸的是,相应的模式分配不起作用:
val (c, d: C[t]) = (a, b)
d.f(c.asInstanceOf[t])

那是因为 t不在第二行的范围内。在这种情况下,您将不得不使用完整的模式匹配。

关于Scala:没有明确已知类型参数的类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39059346/

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