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

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 检查。

解决方法看起来像这样。

  1. 这是一种可能的解决方案,即将 str2 定义为可空字符串
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. 将数组转换为可为 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]

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

如果您确定您的代码永远无法做到这一点,最好只“将数组转换为可为 null 的数组,就像您正在做的那样”。