【问题标题】:Type mismatch using generics使用泛型的类型不匹配
【发布时间】:2021-12-27 16:24:47
【问题描述】:

我在理解泛型时遇到问题,但在这里找不到答案。

问题来了:

我有一个抽象类,它被认为是少数视图模型的父类。想法是,将根据来自不同视图模型的数据创建一个视图。 我想用同样的方法画出来,只是使用不同的类型。

另外,我不想要返回类型,我想触发一些回调。

这是摘要:

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 的类型参数)是预期的

我做错了什么?

【问题讨论】:

    标签: kotlin generics


    【解决方案1】:

    您使用的是泛型方法,但看起来您想要一个泛型类/接口。

    在您的 override fun &lt;Stops&gt; 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
    
        ...
    }
    

    这里&lt;P&gt; 在类声明中,因此&lt;P&gt; 为类的每个实例确定一次。如果在方法上声明泛型,则每个方法调用的实际类型可能不同。

    【讨论】:

    • 这正是问题所在。我刚刚读到您可以将泛型类型指定为一个完整的单词,而不仅仅是字母,不知道我正在通过指定“覆盖乐趣 getData”来做到这一点。谢谢楼主,问题已经解决了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多