类型不匹配必需:结果<列表<数据项>>!发现:成功

问题描述

如果我得到正确的响应,我已经实现了密封类,如果错误 Resuilt.Error,我将得到 Result.Success

在我实现该逻辑的 viewmodel 下方

type Linestring struct {
    coordinates string `xml:"coordinates"`
}    

func plotLocation(c chan data.GpsPos) {
    /*
        continuously read from the channel
        use the location data to plot a breadcrumb trail
    */

    defer wg.Done()

    for currentCoords := range c {

        file,err := os.Open("/Users/me/foo.kml")
        if err != nil {
            log.Fatal(err)
        }
        defer file.Close()

        var buf bytes.Buffer
        decoder := xml.NewDecoder(file)
        encoder := xml.NewEncoder(&buf)

        for {
            token,err := decoder.Token()
            if err == io.EOF {
                break
            }
            if err != nil {
                log.Printf("error getting token: %v\n",err)
                break
            }
            switch v := token.(type) {
            case xml.StartElement:
                if v.Name.Local == "Linestring" {

                    var coords Linestring
                    if err = decoder.DecodeElement(&coords,&v); err != nil {
                        log.Fatal(err)
                    }
                    coords.coordinates += fmt.Sprintf("%f,%f,%d\n",currentCoords.Lat,currentCoords.Long,0)
                    if err = encoder.EncodeElement(coords,v); err != nil {
                        log.Fatal(err)
                    }
                    continue
                }
            }
            if err := encoder.Encodetoken(xml.copyToken(token)); err != nil {
                log.Fatal(err)
            }
        }
    }
}

低于我的密封类结果

@Hiltviewmodel
class GiphyTaskviewmodel
@Inject
constructor(private val giphyTaskRepository: GiphyTaskRepository):viewmodel()
{
    var giphyresponse=mutablelivedata<Result<List<DataItem>>>()


    fun getGifsFromText(apikey:String,text:String,limit:Int)= viewmodelScope.launch {
    giphyTaskRepository.getGifsFromText(apikey,text,limit).let { response->
        if(response?.isSuccessful){
            var list=response.body()?.data
            giphyresponse.postValue(Success(list))
        }else{
            giphyresponse.postValue(Error(Exception(response.message())))

        }

    }
}

}

但是当我运行项目时出现以下错误

类型不匹配。必需:结果!发现:成功

解决方法

您的 Success 扩展了 Result<Any?>,因此它不是 Result<List> 的子类型。您需要对其进行参数化:

data class Success<T>(val data: T) : Result<T>()

另外,Kotlin stdlib 中已经有一个类似的工具,它比你自己的优化得更好。它被命名为... 结果 ;-) https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/

更新

我最初没有注意到的另一个问题是,您将类命名为 Error,而 Java/Kotlin 中已经存在 Error 类,因此它可能会导致问题。最简单的方法是重命名。

请注意,为您提供一个完整的示例并非易事,但请尝试以下操作:

giphyTaskRepository.getGifsFromText(apikey,text,limit).let { response->
    if(response?.isSuccessful){
        var list=response.body()?.data ?: error("Don't know what to do here")
        giphyresponse.postValue(Success(list as List<DataItem>))
    }else{
        giphyresponse.postValue(Err(Exception(response.message())))
    }
}

sealed class Result<out T>
data class Success<T>(val data: T) : Result<T>()
data class Err(val exception: Exception) : Result<Nothing>()

正如我所说,当 body() 为 null 时,我不知道您的预期行为是什么,所以我只是抛出了一个错误。

另外,我不知道 body().data 的类型是什么,但我认为它只是 Any,所以我将它转换了。可能没有必要。

,

类型不匹配。要求:结果!发现:成功

这正是你的问题。您已声明 LiveData 发出 Result<List<DataItem>>SuccessResult<Any?>。它不符合您为 giphyresponse 设置的约束。

要发布 Success,它应该是 Result<T>Result<List<DataItem>>>,具体取决于您的层次结构。

要发布 Error,它也必须属于 Result<List<DataItem>>>,并且必须创建一个空列表 - 因为该列表是强制性的。另一种方法是将 giphyresponse 定义为 MutableLiveData<Result<List<DataItem>?>>(),这样 Error 可以携带 null 数据而不是虚拟列表。