如何编写返回指定类型的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
相关产品推荐
相关产品推荐

