我在理解泛型時遇到了問題,我沒能在這里找到答案。
這是問題:
我有一個抽象類,它應該是少數視圖模型的父類。想法是,將根據來自不同視圖模型的資料創建一個視圖。我想基于相同的方法繪制它,只是使用不同的型別。
另外,我不想要回傳型別,我想觸發一些回呼。
這是摘要:
package foo.bar.ui.app.user_profile.view_model
abstract class UserDefaultsGenericViewModel : BaseViewModel() {
abstract fun <P> getData(
data: (P) -> Unit,
error: (Result.Error) -> Unit
)
}
然后一個 ViewModel 的例子是這樣的:
package foo.bar.ui.app.user_profile.view_model
@HiltViewModel
class StopViewModel @Inject constructor(
private val getStopsByRouteUseCase: ParamsUseCase<RouteParams, Stops>
) : UserDefaultsGenericViewModel() {
var stopId = ""
override fun <Stops> getData(data: (Stops) -> Unit, error: (Result.Error) -> Unit) {
viewModelScope.launch {
when (val resultStops = getStopsByRouteUseCase.invoke(RouteParams(stopId, Direction.ToWork))) {
is Result.Success -> {
data.invoke(resultStops.value)
}
is Result.Error -> Log.e("TAG", "bar")
}
}
}
}
問題出在這一行: data.invoke(resultStops.value)
我越來越:
型別不匹配:推斷型別是 foo.bar.onboarding.Stops 但 Stops#1(foo.bar.ui.app.user_profile.view_model.StopViewModel.getData 的型別引數)是預期的
我究竟做錯了什么?
uj5u.com熱心網友回復:
您正在使用泛型方法,但看起來您需要泛型類/介面。
在您的override fun <Stops> getData,Stops是型別引數的任意名稱,而不是Stops您似乎想要的實際型別。您可能想要的是以下內容:
// note the <P> at the class level
abstract class UserDefaultsGenericViewModel<P> : BaseViewModel() {
// no <P> here after the fun keyword
abstract fun getData(
data: (P) -> Unit,
error: (Result.Error) -> Unit
)
}
@HiltViewModel
class StopViewModel @Inject constructor(
private val getStopsByRouteUseCase: ParamsUseCase<RouteParams, Stops>
) : UserDefaultsGenericViewModel<Stops>() { // note the <Stops> type argument here
...
}
這里<P>是在類宣告上,因此<P>為類的每個實體確定一次。如果在方法上宣告泛型,則每個方法呼叫的實際型別可能不同。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/396644.html
上一篇:使用泛型進行介面向下轉換
