习惯用法 Kotlin 在检查 null 值时

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

智能转换为“Record”是不可能的,因为“record”是一个可变属性,可能在此时被更改


1
为什么你在一个空安全类型上使用空检查? - Zoe stands with Ukraine
可能是https://dev59.com/bVcP5IYBdhLWcg3wTYUn的重复问题。 - Zoe stands with Ukraine
1
@Zoe 抱歉,我错过了 ?。是打字错误。 - Héctor
在 Kotlin 中,您将使用一个延迟初始化的委托属性:https://kotlinlang.org/docs/reference/delegated-properties.html#lazy - JB Nizet
2个回答

4

在Kotlin中,你可以使用一种惯用的方式来定义一个延迟属性:

class Person(private val service: Service) {

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

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

谢谢。如何强制重新初始化?即再次调用service.doSomething()。这可能吗? - Héctor
1
据我所知,在stdlib中没有可用的方法来实现这个。你需要自己实现一个ResettableLazy。快速的谷歌搜索可以找到这个:https://dev59.com/H1sV5IYBdhLWcg3w0hpU - JB Nizet
非常感谢。我会去做的。 - Héctor

1

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

    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接