繁体   English   中英

在实现协议方法时快速提供通用方法类型参数

[英]Swift supply generic method type parameter when implementing protocol method

我有一个名为ContentService的协议,旨在公开用于从各种REST API读取数据的通用功能。 ContentService的每个实现都将执行该特定API所需的机制。

protocol ContentService {     
    func loadNextPage<T>(pageStartId: T) -> [Datum]
    //Other methods...
}

由于给定的API可能有其他方法来标记返回数据的页面边界,因此我想在实现类中指定所需的类型,如下所示:

class ServiceA : ContentService {

    func loadNextPage<Int>(pageStartId: Int) -> [Datum] {
        //Do something with pageStartId typed as an Int
        return posts
    }
}

class ServiceB : ContentService {
    func loadNextPage<NSDate>(pageStartId: NSDate) -> [Datum] {
        //Do something with pageStartId typed as an NSDate
        return posts
    }
}

注意 ,我在实现类型(ServiceA,ServiceB)的定义中指定了类型参数,因为它们特定于该服务。 我的期望是这些类的任何实例都会有一个带有签名loadNextPage(pageStartId: X) -> [Post] ,其中X是实现该方法时为T提供的特定类型。

为了从api加载数据页面,我将使用如下所示的内容:

let apiA = ServiceA()
let apiB = ServiceB()

let dataA = apiA.loadNextPage(1234)
let dataB = apiB.loadNextPage(NSDate())

虽然此编译没有错误。 您还可以编译以下内容而不会出现错误:

let dataA = apiA.loadNextPage("Anything works here.")

因此,ServiceA的loadNextPage()方法不限于Int参数。 此外,在loadNextPage()方法的方法定义中,尽管在Xcode中检查pageStartId参数似乎是预期的类型,但我无法使用通常可以在该类型上访问的任何运算符或方法。 例如,在ServiceA的实现中,即使pageStartId应该是Int,也不let newId = pageStartId + 5

两个问题:

1)显然,我对Swift中的泛型方法有误解,想知道为什么不能使用这种模式。

2)如果有人有一个聪明的解决方案来实现我想要在上面尝试的方法,我很想知道。

您的协议

protocol ContentService {     
    func loadNextPage<T>(pageStartId: T) -> [Datum]
    //Other methods...
}

需要通用方法loadNextPage ,并且

func loadNextPage<Int>(pageStartId: Int) -> [Datum] {
    //Do something with pageStartId typed as an Int
    return posts
}

正是这样:占位符恰好具有名称Int通用方法。 在方法内部, Int引用该占位符类型,并隐藏全局Swift类型Int 等效的定义是

func loadNextPage<FOO>(pageStartId: FOO) -> [Datum] {
    //Do something with pageStartId typed as an Int
    return posts
}

您可能想要定义一个关联类型 T的协议:

protocol ContentService { 
    associatedtype T
    func loadNextPage(pageStartId: T) -> [Datum]
    //Other methods...
}

和一个采用T == Int协议的类:

class ServiceA : ContentService {

    func loadNextPage(pageStartId: Int) -> [Datum] {
        let newId = pageStartId + 5  // <-- This compiles now!
        //Do something with pageStartId typed as an Int
        return posts
    }
}

现在

let dataA = apiA.loadNextPage(1234)

编译,但是

let dataA2 = apiA.loadNextPage("Anything works here.")
// error: cannot convert value of type 'String' to expected argument type 'Int'

不符合预期。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM