我有一个协议:
protocol Model {}
使用此协议的结构:
struct Foo: Model {}
然后我有一个通用的协议:
protocol Controller {
func fun<T: Model>() -> Observable<T>
}
控制器的方法实现可以推断出类型:
class Bar: Controller {
func fun<Foo>() -> Observable<Foo> {
// return an observable
}
}
我以为我在这里做的是有两个“基本”协议,一个用于模型,一个用于控制器。基本控制器指示使用基本模型组的泛型实现的方法,然后实现可以指定要使用的模型。写完所有内容后,它可以正常编译,并且一切看起来都井井有条,但是当我创建Bar
的实例并尝试对其调用fun()
时,我会收到一条错误消息,提示Generic parameter 'Foo' can not be inferred
。 >
这是一个可以复制的最小完整示例:
protocol Model {}
struct Foo: Model {}
protocol Controller {
func fun<T: Model>() -> Observable<T>
}
class Bar: Controller {
func fun<Foo>() -> Observable<Foo> {
return Observable.create { observer in
let cancel = Disposables.create {
// clean up
}
return cancel
}
}
}
现在调用Bar().fun()
会出现错误:Generic parameter 'Foo' can not be inferred
有两件事我在这里不明白。首先是它怎么知道我调用了指定Foo的实现,而同时又无法推断类型呢? Foo不是通用的,它是Foo结构的实际类型。我不明白的第二件事和这里的实际问题是,如果我在实现并指定通用方法的实例上调用方法,为什么它不能推断类型?
答案 0 :(得分:1)
我认为您的误解是将这种方法中的Foo
误认为是Foo
结构:
func fun<Foo>() -> Observable<Foo> {
// return an observable
}
不是!在以上方法的上下文中,Foo
只是另一个通用类型参数!
您要在这里实现的目标...
基本控制器使用基本模型组的泛型来指定要实现的方法,然后实现可以指定要使用的模型。
...应使用关联的类型:
protocol Model {}
struct Foo: Model {}
protocol Controller {
associatedtype ModelType: Model
func fun() -> Observable<ModelType>
}
class Bar: Controller {
typealias ModelType = Foo
func fun() -> Observable<Foo> {
return Observable.create { observer in
let cancel = Disposables.create {
// clean up
}
return cancel
}
}
}
答案 1 :(得分:0)
func fun<Foo>(_ type: Foo.Type) -> Observable<Foo> {
return Observable.create { observer in
let cancel = Disposables.create {
// clean up
}
return cancel
}
}
然后您可以通过以下方式调用它:
Bar.fun(YourModel.self)
答案 2 :(得分:0)
首先,您需要修复fun
方法的实现:
class Bar: Controller {
func fun<T: Model>() -> Observable<T> {
return Observable<T>.create { observer in
let cancel = Disposables.create {
// clean up
}
return cancel
}
}
}
然后,您需要在调用方中推断出通用的Foo
参数,例如:
let observableFoo: Observable<Foo> = Bar().fun()