关于我的问题,有很多答案,但是我为他们尝试的解决方案并未完全解决问题。我不确定这是否与具有多个泛型或其他特性有关(也是Swift的较新版本,因此请全神贯注于语法)。
我在我的API请求代码中注意到了很多共性,所以我决定将主要工作抽象出来,并使其与任何可编码的请求/响应对象一起使用。这是我的主要请求方法:
private func sendRequest<T: Encodable, U: Decodable>(url: URL, requestModel: T) -> Promise<U>
我正在这样称呼它:
public func signIn(requestModel: SignInRequest) -> Promise<SignInResponse> {
let url = URL(string: authURL + "/signin")!
//getting compile error "Cannot explicitly specialize generic function" on this line
return sendRequest<SignInRequest, SignInResponse>(url: url, requestModel: requestModel)
}
我尝试直接分配给返回对象:
let x : Promise<SignInResponse> = sendRequest(...)
return x
帮助编译器解决(如其他解决方案中所述),但仍然存在相同的问题。有见识吗?
答案 0 :(得分:0)
我最终根据以下帖子使用了一种解决方案:https://stackoverflow.com/a/36232002/1088099
我显式传递了请求和响应对象类型作为参数:
private func sendRequest<T: Encodable, U: Decodable>(requestModelType: T.Type, responseModelType: U.Type, url: URL, requestModel: T) -> Promise<U>
并致电:
public func signIn(requestModel: SignInRequest) -> Promise<SignInResponse> {
let url = URL(string: authURL + "/signin")!
return sendRequest(requestModelType:SignInRequest.self,
responseModelType:SignInResponse.self,
url: url,
requestModel: requestModel)
}
不是我所希望的解决方案,但可以解决问题。
答案 1 :(得分:0)
如果您为函数的参数提供足够的上下文来确定所有通用参数,则推断将成功。
从您的代码中,我怀疑不是这种情况,因为通用类型U
既没有作为参数出现,也没有附加的类型约束来指定它。因此,编译器无法从函数调用中推断出函数返回值的具体类型是什么。
因此,如果T
与U
之间存在关联,则可以将其用作附加约束,以在找到U
后T
来“帮助”编译器推断。这是一个最小的示例:
protocol Foo {
associatedtype Bar
var bar: Bar { get }
}
struct FooImpl: Foo {
let bar: Int = 0
}
func f<T, U>(foo: T) -> U where T: Foo, U == T.Bar {
return foo.bar
}
let a = f(foo: FooImpl())
协议Foo
具有关联的类型Bar
。通过在函数f
的签名中使用此关联以对其返回类型添加约束,当我使用{的实例调用它时,Swift的编译器现在可以完全推断f
的专用签名。 {1}}。
在您的特定示例中,我建议编写一个FooImpl
参数应向其确认的协议,并使用关联的类型对返回值施加约束。
例如:
requestModel