Как вы инициализируете свойства с помощью пользовательских сеттеров, которые выполняют проверку ошибок? - PullRequest
3 голосов
/ 03 марта 2020

Как я могу инициализировать свойство с помощью пользовательского установщика?

Например, в своем установщике я проверяю, чтобы значение не было отрицательным.

class Foo(length: Int) {
    var length = length
        set(value) {
            if (value < 0) throw IllegalArgumentException("Can't be negative.")
            field = value
        }
    }
}

Однако, если я его назову как Foo(-5) исключение не вызывается, так как установщики не вызываются при инициализации свойств.

Еще одна вещь, которую я попробовал, была ниже, но тогда кажется неправильным устанавливать длину дважды.

class Foo(length: Int) {
    var length = length
        set(value) {
            if (value < 0) throw IllegalArgumentException("Can't be negative.")
            field = value
        }
    }

    init {
        this.length = length
    }
}

Наконец, я подумал о приведенном ниже коде, но это кажется неправильным, поскольку вы проверяете неправильное значение в двух местах.

class Foo(length: Int) {
    init {
        if (length < 0) throw IllegalArgumentException("Can't be negative.")
    }

    var length = length
        set(value) {
            if (value < 0) throw IllegalArgumentException("Can't be negative.")
            field = value
        }
    }
}

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Существует также «четвертый» способ (на самом деле вариация вашего второго):

class Foo {
    var length = 0 // You cannot even assign length here
        set(value) {
            if (value < 0) throw IllegalArgumentException("Can't be negative.")
            field = value
        }

    // Having to use a warning suppression is the primary drawback of this 'fourth' way
    @Suppress("ConvertSecondaryConstructorToPrimary")
    constructor(length: Int) {
        this.length = length
    }
}

Помимо аннотации подавления предупреждений express, на мой взгляд, это самый чистый, без повторений и с минимальным шаблоном.

1 голос
/ 04 марта 2020

Ваш второй метод настолько чист, насколько вы можете его сделать, хотя я бы установил начальное значение для некоторой константы, например 0, а не length. Затем, если вы забудете назначить length в блоке init, вы получите предупреждение компилятора о том, что параметр конструктора не используется.

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