是否有办法创建一个具有trait或mixin的泛型类,它是类型参数

时间:2017-05-04 20:51:07

标签: scala generics traits scalaz type-constructor

我正在尝试将额外数据附加到其他类型,并具有类似于以下特征:

trait ExtraData {
  def getExtraData() : Array[Byte]
}

我现在正在使用它:

class ExternalType1WithExtraData(superType:ExternalType1, bytes:Array[Byte]) extends ExternalType1(superType.a,superType.b, ...) with ExtraData {
  def getExtraData() : Array[Byte] = bytes
}

class ExternalType2WithExtraData(superType:ExternalType2, bytes:Array[Byte]) extends ExternalType2(superType.z,superType.w, ...) with ExtraData {
  def getExtraData() : Array[Byte] = bytes
}

似乎有一种创建这些类的通用方法,但我还没有找到它。

---开始编辑 - 添加所需的行为

给定功能

def sendData(ex : ExternalType1)

我希望能够将增强类型传递给该函数。

val data:ExternalType1 = ???
val moredata:ExternalType1 = { new ExternalType1 with ExtraData{...} }
sendData(moredata)

---结束编辑

我试图按照这些方针做事,但没有成功:

// Compiler wont let me extend T
class WithExtraData[T](bytes:Array[Byte]) extends T with ExtraData{
  def getExtraData() : Array[Byte] = bytes
}
  

:12:错误:需要类类型但是找到了T          class WithExtraDataT使用ExtraData扩展T {                                                            ^   :12:错误:非法继承;超类型T.    不是超类Object的子类    混合特性ExtraData          class WithExtraDataT使用ExtraData {

扩展T
// Seems closer, but doesn't work.
class WithExtraData[T](t:T, bytes:Array[Byte]) extends ExtraData {
  this : T => t
  def getExtraData() : Array[Byte] = bytes
}
  

:13:警告:一个纯粹的表达在声明中没有任何作用;多行表达式可能需要括起括号                自我:T => Ť                            ^   已定义的类WithExtraData

     

阶> new WithExtraData [String](" hi",new ArrayByte)   :13:错误:类WithExtraData无法实例化,因为它不符合其自身类型WithExtraData [String] with String

有没有办法实现这个目标?

2 个答案:

答案 0 :(得分:2)

我认为你可以合理得到的最接近的(至少没有宏)不是扩展struct CommonValues { static var UserNum: Int = 0 } ,而是改为隐式转换:

ExternalType1

然后你可以,例如只要需要class WithExtraData[T](val value: T, bytes: Array[Byte]) extends ExtraData { def getExtraData(): Array[Byte] = bytes } object WithExtraData { implicit def getValue[T](x: WithExtraData[T]): T = x.value } 就通过WithExtraData[ExternalType1]

答案 1 :(得分:0)

如果我理解你的话,你基本上会尝试用值表示的其他类型信息来丰富你的类型?在这种情况下,您要查找的概念称为Dependent Types

Scala本身不支持此概念(例如Idris)。但是,有一些变通方法可以解决。

一个例子是使用Shapeless

import shapeless._
import SingletonTypes._

val test1: ^((20 + 50) > 1) = true
test1: Boolean(true) = true

val test2: ^((20 + 50) > 1) = false
<console>:11: error: type mismatch;
 found   : Boolean(false)
 required: Boolean(true)