2017-01-12 36 views
2

我正在使用Swift 3,并且想要完成某些我不确定的事情。我的后端有不同的内容类型的几个不同的端点,以不同的方式页面响应等。我试图创建一个通用的协议,可以为每个内容类型实现。在符合该协议的类的声明中指定协议函数的返回类型

protocol DynamicContentFetcher { 
    func content() -> MutableObservableArray<Any> 
    func getNext() 
    func refresh() 
} 

其中一个实例是AdSearch。

class AdSearch: DynamicContentFetcher { 
    var results = MutableObservableArray<DynamicAd>([]) 
    func content() -> MutableObservableArray<Any> { 
     return results 
    } 

return不与错误Cannot convert return expression of type MutableObservableArray<DynamicAd> to return type 'MutableObservableArray<Any>,这是有道理的编译。

将是很好的什么,就是如果我能初始化我的班,符合DynamicContentFetcherAdSearch<DynamicAd>和<使用该值>做func content() -> MutableObservableArray<#Specified Type#>的协议。这可能与斯威夫特?

MutableObservableArray是来自Bond框架的类,它是一个反应式编程窗格。

+0

泛型在Swift中不是协变的;这就是错误来自的地方:“MOA ”不是“MOA ”的子类型。使类型参数明确(如dfri的答案所示),并且一切都很好。 (方不是:你选了一个不好的标题,它没有告诉我们任何关于你的问题的信息。) – Raphael

+0

@Raphael对于标题的抱歉,英语不是我的第一语言,我很难描述我正在努力完成的任务。 –

回答

5

您可以在协议使用associatedtype,并在content()返回类型在您使用此作为typeholder协议:

struct MutableObservableArray<T> {} 

protocol DynamicContentFetcher { 
    associatedtype T 
    func content() -> MutableObservableArray<T> 
    //func getNext() 
    //func refresh() 
} 

struct DynamicAd {} 

class AdSearch: DynamicContentFetcher { 
    var results = MutableObservableArray<DynamicAd>() 
    func content() -> MutableObservableArray<DynamicAd> { 
     return results 
    } 
} 

将是很好的什么,就是如果我能初始化我的类符合 DynamicContentFetcherAdSearch<DynamicAd>并使用该值 <>func content() -> MutableObservableArray<#Specified Type#>在 该协议。

您可能希望让AdSeach类是通用的,拿着它用于指定通用typeholder(下面,隐含的推论)的typealiasDynamicContentFetcher协议的associatedtype

class AdSearch<U>: DynamicContentFetcher { 
    // typealias T = U // infered 
    var results = MutableObservableArray<U>() 
    func content() -> MutableObservableArray<U> { 
     return results 
    } 
} 

struct DynamicAd {} 
let dynamicAdSearch = AdSearch<DynamicAd>() 
+0

谢谢!是否有可能做到这一点,所以我可以定义而不指定类型?在定义AdSearch的模型中,我想要一个'var contentFetcher:DynamicContentFetcher ',但这或者给我“协议只能用作通用包含,因为它具有自我或者符合类型要求”如果我没有指定它,或者“无法专门化非泛型类型”(如果我指定它)。 –

+1

Swift编译器可以找出'AdSense'用于'T'的类型,但我认为为了清楚起见,添加'typealias T = DynamicAd'是个好主意。 – Raphael

+0

@OscarApeland你可以声明如下:'func contentFetcher () - > U其中U.T:DynamicContent {...}'。如何实例化返回值,我不知道。 :D – Raphael

相关问题