Я пытаюсь создать некоторый код алгебры изображений, который может работать с изображениями (в основном линейный пиксельный буфер + размеры), которые имеют разные типы для пикселя. Чтобы заставить это работать, я определил параметризованную черту Pixel с помощью нескольких методов, которые должны быть в состоянии использоваться с любым подклассом Pixel. (На данный момент меня интересуют только операции, которые работают с одним и тем же типом пикселей.) Вот оно:
trait Pixel[T <: Pixel[T]] {
def div(v: Double): T
def div(v: T): T
}
Теперь я определяю один тип пикселей, который имеет хранилище на основе трех двойных (в основном RGB 0,0-1,0), я назвал его TripleDoublePixel:
class TripleDoublePixel(v: Array[Double]) extends Pixel[TripleDoublePixel] {
var data: Array[Double] = v
def this() = this(Array(0.0, 0.0, 0.0))
def div(v: Double): TripleDoublePixel = {
new TripleDoublePixel(data.map(x => x / v))
}
def div(v: TripleDoublePixel): TripleDoublePixel = {
var tmp = new Array[Double](3)
tmp(0) = data(0) / v.data(0)
tmp(1) = data(1) / v.data(1)
tmp(2) = data(2) / v.data(2)
new TripleDoublePixel(tmp)
}
}
Затем мы определяем изображение, используя пиксели:
class Image[T](nsize: Array[Int], ndata: Array[T]) {
val size: Array[Int] = nsize
val data: Array[T] = ndata
def this(isize: Array[Int]) {
this(isize, new Array[T](isize(0) * isize(1)))
}
def this(img: Image[T]) {
this(img.size, new Array[T](img.size(0) * img.size(1)))
for (i <- 0 until img.data.size) {
data(i) = img.data(i)
}
}
}
(Я думаю, что я мог бы обойтись без явного объявления размера и данных и использовать только то, что было названо в конструкторе по умолчанию, но я не получил это работать.)
Теперь я хочу написать код для его использования, который не должен знать, какого типа пиксели. Например:
def idiv[T](a: Image[T], b: Image[T]) {
for (i <- 0 until a.data.size) {
a.data(i) = a.data(i).div(b.data(i))
}
}
К сожалению, это не компилируется:
(fragment of lindet-gen.scala):145:
error: value div is not a member of T
a.data(i) = a.data(i).div(b.data(i))
Мне сказали в #scala, что это сработало для кого-то другого, но это было на 2.8. Я пытался запустить 2.8-rc1, но RC1 для меня не компилируется. Есть ли способ заставить это работать в 2.7.7?