关键字lateinit是不必要的?

我正在学习Kotlin的过程中,阅读关于lateinit关键字使我怀疑它的用处。 考虑这个代码:

 var testString: String? = null lateinit var lateTestString: String fun print() { print(testString?.length) print(lateTestString.length) } 

这里得到字符串长度的唯一区别是通过使用?.来检查它是否为null ?. 运营商。 在访问属性或调用方法时,是否使用lateinit快捷方式不必添加额外的问号? 就这一点而言,我认为在访问lateinit一个问题时,不得不添加额外的问号而不是获得一个exception。

更多的研究表明,对于那些variables尚未初始化的注入和/或unit testing来说, lateinit是很好的选择,但是它是可以的。 然而,这不值得有这个额外的东西?. 而不是仅仅. 不冒险例外?

lateinit关键字存在,以启用一个特定的情况:当你的领域不能为空,但你也不能初始化它的构造函数或一个常量值。 在你使用它之前确保你初始化了这个值。 如果你不这样做,你会得到一个明确的特殊例外。

晚期使用与“正常”可空领域之间的区别?. 是后者传达了关于代码的错误信息:“这个东西有时可能是空的”。 事实上,它不能。 它只是比平时晚(比如dependency injection而不是构造函数)初始化。

正在使用lateinit快捷方式不必添加额外的问号

其实它更接近于一个捷径!! 。 我在代码中使用了很多,出于我将要描述的原因。

那两个!! 被有意识地选择来吸引注意力的地方在代码中,你可以对“types系统下注”,可以这么说。 当在适当的地方使用,这正是你想要的,但是那些实际上是非空的项目中的所有这些variables呢,只是types系统太弱而无法certificate它呢? 我讨厌看到扩散!! 所有我的代码库,当我可以很容易地确定他们被初始化。 这种噪音会削弱强信号!! 发送。

当你在代码中看到一个lateinit var ,你只需要查看周围环境指定的任何初始化方法,就能说服自己一切正常。 很容易检查它是否正确使用,我从来没有看到它的一个bug。

Kotlin的设计师们把真实的开发者的关注放在严格的forms主义之上,实际上是非常令人高兴的。

我不是来自Jetbrains团队,所以也许我在这里没有一个清晰的图片,但我同意你在lateinit看起来不是一个好的构想。

lateinit被添加时,最初的想法是,我们有一些框架(提示:Android)偶尔的框架的用户没有访问类的构造函数(提示:Android的活动类),他不能初始化一些属性构造函数或init块。 但是,由于这些类有某种生命周期的事实,我们可以肯定foo属性会在第一次被使用之前被初始化,因为例如初始化发生在onCreate() ,而属性在稍后发生的onResume()使用。

(过去的某个地方,懒惰的程序员J – Jetbrains):

L:嘿,Jetbrains! 我们很懒,如果我们确定属性会被初始化,我们不需要额外的问号。 我们能不能标出来克服柯林的无效安全?

J:是的,当然! 让我们在lateinit修饰符中lateinit

好主意?

没有。

因为在更高版本的语言中,创建者决定为lateinit属性添加新的语法。 我可能是错的(没有太多的关注),但它看起来像foo::isInitialized 。 原因是这个修饰符被滥用(或者从一开始就有缺陷),所以我们需要附加一些检查。

所以,基本上,我们正在交易问号以及全无效安全的机会,以执行foo::isInitialized检查以防止出现UninitializedPropertyAccessException (或其他)。

迟到意味着稍后初始化
在这个代码中你会得到错误。 调用之前,您必须初始化lateTestString。

 var testString: String? = null lateinit var lateTestString: String fun print() { print(testString?.length) print(lateTestString.length) }