Qual è la differenza tra T e T? a Kotlin?
Qual è la differenza tra:
fun <T, R> List<T>.map1(transform: (T) -> R): List<R> {
return this.map(transform)
}
e
fun <T, R> List<T>.map2(transform: (T?) -> R): List<R> {
return this.map(transform)
}
e
fun <T, R> List<T?>.map3(transform: (T?) -> R): List<R> {
return this.map(transform)
}
Nel mio test, nullè accettato per tutte e 3 le funzioni di trasformazione sopra , quindi: c'è qualche differenza tra Te T??
Risposte
Nei tuoi esempi, Te T?sono equivalenti, ma ci sono altri casi in cui ?fa la differenza.
Quando dichiari un parametro di tipo <T>, non ha alcuna restrizione su di esso. È come scrivere <T: Any?>e significa Tche consentirà qualsiasi sottotipo di Any?. L'aggiunta di un ?a esso lo renderebbe annullabile, ma Any?è già annullabile, quindi ?non cambia nulla. Ciò significa che l'insieme di tipi consentito da un tipo illimitatoT è lo stesso dell'insieme di tipi consentito da T?.
Non appena metti delle restrizioni su ciò che Tpuò essere, le cose cambiano, però. Ad esempio, nella funzione seguente, dichiariamo un parametro di tipo <T: Any>, limitandolo in modo che non sia più annullabile.
fun <T: Any> myFunction(item: T) // item can't be null
Ciò significa che non posso passare nulla myFunction. Posso chiamare la funzione solo con un nullargomento se cambio il tipo di parametro in essere T?.
fun <T: Any> myFunction(item: T?) // item can be null
Nota che ?annota solo un parametro di tipo esistente. Dichiarare un parametro di tipo con a ?non significa nulla e non viene compilato. Ad esempio, fun <T?> myFunction(item: T)non è un codice Kotlin valido.