【问题标题】:Does as? in a if statement insure that the instance inside the block isn't null inside all the if block?作为吗?在 if 语句中确保块内的实例在所有 if 块内都不为空?
【发布时间】:2021-03-09 14:35:01
【问题描述】:

我知道如果我将 as? 分配给一个变量,那么编译器就不会担心安全转换问题。 例如:

w:Wolf? = Wolf()
wolf = w as? Wolf

现在我可以使用变量 wolf 来调用 Wolf 的任何公共成员,而无需使用问号(无需安全调用)

但是如果as?位于 if 块内,并且 item 变量未分配。例如:

  if (item as? CountryDataItem != null)
    {
           // code that is using *item*
    }

    else{
   } 

if 块 中的代码是否可以将 item 用作 CountryDataItem 而无需强制转换,并且编译器在使用 CountryDataItem 时不会注释安全调用 问题是因为该项目没有保存在任何变量中,所以我不确定编译器如何考虑他?

【问题讨论】:

    标签: android kotlin casting


    【解决方案1】:

    答案是肯定的。编译器知道如果item 为空,那么控件将永远不会进入if 块,因此item 被智能转换为CountryDataItem

    但是,您正在做的事情是不必要的。您应该改用is。像这样:

    if (item is CountryDataItem) {
        // code that is using *item*
    }
    

    仅当字段itemval 时,上述情况才成立。如果itemvar,则编译器不会将其智能转换为CountryDataItem,因为它可能会在其他地方更新。在这种情况下,您将需要使用局部变量。像这样:

    val myItem = item 
    if (myItem is CountryDataItem) {
        // code that is using *myItem*
    } else {
       ...
    }
    

    val myItem = item as? CountryDataItem
    if (myItem != null) {
        // code that is using *myItem*
    } else {
        ...
    }
    

    【讨论】:

    • 我理解有时会阻止我们按照您编写的方式进行操作,它会说他不能保证在 if 检查和之间将项目设置为 null 的不同位置if 的块
    • 哦,所以您的字段itemvar,可能会在您的应用程序的其他部分中更新。我已经更新了我的答案
    • 我写代码的方式不好吗?我是否必须将引用保存在局部变量中才能“享受”智能转换并确保变量不等于 null?
    • 虽然我没有将 item 的结果赋值为? CountryDataItem 会被转换成 CountryDataItem if block body?
    【解决方案2】:

    我可能是错的,但我认为 as 的行为?有点不一样

    当您执行wolf = w as? Wolf 时,wolf 仍然是可空的Wolf?,所以您仍然需要wolf?.method()

    wolf = w as Wolf 将使 wolf 成为不可为空的 Wolf,但如果 w 为空,代码将抛出异常

    这是我从文档中发现的

    https://kotlinlang.org/docs/reference/typecasts.html#safe-nullable-cast-operator

    【讨论】:

    • 但是在我的代码中,在块体之前我检查了 item 是什么? CountryDataItem 反对null,在使用他之前
    • Luiz 表示您的 wolf 示例 - w as? Wolf 评估为 either 非空 Wolf 类型 null,因此结果type 是可空的 Wolf?(因为它可能是 Wolf 或 null)。因此,您仍然必须使用 ? 对其进行空检查
    猜你喜欢
    • 1970-01-01
    • 2015-04-15
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多