Интересное решение для набора текста в Scala, не работает в 2.7.7? - PullRequest
3 голосов
/ 02 мая 2010

Я пытаюсь создать некоторый код алгебры изображений, который может работать с изображениями (в основном линейный пиксельный буфер + размеры), которые имеют разные типы для пикселя. Чтобы заставить это работать, я определил параметризованную черту 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?

1 Ответ

5 голосов
/ 02 мая 2010

Ваша idiv функция должна знать, что она на самом деле будет работать с пикселями.

def idiv[T <: Pixel[T]](a: Image[T], b: Image[T]) {
    for (i <- 0 until a.data.size) {
        a.data(i) = a.data(i).div(b.data(i))
    }
}

Параметр простого типа T будет определять функцию для всех возможных типов T, которые, конечно, не все поддерживают операцию div. Так что вам нужно будет установить общее ограничение, ограничивающее возможные типы Pixel s.

(Обратите внимание, что вы можете наложить это ограничение и на класс Image, предполагая, что изображение, отличное от пикселей, не имеет смысла)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...