什么是使用Kotlin双爆为可空类成员

时间:2017-11-14 19:56:56

标签: kotlin nullable

在kotlin中,如果变量可以为空,那么kotlin将要求使用!!或使用前检查null。 在拥有可以为空的类成员的情况下,在该类内部任何地方裁判该成员kotlin将警告检查可以为空的。

class ClassWithNullableMemebr {
      Var nullableMember: OtherClass? = null;

      constructor (obj: OtherClass) {
          nullableMember = obj
      }
      fun foo() {
          nullableMember!!.doSomething()
      }
      fun getTheOtherClassMember : OtherClass {
          return nullableMember!!
      }
 }

如果保证nullableMember在构造函数中初始化,如何避免使用!!。

在Java或其他语言中,他们可以检查null一次并且如果按照设计,则成员应该永远不为null。然后在课堂内成员将被引用而不用担心。

有人建议做

if (nullableMember != null) {
    nullableMember!!.doSomething()
}

这仍然需要!!甚至在检查之后,它使代码看起来不漂亮。

这个案子真的用吗?与使用没什么不同!!因为nullableMember是在构造函数中赋值的,而函数返回它无法避免!!。

我认为如果在实例化类之后这个nullableMember保证不为null!不应该被认为是糟糕的编码风格。而且没有其他方法可以避免它。

有没有人建议避免使用' !!'在这样的情况下?

3 个答案:

答案 0 :(得分:2)

如果您确定该变量的值不为null,则应将其定义为不可为空。

在此之后,有两种方法可以避免编译器警告和即时变量初始化:

  1. lateinit 修饰符的使用
  2.   

    lateinit var nullableMember:OtherClass

    请注意,如果您在初始化之前尝试访问此变量,则会抛出异常

    1. 使用 notNull()委托
    2.   

      var nullableMember:Delegates.notNull()

      的OtherClass

      您可以找到here.

      这两者之间的差异

      如果需要在代码中的某处将此变量的值设置为null,我担心您将不得不使用 !! ,因为没有更好的方法来执行此操作

答案 1 :(得分:1)

  

如果保证nullableMember在构造函数

中初始化

在你的情况下,它不是。如果您调用辅助构造函数,它将被初始化,但您也有主要的无参数构造函数,将其初始化为null

如果 保证在构造函数中初始化为非null,那么正如Oliver的评论所说,它不应该是可空的!如果它仅在构造函数(包括辅助版)或val块中设置,则它应为init

即。这个类应该简化为

class ClassWithNullableMemebr(val nullableMember: OtherClass) {
    fun foo() {
        nullableMember.doSomething()
    }
}

答案 2 :(得分:1)

如果保证在构造函数上初始化,那么它根本不需要为空。

你可以:

class ClassWithMember(val member: OtherClass) {
  fun foo() {
      member.doSomething()
  }
}