是否有可能构建subj?类似的东西:
trait THasArray[T]
{
val ARRAY_SIZE = 8
val array = Array.fill[T](ARRAY_SIZE)(null)
}
效果不好 - 编译器抱怨' null'这是我需要的。我知道Option,虽然问题是,是否可以使用普通数组。
感谢。
修改
谢谢你们两个人。 我已经发现了将类标记作为隐式参数传递的技巧。
尽管如此,我已经重新制定了我原来的问题。我需要将该数组初始化一次,并且永远不会改变。所以这里的解决方案并不需要隐式的val类型标记,而是使用init函数来实现这个技巧
trait THasArray[T >: Null]
{
private var table: Seq[T] = null
protected def init(elems: (Int, T)*)(implicit manifest: Manifest[T]) =
{
val size = (elems foldLeft 0)(_ max _._1)
val array = Array.fill[T](size + 1)(null)
elems foreach { x => array(x._1) = x._2 }
table = array
}
}
答案 0 :(得分:2)
首先,方法Array.fill
在范围内需要隐式ClassTag
。其次,null的类型为Null
,因此您需要将其强制转换为T
。第三,array
值应该是惰性的,因为ClassTag
实例仅在HasArray
创建时可用。
trait HasArray[T] {
implicit def ev: ClassTag[T]
def size: Int
lazy val array = Array.fill[T](size)(null.asInstanceOf[T])
}
case class HasStringArray(size: Int)(implicit val ev: ClassTag[String]) extends HasArray[String]
scala> HasStringArray(8).array
res11: Array[String] = Array(null, null, null, null, null, null, null, null)
答案 1 :(得分:2)
T
需要具有Null
的下限,因为并非Scala中的所有值都可以为空。扩展AnyVal
的类型由JVM原语表示,它们不能为空;例如,没有null Int
。
另外,请查看Array.fill
的方法签名:
def fill[T: ClassTag](n: Int)(elem: => T): Array[T]
上下文绑定T: ClassTag
表示fill
具有类型为ClassTag[T]
的隐式参数。特征的类型参数不能具有上下文绑定,因此遗憾的是,当您继承ClassTag
时,您必须稍微偏离THasArray
范围。< / p>
trait THasArray[T >: Null] {
implicit def classTagT: ClassTag[T]
val ARRAY_SIZE = 8
lazy val array = Array.fill[T](ARRAY_SIZE)(null)
}
class Foo[T >: Null](implicit val classTagT: ClassTag[T])
extends THasArray[T]