我有這樣的東西
fun validate(obj1: Any) {
// Here I am getting the KClass of the object
val objKClass = obj1::class
// Here I am casting the object using KClass
val obj1Cast = objKClass.safeCast(obj1)
// Then I want to iterate over its properties
for (prop in objKClass.memberProperties) {
//And get one BigDecimal? value
val bigDecimal: BigDecimal? = prop.get(obj1Cast) as BigDecimal?
}
}
這不起作用,我與prop.get(obj1Cast):
Type mismatch.
Required:
Nothing
Found:
Any?
是否有其他方法可以訪問 memberProperties 的值并將它們轉換為 BigDecimal?(例如)給定一個型別為 Any 的物件作為我的函式的輸入?
uj5u.com熱心網友回復:
使用泛型型別捕獲來解決這個問題。
在您當前的代碼prop中,型別為KProperty1<out Any, *>. 這是因為型別obj1是Any,所以型別objKClass是KClass<out Any>。out Any當它用作輸入引數時,沒有滿足該型別的值,因此會出現編譯錯誤。
第一步是捕獲的型別obj1。我們可以通過為它添加一個泛型型別引數來做到這一點,而不是使用Any. 我們稱之為捕獲的型別T。
fun <T: Any> validate(obj1: T) {
val objKClass: KClass<out T> = obj1::class
val obj1Cast = objKClass.safeCast(obj1) ?: return
for (prop in objKClass.memberProperties) {
val bigDecimal: BigDecimal? = prop.get(obj1Cast) as BigDecimal?
}
}
現在的型別prop是KProperty1<out T, *>。這讓我們更近了一步,但我們仍然有一個編譯錯誤。那是因為out T只能用于輸出值,但我們想將 a 傳遞給T方法引數。
幸運的是,它safeCast可以幫助我們,因為它會縮小值的型別,使其與類的型別完全匹配。我們只需要通過使用第二種方法來捕獲類的確切型別來給它一些幫助。我們稱其為較窄的確切型別T2。
// Here we capture the type of the object as T,
// and get its class as KClass<out T>
fun <T: Any> validate(obj1: T) {
validate(obj1, obj1::class)
}
// Here we narrow the type of the object from T to T2
fun <T: Any, T2: T> validate(obj1: T, type: KClass<T2>) {
val obj1Cast = type.safeCast(obj1) ?: return
for (prop in type.memberProperties) {
val bigDecimal: BigDecimal? = prop.get(obj1Cast) as BigDecimal?
}
}
現在它沒有編譯錯誤。有關其作業原理的更多資訊,您可以閱讀“泛型型別捕獲”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/512899.html
標籤:科特林仿制药内省
上一篇:如何在Flutter鉤子中使用List<int>的狀態?
下一篇:kotlin中使用的任何函式型別
