我只是想进一步了解Kotlin可为空的类型声明。
MutableList.remove
的类型声明为:
fun <T> MutableCollection<out T>.remove(element: T): Boolean
然而,即使myBook
的推断类型为Stuff?
并且其值为null
,也可以编译并运行以下代码。
data class Stuff(val name: String)
fun main(args: Array<String>) {
val myListOfStuff: ArrayList<Stuff> = arrayListOf(
Stuff("bed"),
Stuff("backpack"),
Stuff("lunch")
)
val myBook = myListOfStuff.find { it.name == "book" }
val found = myListOfStuff.remove(myBook)
println(myListOfStuff)
}
为什么remove
类型声明不使用可为空的T?
类型,诸如此类?
fun <T> MutableCollection<out T>.remove(element: T?): Boolean
或更准确地说,out
修饰符如何使T
可以为空?
答案 0 :(得分:3)
我想,您实际上并不是在调用您所引用的成员函数remove,而是以下扩展函数:
fun <T> MutableCollection<out T>.remove(element: T): Boolean
答案 1 :(得分:2)
中的T类型
fun <T> MutableCollection<out T>.remove(element: T): Boolean
推断为Stuff?
。您的行
val found = myListOfStuff.remove(myBook)
尝试删除所有出现的null
,因为myBook
为空。它显然找不到任何东西,但编译器并不介意。
out
关键字向编译器确保不会调用诸如add(element)
之类的函数(add(null)
是一个问题),仅返回诸如{{ 1}}。
请参阅以下内容进行澄清:
T
输出:
get()
对于data class Stuff(val name: String)
fun main(args: Array<String>) {
val myListOfStuff: ArrayList<Stuff?> = arrayListOf(
Stuff("bed"),
Stuff("backpack"),
Stuff("lunch"),
null
)
println(myListOfStuff)
val found = myListOfStuff.remove(null)
println(myListOfStuff)
}
关键字,请参见此处:https://kotlinlang.org/docs/reference/generics.html#declaration-site-variance