gpt4 book ai didi

scala - 为什么我们必须显式指定 ClassTag 类型类

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

现在 scala 已经通过 ClassTag 迭代到 JVM 类型删除修复。 typeclass,为什么它是一个选择加入,而不是让编译器总是捕获类型签名以进行运行时检查。拥有一个隐式参数化类型约束将可以调用 classTag[T]无论泛型参数声明如何。

编辑 :我应该澄清一下,我并不是说 scala 应该将幕后的签名更改为始终包含 ClassTag .相反,我的意思是因为 ClassTag表明 scala 可以捕获运行时类型信息,从而避免类型删除限制,为什么不能将该捕获作为编译器的一部分隐含,以便该信息在 scala 代码中始终可用?

我怀疑它与向后兼容性、Java 生态系统兼容性、二进制大小或运行时开销相关,但这些只是推测。

最佳答案

向后兼容性将被完全破坏,真的。如果您有一个简单的方法,例如:

def foo[A](a: A)(implicit something: SomeType) = ???

那么假设在下一个版本的Scala中,编译器突然添加了隐式 ClassTag s 到所有具有类型参数的方法的签名。这种方法会被打破。任何被显式调用的地方,例如 foo(a)(someTypeValue)不会再工作了。二进制和源代码兼容性将消失。

Java 互操作性将是丑陋的。假设我们的方法现在看起来像这样:
def foo[A : ClassTag](a: A) = ???

因为 ClassTag s 是由 Scala 编译器生成的,在 Java 中使用这种方法会更加困难。您必须创建 ClassTag你自己。
ClassTag<MyClass> tag = scala.reflect.ClassTag$.MODULE$.apply(MyClass.class);
foo(a, tag);

我的 Java 可能不是 100% 正确,但你明白了。任何参数化的东西都会变得非常难看。好吧,如果它需要一个隐式 ClassTag ,但是需要这样做的方法类别会急剧增加。

此外,在我们(至少是我)使用的大多数参数化方法中,类型删除并不是什么大问题。我认为自动需要 ClassTag由于上述原因,对于每个类型参数来说,麻烦远大于它的帮助。

当然这会增加更多的编译器开销,因为它需要生成更多 ClassTag s 比通常情况下。我认为它不会增加更多的运行时开销,除非 ClassTag有所作为。例如,在像下面这样的简单方法中, ClassTag并没有真正做任何事情:
def foo[A : ClassTag](a: A): A = a

我们还应该注意到,它们也不完美。因此,添加它们并不是消除问题的最终解决方案。
val list = List(1, "abc", List(1, 2, 3), List("a", "b"))
def find[A: ClassTag](l: List[Any]): Option[A] =
l collectFirst { case a: A => a }

scala> find[List[String]]
res2: Option[List[String]] = Some(List(1, 2, 3)) // Not quite! And no warnings, either.

添加 ClassTag每个类实例都会增加开销,并且肯定也会破坏兼容性。在很多地方也是不可能的。我们不能只注入(inject) java.lang.StringClassTag .此外,我们仍然很容易被删除。拥有 ClassTag每个类中的字段确实不比使用 getClass好.我们可以进行类似的比较
case a if(a.getClass == classOf[String]) => a.asInstanceOf[String]

但这非常丑陋,需要类型转换,而且不一定是 ClassTag旨在修复。如果我用我的 find 尝试这样的事情方法,它根本行不通。
// Can't compile
def find[A](l: List[Any]): Option[A] =
l collectFirst { case a if(a.getClass == classOf[A]) => a.asInstanceOf[A] }

即使我要设计这个以某种方式与 ClassTag 合作,它会从哪里来?我不能说 a.classTag == classTag[A] , 因为 A已经被抹去了。我需要 ClassTag在方法调用站点。

关于scala - 为什么我们必须显式指定 ClassTag 类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30293025/

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