加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么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,一切都会有所不同……

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读