Kotlin - 可空字段的非空 getter

Posted

技术标签:

【中文标题】Kotlin - 可空字段的非空 getter【英文标题】:Kotlin - nonnull getter for a nullable field 【发布时间】:2017-04-04 15:38:17 【问题描述】:

我是 Kotlin 的新手,我尝试将一个小型 Java 项目重新设计为这种新语言。我在我的项目中使用了 mongodb,并且我有一个类,例如:

class PlayerEntity 

  constructor()  //for mongodb to create an instance

  constructor(id: ObjectId, name: String)  //used in code
    this.id = id
    this.name = name
  

  @org.mongodb.morphia.annotations.Id
  var id: ObjectId? = null

  var name: String? = null

由于构造函数为空,我必须将 id 字段标记为可为空 (var id: ObjectId?)。当我尝试从另一个类访问此字段时,我必须使用非空检查:thePlayer.id!!。但我的应用程序的逻辑是 id 字段永远不会为空(mongo 创建 Player 的实例并立即设置 id 字段)。而且我不想到处做非空检查。

我试图创建一个非空的 getter,但它没有编译:

var id: ObjectId? = null
    get(): ObjectId = id!!

我也可以为 id 创建一些存根并在构造函数中使用它,但这看起来像一个肮脏的黑客:

val DUMMY_ID = new ObjectId("000000000000000000000000");

那么有没有办法解决这个问题?

【问题讨论】:

lateinit放在你的变量之前,这基本上意味着,不要打扰如何,但我确保它会被初始化 this similar problem in hibernate and solution 有帮助吗? 【参考方案1】:

我个人在类似情况下使用前缀为_ + public val 的私有var。

class Example<out T> 
  private var _id: T? = null
  val id: T
    get() = _id!!

对于您的情况,它看起来像这样:

@org.mongodb.morphia.annotations.Id
private var _id: ObjectId? = null
val id: ObjectId
  get() = _id!!

或者,像这样将您的变量声明为lateinit(但请注意,这会公开公开设置器):

@org.mongodb.morphia.annotations.Id
lateinit var id: ObjectId

【讨论】:

lateinit 在这种情况下是正确的做法;无需为第二个属性而烦恼。 谢谢,lateinit 正是我所需要的 @yole 每个人都是他自己,出于某种原因,我个人不喜欢lateinit “我个人在类似情况下使用前缀为 _ + public val 的私有 var”。这和带有私有 setter 的公共 var 有什么区别?有吗? getter/setter 不能覆盖其父 var/val 的类型,因此任何使用 getter 的人仍然必须非空断言 (!!) 返回值。

以上是关于Kotlin - 可空字段的非空 getter的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 中的非空值产生空指针异常

如何通过 GraphQL 查询包含非空字段的可空数据?

Kotlin空安全总结 ( 变量可空性 | 手动空安全管理 | 空安全调用操作符 | 非空断言操作符 | 空合并操作符 | 空指针异常处理 | 先决条件函数判空 )

非空日期如何在视图中变为可空

MySQL中建表时可空(NULL)和非空(NOT NULL)的一些思考

Spring Mongo 仅通过新 POJO 的非空字段进行更新