You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写返回指定类型的Apollo查询通用函数?

问题描述

在test()函数中可见两个返回结果response1和response2,二者类型存在差异:response1直接调用apolloClient.query获取,response2通过自定义通用函数getCallFrom获取。需求是让通用函数返回与response1一致的类型(com.apollographql.apollo.api.Response<MyTestQuery.Data>),尝试替换通配符*未解决问题,请问问题出在哪里?

原始代码
fun getCallFrom(query: Query<*, *, *>): ApolloQueryCall<out Any?> = apolloClient.query(query)

fun test() {
    val response1: com.apollographql.apollo.api.Response<MyTestQuery.Data> = apolloClient.query(
        MyTestQuery("test")
    ).await()
    
    val response2: com.apollographql.apollo.api.Response<out Any?> = getCallFrom(
        MyTestQuery("test")
    ).await()
}
问题原因与解决方案

问题根源

你用Query<*, *, *>这种无界通配符定义参数,会让编译器丢失Query的具体类型信息——它无法推断出当前传入的MyTestQuery对应的Data子类是什么,只能把返回值的类型上限限定为Any?,最终导致response2的类型被弱化。

解决方案

给getCallFrom添加泛型参数绑定,明确关联Query的三个泛型类型(Data、Variables、Builder),让编译器能跟踪到具体的类型信息:

// 泛型参数绑定Query的三个类型参数,返回对应Data类型的ApolloQueryCall
fun <D : Operation.Data, V : Operation.Variables, B : Operation.Builder<D, V, B>> getCallFrom(query: Query<D, V, B>): ApolloQueryCall<D> = apolloClient.query(query)

修改后,test()函数中的response2就能和response1使用完全一致的类型:

fun test() {
    val response1: com.apollographql.apollo.api.Response<MyTestQuery.Data> = apolloClient.query(MyTestQuery("test")).await()
    
    // 现在类型完全匹配,无需再用out Any?
    val response2: com.apollographql.apollo.api.Response<MyTestQuery.Data> = getCallFrom(MyTestQuery("test")).await()
}

原理说明

Apollo的Query接口本身是带三个泛型参数的:

  • D:对应查询返回的Data实体类(比如MyTestQuery.Data)
  • V:查询的变量类型
  • B:查询的Builder类型

通过泛型参数绑定这些类型,编译器就能在调用getCallFrom时,自动推断出传入Query的具体D类型,最终让ApolloQueryCall返回对应D的类型,调用await()后自然得到Response<MyTestQuery.Data>。


内容的提问来源于stack exchange,提问作者Sirop4ik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 14:00:25