泛型 – 通用数据结构的默认值
我想写一个SparseVector [T]类,其中T可以是double,int或boolean.
该类不会被数组支持(因为我想要一个稀疏数据结构)但我已经看到,当我构建一个AnyVal类型的空数组时,元素被初始化为默认值.例如: scala> new Array[Int](10) res0: Array[Int] = Array(0,0) scala> new Array[Boolean](10) res1: Array[Boolean] = Array(false,false,false) scala> new Array[Double](10) res2: Array[Double] = Array(0.0,0.0,0.0) 如何在班级中包含此默认值?我想要的行为是: val v = new SparseVector[Double](100) println( v(12) ) // should print '0.0' val w = new SparseVector[Boolean](100) println( v(85) ) // should print 'false' 谢谢 解决方法
您可以利用Scala已经为您提供获取类型默认值的方法这一事实.当你写var x:Int = _时,这会将x初始化为0.类似于所有AnyVal类型.所有AnyRef类型都初始化为null.
记住这一点,您可以重写稀疏的矢量类,如下所示: class SparseVector[T](val size: Int) { import scala.collection.mutable.Map private var default: T = _ private[this] val storage = Map[Int,T]() def apply(key: Int) = if(key < size) storage.getOrElse(key,default) else throw new IllegalArgumentException("Index " + key + " out of bounds") def update(key: Int,value: T) { storage(key) = value } } 现在代码如下所示按预期工作: scala> val b = new SparseVector[Boolean](10) b: SparseVector[Boolean] = SparseVector@cfd22a scala> b(1) res20: Boolean = false scala> b(1) = true scala> b(1) res22: Boolean = true scala> val i = new SparseVector[Int](10) i: SparseVector[Int] = SparseVector@1813c12 scala> i(1) res23: Int = 0 scala> i(1) = 10 scala> i(1) res25: Int = 10 scala> i(10) java.lang.IllegalArgumentException: Index 10 out of bounds 我可能会对这个课程做一些改进: >使用`toString`方法以合理的方式打印集合 object SparseVector { def apply[T](size: Int) = new SparseVector[T](size) def apply[T](size: Int,default: T) = { val result = new SparseVector[T](size) result.default = default result } } 现在这个工作: scala> val b = SparseVector[Boolean](10,true) b: SparseVector[Boolean] = SparseVector@126f29f scala> b(4) res28: Boolean = true scala> val i = SparseVector[Int](10,42) i: SparseVector[Int] = SparseVector@b9979b scala> i(3) res30: Int = 42 编辑:我编写的代码适用于Scala 2.7.6.final. Mitch Blevins指出,当使用Scala 2.8r.19890运行时,代码会将null作为AnyVal类型的默认值.正如评论中所解释的那样,这不应该是可能的,因为Null不是AnyVal的子类型.如果使用2.8,一般的想法应该是相似的,因为var b:Boolean = _仍然应该给你布尔类型的默认值.使用集合存储稀疏向量可能会有所不同,但正如我在评论中所说,我不熟悉2.8集合的重新设计. EDIT2:…无法实现null行为,但遗憾的是它.做一些more research into the problem似乎由于类型擦除,字段默认值始终初始化为null.之后……奇怪随之而来.有关讨论,请参阅Mitch’s post,以及一些重现问题的熊骨代码. 为了使代码正常工作,我尝试过但失败了: > null.asInstanceOf [T] – 不,Java没有具体化的泛型.这仍然是空的 从概念上讲,我的解决方案应该有效.但它不是由于我在Scala Trac中有reported的非常奇怪的行为. 有关可为空的AnyVals的详细讨论,另请参阅this blog post. – Flaviu Cipcigan (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |