scala - Using private mutable collections of a covariant type -
i have covariant scala type thing[+b]
. implementation uses internal mutable queue:
private val queue : asyncqueue[b]()
asyncqueue custom mutable queue implementation, special properties can't implement in immutable version. because it's mutable, asyncqueue invariant. can't use in covariant type thing
.
since queue
private, can guarantee correctness of code: e.g. won't try assign queue
reference of type queue[any]
. how can make work, keeping thing
covariant in b
, without using casts?
(the solution casts declare asyncqueue[object]
, cast objects on enqueue/dequeue, ugly.)
eta: understand type covariance, , understand why shouldn't able declare asyncqueue of covariant type, or make asyncqueue covariant. question how design code avoid using casts everywhere.
you can make member immune variance check making private[this]
, according the spec.
scala> trait thing[+a] { def next(): } defined trait thing
expectedly,
scala> class thingie[+a](implicit t: classtag[a]) extends thing[a] { val = mutable.arraybuffer.fill[a](10)(t.runtimeclass.newinstance.asinstanceof[a]) ; private val = as.iterator ; def next() = it.next() } <console>:12: error: covariant type occurs in invariant position in type => scala.collection.mutable.arraybuffer[a] of value class thingie[+a](implicit t: classtag[a]) extends thing[a] { val = mutable.arraybuffer.fill[a](10)(t.runtimeclass.newinstance.asinstanceof[a]) ; private val = as.iterator ; def next() = it.next() }
but
scala> class thingie[+a](implicit t: classtag[a]) extends thing[a] { private[this] val = mutable.arraybuffer.fill[a](10)(t.runtimeclass.newinstance.asinstanceof[a]) ; private val = as.iterator ; def next() = it.next() } defined class thingie
and
scala> class x defined class x scala> val xs = new thingie[x] xs: thingie[x] = thingie@49f5c307 scala> xs.next res1: x = x@4816c290
Comments
Post a Comment