为什么Scala不会自动“处理”ClassTags?
发布时间:2020-12-16 18:51:39 所属栏目:安全 来源:网络整理
导读:类标签似乎非常容易使用,但是,如果不是全部的话,至少在某些情况下,始终可靠地自动插入ClassTag样板是否在数学上是不可能的?考虑这个例子: def foo[T: ClassTag] = { val cls = classTag[T].runtimeClass.asInstanceOf[Class[T]] val myList: Seq[T] = pars
类标签似乎非常容易使用,但是,如果不是全部的话,至少在某些情况下,始终可靠地自动插入ClassTag样板是否在数学上是不可能的?考虑这个例子:
def foo[T: ClassTag] = { val cls = classTag[T].runtimeClass.asInstanceOf[Class[T]] val myList: Seq[T] = parseList(rawJson,cls) // let's assume parseList a library method that needs to work with a Class instance (e.g. RestFB's fetchConnnection) ... } 斯卡拉为什么不让我写: def foo[T] = { val cls = classOf[T] val myList: Seq[T] = parseList(rawJson,cls) // let's assume parseList a library method that needs to work with a Class instance (e.g. RestFB's fetchConnnection) ... } …并自动将后者转换为前者? 是否有技术原因,例如编译器/反射库并不总能可靠地确定类标签的可取性?或者纯粹是一种有意识的设计选择来保持这一点?例如,鼓励程序员首先避免使用类标签以获得更清洁的设计和更好的性能,即使已知在许多情况下它是不可能的? 附:我不是在问为什么Scala不会(也不建议它)将ClassTag魔法添加到具有泛型类型参数的每个方法定义中;我只是问为什么在需要/不可避免的时候不能自动完成. 解决方法
这个语法:
def foo[T: ClassTag] = ... 实际上是这个的简写: def foo[T](implicit ev: ClassTag[T]) = ... 这意味着如果为每个泛型类型参数提供了ClassTag [T],那么每个函数都会有附加隐藏参数,甚至几个. 这当然是完全不合需要的.这种方法最突出的缺点之一是使用泛型时几乎破坏了Java的互操作性: SomeClass someClass = new SomeClass(); someClass.foo<Integer>(ClassTag.apply(Integer.class)); 想象一下更高级的通用方法和参数.这只是为了匹配泛型类型的能力,这几乎是不需要的. 调用Java泛型方法也是不明确的.这里应该调用哪种方法: val jc = new JavaClass jc.foo[Int]() 如果JavaClass定义如下: public class JavaClass { public <T> void foo() { ... } public <T> void foo(ClassTag<T> ct) { ... } } ? 当然,如果Java支持reified generics,一切都会有所不同…… (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |