【问题标题】:Idiomatic Kotlin when checking null检查 null 时的惯用 Kotlin
【发布时间】:2019-04-26 20:16:00
【问题描述】:

在 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)),我会得到这个错误:

智能转换为“记录”是不可能的,因为“记录”是可变的 此时可能已更改的属性

【问题讨论】:

标签: java kotlin idioms


【解决方案1】:

在惯用的 Kotlin 中,您可以使用 lazy delegated property:

class Person(private val service: Service) {

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

    fun name() = record.get("name");
}

【讨论】:

  • 谢谢。如何强制重新初始化?即再次调用`service.doSomething()。这可能吗?
  • AFAIK,在 stdlib 中没有可用的方法。你需要自己实现一个 ResettableLazy 。快速谷歌搜索导致:stackoverflow.com/questions/35752575/…
  • 非常感谢。我会这样做的。
【解决方案2】:

你的 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 会强制你通过使用“?”来声明。 char 当你定义它。所以它需要看起来像这样:

        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")
        }

    }

【讨论】:

    猜你喜欢
    • 2017-07-03
    • 2018-02-08
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 2015-06-05
    • 2011-12-15
    • 2016-03-28
    • 1970-01-01
    相关资源
    最近更新 更多