首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这个转换成亚型安全吗?

这个转换成亚型安全吗?
EN

Stack Overflow用户
提问于 2016-09-24 03:22:36
回答 1查看 267关注 0票数 1

给定这些类和变量:

代码语言:javascript
复制
abstract class Base[T <: Base[_]] {
  val self: T
  def me(): T = self
}

class Derived extends Base[Derived] {
  lazy val self = this
  def whoAmI() = "Im derived"
}

val d = new Derived

我可以安全地打电话给d.foo().whoAmI()

但这也是安全的类型吗?

代码语言:javascript
复制
abstract class Base[T <: Base[_]] {
  def me(): T = this.asInstanceOf[T]
}

class Derived extends Base[Derived] {
  def whoAmI() = "Im derived"
}

我在考虑一些边缘情况,在这种情况下,其他类从派生扩展,而转换可能会爆炸。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-24 03:35:02

这类型不安全。如果您发现您需要使用asInstanceOf来编译它,答案将是“否”。只有在只有一个子类型的情况下,才能安全地将其转换为子类型。否则,你就不能保证。

考虑一下这个例子:

代码语言:javascript
复制
abstract class Base[T <: Base[_]] {
  def me(): T = this.asInstanceOf[T]
}

class A extends Base[A]
class B extends Base[A]

scala> val b = new B
b: B = B@4b44655e

scala> b.me
java.lang.ClassCastException: B cannot be cast to A
  ... 33 elided

我们正在扩展的T中的Base必须与我们正在创建的子类型相同,这是没有限制的--只是它们都扩展了BaseAB都是Base[_],但B不是A,所以向A转换是不安全的。

通过在Base中引入一个自我类型,并要求它也是一个T,这是很容易解决的。然后,我们可以确定this是一个T,不需要强制转换。

代码语言:javascript
复制
abstract class Base[T <: Base[_]] { this: T =>
  def me(): T = this
}

这将不再编译:

代码语言:javascript
复制
scala> class B extends Base[A]
<console>:12: error: illegal inheritance;
 self-type B does not conform to Base[A]'s selftype A
       class B extends Base[A]
                       ^
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39672145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档