泛型 – 当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
}

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...