无效安全的好处



我是Kotlin的新手,我已经读到这似乎是方向盘之后的最佳发明。无论如何,这让我感到可疑,当然是因为我不了解概念所暗示的一切。

在我们拥有NullPointerException之前,要恢复我所理解的内容,因此对代码中的某些问题和问题出现在哪里,而不是设置零的位置。无论如何,很明显,我们可以在这里等待,直到零指针又回来,期望从回溯中了解发生了什么。每个人都已经做到了,这从来都无法找到。

现在,使用Null指针安全性,我们不再发生这种崩溃,只是某个部分在我们的应用程序中无法执行的代码(我们假设所使用的参考文献不应该像以前那样为null,当然(,导致可能比以前的NullPointerException更复杂地理解奇怪的行为,或者可能只是某个月没有执行的某些任务。

这是null指针安全性的好处吗?

我会假设您来自Java,您已经在其他地方查看过一些说明不完全了解它们。因此,我不会尝试给您一个全面的解释(您可以在其他地方找到(,但是我会尝试清楚地说明Null指针安全的核心思想。

,如果您理解它们,则有两个要点应该足够清楚。首先,有一种想法是有两种单独的类型来表示您将在Java中建模为单一类型:无效的类型,而不是可确定的类型。为了给您一个示例,在Java中,您将字符串放在String对象中,而无需关心字符串是否为null,在Kotlin中,您有两种类型:String?String。第一个接受零值(如Java等效(,但第二个不接受。因此,您可以使用?(例如String?Int?(的类型中的零值,但是对您可以做的事情有很多限制:基本上,您仅限于用null做的事情,因为,毕竟,毕竟,该变量可以保持零值。因此,没有呼叫方法。因此,虽然在Java中,您可以在其上调用一种方法,并且有时使用NullPointerException,在Kotlin中,您无法调用任何方法。这并不是因为Kotlin的某种沉默行为,而是要简单得多:编译器不会让您。尝试,您会发现该程序没有编译。如果变量是类型String而不是String?,则Kotlin可以从中调用方法。

因此,基本上没有零指针例外,因为您永远无法在对象变量上调用一个可以为null的方法。

但是,有时变量不是null:那么,在变量不是null的情况下,您如何在变量上调用该方法?同样,答案很简单:您必须检查它。我的意思是,您必须使用if指令(明确或隐式(,该指令将检查变量是否为null。类似于" if (myVariable != null) {call method on variable}"。因此,如您所见,Kotlin编译器足够聪明,可以看到您使用的是if指令,该指令保证该变量不是无效的,因此它将让您在{}之间的块中调用变量上的方法。换句话说,如果您的变量是类型String?,但是您在if块中,您检查了变量不是null,Kotlin将其视为String类型的变量,而不是String?

当您谈论

某些部分默默执行的代码

我猜您正在考虑一些在其中内部具有隐式if的操作员,例如?.操作员。如果您写

myVariable?.call()

这意味着大致

if (myVariable != null) { myVariable.call()}

因此,确实,如果变量为null,它将默默"失败"。但这与Java没有什么不同,如果您使用相同的if。换句话说,如果变量为null,则什么都不会发生可能导致NullPointerException 不编译。当您获得"默默地执行的代码的一部分"时,唯一的情况是,当您使用安全的呼叫来处理潜在的无效错误时。这不是处理此类错误的唯一,也不是最有用的方法。

给您一个简短的答案,您的理解是完全正确的。Kotlin不能解决NPE问题。它只是主动迫使您做出明确的决定以防止它。

无效安全如何保护您免受问题

在大多数语言中,都可以

val example: String = null

然后您将这样做:

print(example.toUpperCase());

您可以看到错误可能是在代码的第一个位中,但是错误发生在第二位,这令人困惑。

使用无效的安全性,当您定义一个变量时,您会说是否为无效,并在损坏时获得汇编(而不是运行时(错误。

如何在kotlin中获得nullpoInterException

仍然有可能获得无效指针,但是主要方式就是这样:

  • 创建一个无效的类型

    var r:String
    
  • 具有null

    的值
    r = null
    
  • 断言该值不是null

    r!!
    

这就是为什么您要避免!!,除非您确定该值不会为null。

使用无效类型

当您不希望以多种方式null时,您可以处理无效的类型:

  • 使用默认值

    val set = nullable ?: "It was null, sorry"
    
  • 如果值为null

    val set = nullable ?: throw AssertionError(":(")
    
  • 传播nulls

    val set = nullable?.doThing()?.doThing2()?.property
    

    集将是最终值,如果其中任何一个都退回了null

  • ,则为null。
  • 仅在nulls上操作

    nullable?.let {
         print(it.property)
    }
    

您不需要由于空对象而不需要执行某些代码。

零指针安全系统的好处是,如果您可能面对Null Pointer,您可以事先知道并采取相应的行动。您可以确定某些事情是否可能为无效,并且做一些不同的事情。

例如:

var nullableServiceVariable: NullableService? = null   //Let's say that you initialize this somewhere
var serviceAnswer = nullableServiceVariable?.answer ?: "Answer for null!"

编译器可让您处理null的可能性,因此您不会得到意外的NullPoInterException,可以停止所有应用程序。如果无效的确实是无效的,我将提供一个替代分支,以便我的系统仍然有效。


如果愿意,可以扔一个NullPointerException,但是最好使用不可用的变量:

var serviceAnswer = nullableServiceVariable!!.answer

!!如果变量为null。

相关内容

  • 没有找到相关文章