Идиоматический котлин при проверке нуля - PullRequest
0 голосов
/ 24 ноября 2018

В Java я бы сделал что-то вроде этого:

class Person {

    private Record record;

    public String name() {
      record().get("name");
    }

    private Record record() {
      if (record == null) {
        refetch();
      }
      return record;
    }

    private void refetch() {
      record = service.doSomething()
    }

}

В Kotlin у меня есть этот эквивалентный код:

class Person(private var record: Record?) {

    fun name() : String {
      record().get("name");
    }

    private fun record() : Record {
      record ?: refetch()
      return record!!;
    }

    private fun refetch() {
      record = service.doSomething()
    }

}

Как видите, я использую !! оператор, и мне не очень нравится.Есть ли другой, более идиоматический способ сделать это?

Если я просто следую пути Java (if (record == null)), я получаю эту ошибку:

Умное приведение к «Запись» невозможно, потому что «запись» является изменяемым свойствомкоторые могли быть изменены к этому времени

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Ваш код Java не скомпилирован, поэтому я смоделировал пример.

    class Record {
        String name;
        String address;

        Record(String name, String address) {
            this.name = name;
            this.address = address;
        }

        String getName() {
            return name;
        }
    }

    class Person {

        private Record record;

        public String name() {
            return record().getName();
        }

        private Record record() {
            if (record == null) {
                refetch();
            }
            return record;
        }

        private void refetch() {
            record = new Record("Joe Smith", "101 Broadway, NYC, NY");
        }

    }

Kotlin вынуждает вас ОБЪЯВЛЯТЬ, если значение обнуляется с помощью '?'символ, когда вы определяете это.Так что это должно выглядеть так:

        internal class Record(var name: String, var address: String)

    internal class Person {

        private var record: Record? = null

        fun name(): String {
            return record()!!.name
        }

        private fun record(): Record? {
            if (record == null) {
                refetch()
            }
        return record
        }

        private fun refetch() {
            record = Record("Joe Smith", "101 Broadway, NYC, NY")
        }

    }
0 голосов
/ 24 ноября 2018

В идиоматическом Kotlin вы бы использовали Ленивое делегированное свойство :

class Person(private val service: Service) {

    private val record by lazy { service.doSomething() }

    fun name() = record.get("name");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...