Ошибка приращения/уменьшения перегрузки оператора Groovy

У меня есть следующий фрагмент кода Groovy, который пытается использовать перегрузку оператора для увеличения, уменьшения и равенства. Все это создает два экземпляра, выполняет приращение и уменьшение одного из экземпляров, а затем сравнивает два экземпляра, используя перегруженные методы equals. Когда я делаю сравнение, оно терпит неудачу. Оба должны быть 100, когда этот код завершится. (операторы печати показывают это, но одна из функций toString() кажется неправильной). Что я здесь делаю неправильно?

Это с groovy 1.8.6

class Overload {
    def value

    public Overload(value = 0) {
        this.value = value
    }

    def next() {
        value = value + 1;
    }

    def previous() {
        value = value - 1;
    }

    def boolean equals(other) {
        if (value == other?.value) {
            return true
        }

        return false
    }

    def String toString() {
        "value is = ${value}"
    }
}

def cls1 = new Overload(100)
def cls2 = new Overload(100)

cls1++
cls1--
if (cls1 == cls2) {
    println("cls1 == cls2")
}
else {
    println("cls1 != cls2")
}

println(cls1.toString())
println(cls2.toString())

Выход:

cls1 != cls2
100
value is = 100

person jmq    schedule 15.05.2012    source источник


Ответы (2)


Проблема заключается в методах увеличения и уменьшения экземпляра Overload.

Groovy имеет функцию неявного возврата для последнего вычисленного выражения. Когда вы вызываете cls1++, теперь объект является целым числом, поэтому мы не видим вывод переопределенного метода toString.

def next() {
    value = value + 1
    return this
}

def previous() {
    value = value - 1
    return this
}

Проверь сейчас:

assert cls1.class == Overload
assert cls2.class == Overload
assert cls1 == cls2
assert cls1 == 100
assert cls2 == 100
person Arturo Herrero    schedule 15.05.2012
comment
О боже, это странно. Таким образом, groovy автоматически упаковывает возврат и преобразует весь класс в унарную операцию. Ой. Я не понимал, что в этом случае у него есть возврат и что он будет делать это. Спасибо, это действительно помогло. Я должен быть осторожнее с этим. - person jmq; 16.05.2012

В качестве быстрого дополнительного комментария вам не нужно использовать def при определении возвращаемого типа ваших методов. Более чистая версия вашего класса:

class Overload {
    def value

    public Overload(value = 0) {
        this.value = value
    }

    def next() {
        value = value + 1
        this
    }

    def previous() {
        value = value - 1
        this
    }

    boolean equals(other) {
        value == other?.value
    }

    String toString() {
        "value is = ${value}"
    }
}
person tim_yates    schedule 16.05.2012