繁体   English   中英

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

[英]Is there are way to create a generic class with a trait or mixin that is a subtype of the type parameter

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

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发现类WithExtraDataT使用ExtraData扩展T {^:12:错误:非法继承; supertype T不是mixin trait的超类Object的子类ExtraData类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:警告:纯粹的表达在陈述中没有任何作用; 多行表达式可能需要括起括号self:T => t ^定义的类WithExtraData

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

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

我认为你可以合理得到的最接近的(至少没有宏)不是扩展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]每当ExternalType1是必需的。

如果我理解你是正确的,你基本上尝试用值表示的其他类型信息来丰富你的类型? 在这种情况下,您寻找的概念称为依赖类型

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM