微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

泛型 – 当Scala类型参数用作基类的参数时,它是否可以引用自身?

如果我有以下 Scala类型层次结构:

// Base traits
trait TA[X <: TA[X,Y],Y <: TB[X,Y]]
trait TB[X <: TA[X,Y]]
trait TC[X <: TA[X,_]]

// More specific traits
trait TI[X <: TI[X,Y <: TJ[X,Y]] extends TA[X,Y]
trait TJ[X <: TI[X,Y]] extends TB[X,Y]
trait TK[X <: TI[X,_]] extends TC[X]

// Concrete class that should implement TK,but does not compile
class Z extends TK[TI[_,_]]

// What is needed to be able to get class Z to compile
// The reference of X to itself has been removed.
trait TC2[X <: TA[_,_]]
trait TK2[X <: TI[_,_]] extends TC2[X]
class Z2 extends TK2[TI[_,_]]

TC将是某种TA的通用经理.

TK将是更具体的TA(TI)的更具体的管理者.

Z将是管理实现TI的任何对象的具体实现.

Z不合法,但Z2是.不幸的是,TC和TK比TC2和TK2更具特异性.那么有没有办法用TC和TK来代替TC,而不是TC2和TK2?

[编辑]我没有在我原来的问题中说,我有点理解为什么Z不健全.我真正想知道的是,如果有一种方式可以说:

class Z3 extends TK[TI[TI,_]]

解决方法

当您具有复杂的相互递归类型边界时,通常可以帮助您查看是否可以使用抽象类型成员将问题转换为等效的问题.如果我们机械地做到这一点,你的基础和更具体的特征最终看起来像,

// Base traits
trait TA {
  type X <: TA
  type Y <: TB
} 
trait TB {
  type X <: TA
  type Y <: TB
} 

trait TC {
  self =>
  type X <: TA { type X <: self.X }
} 

// More specific traits
trait TI extends TA {
  type X <: TI
  type Y <: TJ
} 

trait TJ extends TB { 
  type X <: TI
  type Y <: TJ
}

trait TK {
  self =>
  type X <: TI { type X <: self.X }
}

现在我们有一个简单的Z定义,

class Z extends TK {
  type X = TI
}

注意,TA,TB和TI,TJ的成员的定义基本相同.因为这些类型现在是类型成员,所以我们可以将它们分解为常见的基类型,如下所示,

// Base traits
trait T0 {
  type X <: TA
  type Y <: TB
} 
trait TA extends T0
trait TB extends T0

trait TC {
  self =>
  type X <: TA { type X <: self.X }
}

// More specific traits
trait T1 extends T0 {
  type X <: TI
  type Y <: TJ
}

trait TI extends TA with T1
trait TJ extends TB with T1

trait TK extends TC {
  self =>
  type X <: TI { type X <: self.X }
}

class Z extends TK {
  type X = TI
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐