繁体   English   中英

如何将不可为空的类型传递给具有可为空参数的函数?

[英]How to pass a non-nullable type to a function with a nullable parameter?

可以检查可为空类型并将其强制转换为不可为空类型,但反过来则非常困难。

例如:

str1: String? = ""
// if str1 not null
str2: String = str1

str3: String? = str2 // This works!

在我的例子中,我谈论的是一个带有 Array 参数的函数,其中的内容可以为空,但我想传递给函数的 Array 的内容是不可为空的。 这不起作用:

var var1: Array<String?> = arrayOfNulls(10)

var var2: Array<String> = var1.filterNotNull().toTypedArray()

var var3: Array<String?> = var2 // This does not work!

我的问题是如何使这项工作?

我能够将数组转换为可为空的数组,但我不确定这是否是正确的方法。

var str1: String? = ""

// if str1 not null
var str2: String = str1 ?: ""

var str3: String? = str2  

Try This, Here ?: 代表检查一个值是否为空,如果不是空则很好,但如果它为空,您可以在其中设置默认值,这就是为什么我在其中使用默认值“”的原因。

我能说的是

//This value can hold null values 
str1: String? = ""

// if str1 not null, store values in str2
// so, now str2 holds NOT NULL VALUES
str2: String = str1

// Now by default since str2 is NOT NULL
// All the values being passed inside str2 will always be NOT NULL
// 
str3: String? = str2 // This does not work

str3 只会在 str2 为空的情况下引发错误,但这是不可能的,因为正如您所说,它会通过空检查。

解决方法看起来像这样。

  1. 这是一种可能的解决方案,即将 str2 定义为 Nullable 字符串
str1 : String? = ""

str2 : String? = str1

str3 : String? = str2
  1. 另一种解决方案是,将空检查放在 str2 上,因为 str2 不是空 str3 默认情况下不会为空。
str1 : String? = ""

str2 : String = str1 ?: ""

str3 : String = str2

更新

根据更新的问题,

// A list of nulls
var var1: List<String?> = listOf(null, null, null, null, null, null, null, null, null, null)

//Mutable List to hold not null values or filter out null values
var var2: MutableList<String> = mutableListOf()
for (i in var1) var2.add(i ?: "")

//var3 will always be not null
var var3: List<String?> = var2

在 Kotlin 中,数组是不变的,这意味着给定类型的数组不能分配给其父类型的数组。 这就是为什么您不能将Array<String>分配给Array<String?> ,即使StringString? . 为此,您应该

  1. 使用协变列表:
var var1: Array<String?> = arrayOfNulls(10)
var var2: List<String> = var1.filterNotNull()
var var3: List<String?> = var2  // Now works
  1. 将数组转换为可以为空的数组,就像你在做的那样:
var var1: Array<String?> = arrayOfNulls(10)
var var2: Array<String> = var1.filterNotNull().toTypedArray()
var var3: Array<String?> = var2 as Array<String?>  // Now works

目前似乎没有答案实际上可以解释为什么数组是不变的(因此Array<String>不是Array<String?>的子类型)。 如果

var var2: Array<String> = var1.filterNotNull().toTypedArray()

var var3: Array<String?> = var2 // This does not work!

工作,然后你可以做

var3[0] = null
val x: String = var2[0]

因为var3var2引用同一个对象,所以这会将null放入Array<String> ,然后将其作为不可为 null 的String检索。 这显然破坏了空安全。

如果您确定您的代码永远不会这样做,最好只“将数组转换为可空数组,就像您正在做的那样”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM