如何将不可为空的类型传递给具有可为空参数的函数?
How to pass a non-nullable type to a function with a nullable parameter?
可以检查可为 null 的类型并将其转换为不可为 null 的类型,但反之则相当困难。
例如:
str1: String? = ""
// if str1 not null
str2: String = str1
str3: String? = str2 // This works!
在我的例子中,我谈论的是一个带有 Array 参数的函数,其中的内容可以为 null,但我想传递给该函数的 Array 的内容是不可为 null 的。那行不通:
var var1: Array<String?> = arrayOfNulls(10)
var var2: Array<String> = var1.filterNotNull().toTypedArray()
var var3: Array<String?> = var2 // This does not work!
我的问题是如何进行这项工作?
我可以将数组转换为可为 null 的数组,但我不确定这样做是否正确。
var str1: String? = ""
// if str1 not null
var str2: String = str1 ?: ""
var str3: String? = str2
Try This, Here ?: stands for checking if a value is null or not, if
not null its fine, but if it gets null you can set a default value in
it, that why i used a default value "" in it.
我能说的是,
//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 为 null 的情况下抛出错误,但这是不可能的,因为如您所说,它会通过 null 检查。
解决方法看起来像这样。
- 这是一种可能的解决方案,即将 str2 定义为可空字符串
str1 : String? = ""
str2 : String? = str1
str3 : String? = str2
- 另一种解决方案是,在 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?>
,即使 String
是 String?
的子类。为此,您应该
- 使用协变的列表:
var var1: Array<String?> = arrayOfNulls(10)
var var2: List<String> = var1.filterNotNull()
var var3: List<String?> = var2 // Now works
- 将数组转换为可为 null 的数组,正如您所做的那样:
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]
因为 var3
和 var2
引用同一个对象,这会将 null
放入 Array<String>
中,然后将其作为不可空的 String
.这显然破坏了空安全。
如果您确定您的代码永远无法做到这一点,最好只“将数组转换为可为 null 的数组,就像您正在做的那样”。
可以检查可为 null 的类型并将其转换为不可为 null 的类型,但反之则相当困难。
例如:
str1: String? = ""
// if str1 not null
str2: String = str1
str3: String? = str2 // This works!
在我的例子中,我谈论的是一个带有 Array 参数的函数,其中的内容可以为 null,但我想传递给该函数的 Array 的内容是不可为 null 的。那行不通:
var var1: Array<String?> = arrayOfNulls(10)
var var2: Array<String> = var1.filterNotNull().toTypedArray()
var var3: Array<String?> = var2 // This does not work!
我的问题是如何进行这项工作?
我可以将数组转换为可为 null 的数组,但我不确定这样做是否正确。
var str1: String? = ""
// if str1 not null
var str2: String = str1 ?: ""
var str3: String? = str2
Try This, Here ?: stands for checking if a value is null or not, if not null its fine, but if it gets null you can set a default value in it, that why i used a default value "" in it.
我能说的是,
//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 为 null 的情况下抛出错误,但这是不可能的,因为如您所说,它会通过 null 检查。
解决方法看起来像这样。
- 这是一种可能的解决方案,即将 str2 定义为可空字符串
str1 : String? = ""
str2 : String? = str1
str3 : String? = str2
- 另一种解决方案是,在 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?>
,即使 String
是 String?
的子类。为此,您应该
- 使用协变的列表:
var var1: Array<String?> = arrayOfNulls(10)
var var2: List<String> = var1.filterNotNull()
var var3: List<String?> = var2 // Now works
- 将数组转换为可为 null 的数组,正如您所做的那样:
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]
因为 var3
和 var2
引用同一个对象,这会将 null
放入 Array<String>
中,然后将其作为不可空的 String
.这显然破坏了空安全。
如果您确定您的代码永远无法做到这一点,最好只“将数组转换为可为 null 的数组,就像您正在做的那样”。