简体   繁体   English

使用 generics 的类型不匹配

[英]Type mismatch using generics

I have issues understanding generics and i failed to find the answer here.我在理解 generics 时遇到问题,但在这里找不到答案。

Here is the issue:这是问题:

I have an abstract class that is suppose to be the parent class to few viewmodels.我有一个抽象的 class 假设是少数视图模型的父 class。 Idea is, one view is going to be created based on data coming from different viewmodels.想法是,将根据来自不同视图模型的数据创建一个视图。 And i want to draw it based on the same method, just using different Types.我想基于相同的方法绘制它,只是使用不同的类型。

Also, I dont want a return type, i want to trigger some callbacks.另外,我不想要返回类型,我想触发一些回调。

Here is the abstract:这是摘要:

package foo.bar.ui.app.user_profile.view_model


abstract class UserDefaultsGenericViewModel : BaseViewModel() {
    abstract fun <P> getData(
        data: (P) -> Unit,
        error: (Result.Error) -> Unit
    )
} 

And then example of one ViewModel is like this:然后一个 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")
            }
        }
    }
}

The problem is in this line: data.invoke(resultStops.value)问题出在这一行: data.invoke(resultStops.value)

Im getting:我越来越:

Type mismatch: inferred type is foo.bar.onboarding.Stops but Stops#1 (type parameter of foo.bar.ui.app.user_profile.view_model.StopViewModel.getData) was expected类型不匹配:推断类型为 foo.bar.onboarding.Stops 但 Stops#1(foo.bar.ui.app.user_profile.view_model.StopViewModel.getData 的类型参数)是预期的

What am i doing wrong?我究竟做错了什么?

You're using a generic method, but it looks like you want a generic class/interface.您正在使用通用方法,但看起来您想要一个通用类/接口。

In your override fun <Stops> getData , Stops is an arbitrary name of a type parameter, not the actual Stops type that you seem to want.在您的override fun <Stops> getData中, Stops是类型参数的任意名称,而不是您似乎想要的实际Stops类型。 What you probably want instead is the following:您可能想要的是以下内容:

// 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

    ...
}

Here the <P> is on the class declaration, so that <P> is determined once for each instance of the class.这里的<P>在 class 声明上,因此对于 class 的每个实例都确定一次<P> If you declare the generic on the method, the actual type can be different for each method invocation.如果在方法上声明泛型,则每个方法调用的实际类型可能不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM