Scala 中的类型提取

发布于 2024-11-06 04:36:19 字数 679 浏览 0 评论 0原文

我对 Scala 和高级编程语言还很陌生。我尝试解决以下问题。

我已经得到:

val s: Seq[SomeMutableType[_]]

我假设序列中的所有元素都属于同一类型(但目前不知道是哪一个)。

我该如何调用:

def proc[T](v0: SomeMutableType[T], v1: SomeMutableType[T]) { /* ... */ }

编译器抱怨

proc(s(0), s(1))

  • 类型不匹配;找到:SomeMutableType[_$351],其中类型 _$351 需要: SomeMutableType[Any] 注意:_$351 <:Any,但是类 SomeMutableType 在类型 T 中是不变的。 可能希望将 T 定义为 +T。 (SLS 4.5)

我考虑过协变的事情,但我不认为它对我的情况有意义。我只是希望编译器相信我说的 s(0) 和 s(1) 是同一类型!我通常通过一些转换来完成此操作,但我无法在这里转换为 SomeMutableType[T],因为 T 由于擦除而未知。当然,我不能改变proc的定义。

I am pretty new to Scala and advanced programming languages. I try to solve the following problem.

I have got:

val s: Seq[SomeMutableType[_]]

I assume that all elements in the sequence are of the same type (but do not know which one at this point).

How may I call :

def proc[T](v0: SomeMutableType[T], v1: SomeMutableType[T]) { /* ... */ }

with something like

proc(s(0), s(1))

The compiler complains :

  • type mismatch; found : SomeMutableType[_$351] where type _$351 required:
    SomeMutableType[Any] Note: _$351 <: Any, but class SomeMutableType is invariant in type T. You
    may wish to define T as +T instead. (SLS 4.5)

I thought about that covariant thing, but I do not believe it makes sense in my case. I just want the compiler believe me when I say that s(0) and s(1) are of the same type! I usually do this via some casting, but I cannot cast to SomeMutableType[T] here since T is unknown due to erasure. Of course, I cannot change the definition of proc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

病女 2024-11-13 04:36:19

问题是你确实无法做出这样的保证。例如:

scala> import scala.collection.mutable.Buffer
import scala.collection.mutable.Buffer

scala> val s: Seq[Buffer[_]] = Seq(Buffer(1), Buffer("a"))
s: Seq[scala.collection.mutable.Buffer[_]] = List(ArrayBuffer(1), ArrayBuffer(a))

看到了吗?您知道s(0)s(1)是同一类型,因为它们可能不是同一类型类型。

此时,您应该问一个关于您想要完成什么的问题,而不是问您想要如何解决问题,如何。你采取的这些方法行不通。退后一步,思考您试图用这种方法解决什么问题,并询问如何解决该问题。

例如,你说:

我假设序列中的所有元素都具有相同的类型(但不知道是哪个)
此时一个)。

您可能想要做的是参数化一个类或方法,并在声明 s 时使用其类型参数。或者,也许根本就没有s

The problem is that you truly cannot make such a guarantee. For example:

scala> import scala.collection.mutable.Buffer
import scala.collection.mutable.Buffer

scala> val s: Seq[Buffer[_]] = Seq(Buffer(1), Buffer("a"))
s: Seq[scala.collection.mutable.Buffer[_]] = List(ArrayBuffer(1), ArrayBuffer(a))

See? You don't know that s(0) and s(1) are of the same type, because they may not be of the same type.

At this point, you should ask a question about what you want to accomplish, instead of asking how to solve a problem in how you want to accomplish it. They way you took won't work. Step back, think what problem you were trying to solve with this approach, and ask how to solve that problem.

For instance, you say:

I assume that all elements in the sequence are of the same type (but do not know which
one at this point).

It may be that what you want to do is parameterize a class or method, and use its type parameter when declaring s. Or, maybe, not have an s at all.

懵少女 2024-11-13 04:36:19

我是 Scala 的新手,但据我所知,您的问题是在声明 s 时使用通配符类型参数:

val s: Seq[SomeMutableType[_]]

据我所知,类型擦除总是会发生,而您真正想要的是参数化类型绑定到 s 初始化的位置。

例如:

scala> class Erased(val s: List[_])
defined class Erased

scala> new Erased(List(1,2,3)).s.head
res21: Any = 1

如果您改为使用

scala> class Kept[T](val s: List[T])
defined class Kept

scala> new Kept(List(1,2,3)).s.head
res22: Int = 1

那么 s 的内容将保留其类型信息,因为它绑定到 T。即,这正是您告诉编译器“s(0) 和 s(1) 具有相同类型”的方式。

I am new to Scala, but as far as I can see your problem is the use of a wildcard type parameter when you declare s:

val s: Seq[SomeMutableType[_]]

As far as I understand, type erasure will always happen and what you really want here is a parameterised type bound to where s is initialised.

For example:

scala> class Erased(val s: List[_])
defined class Erased

scala> new Erased(List(1,2,3)).s.head
res21: Any = 1

If instead you use

scala> class Kept[T](val s: List[T])
defined class Kept

scala> new Kept(List(1,2,3)).s.head
res22: Int = 1

Then the contents of s retain their type information as it is bound to T. i.e. This is exactly how you tell the compiler "that s(0) and s(1) are of the same type".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文