[英]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.