我正在將一個非常古老的大型 Java 服務器轉換為 Kotlin,并且我正在嘗試在轉換程序中進行盡可能少的邏輯更改。我正在尋找一種方法來翻譯這段 Java 代碼而不從根本上改變它。
考慮以下玩具代碼:
interface Pet
class Dog : Pet
class Cat : Pet
class PetSitter<T : Pet> {
fun walk(pet: T) {}
}
fun main() {
val sitters: Array<PetSitter<*>> =
arrayOf(PetSitter<Cat>(), PetSitter<Dog>())
sitters[0].walk(Cat()) // Type mismatch.
// Required: Nothing
// Found: Cat
}
這無法與訊息一起編譯Type mismatch: inferred type is Cat but Nothing was expected。
在 Java 中,以下作業正常:
PetSitter[] sitters = ... // Note: PetSitter's generic is omitted
sitters[0].walk(new Cat());
是否可以Array<PetSitter>在 Kotlin 中類似地定義一個(沒有寵物泛型)?或者其他一些方法來使引數型別為PetSitter<*>.walk是Pet而不是Nothing?
uj5u.com熱心網友回復:
在 Java 中,這稱為原始型別。它僅出于向后兼容性的需要而得到支持,并且不鼓勵使用它,因為它違背了使用泛型的目的。出于同樣的原因,Kotlin 完全禁止它,因為它沒有它必須支持的語言的預泛型版本。
使用原始型別的等價物是將型別轉換為寬松的。這個要求是為了迫使你考慮演員陣容是否合適。
(sitters[0] as PetSitter<Cat>).walk(Cat())
uj5u.com熱心網友回復:
更新:參見https://stackoverflow.com/a/70114733/2875073,它更簡單。
Kotlin 似乎不允許原始型別,但看起來解決方法是將我的 Pet 實體強制轉換為Pet,然后創建一個when列舉每個子型別并sitters[0]為每個案例進行強制轉換的案例:
val myPet: Pet = Cat()
when (myPet) {
is Dog -> (sitters[0] as PetSitter<Dog>).walk(myPet)
is Cat -> (sitters[0] as PetSitter<Cat>).walk(myPet)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/366530.html
上一篇:Rust-閉包和泛型型別
