如何在Swift中创建通用协议?
我想用一个方法创建一个协议,该方法接受一个泛型输入并返回一个泛型值 这是我到目前为止尝试过的,但它会产生语法错误 使用未声明的标识符T 我做错了什么如何在Swift中创建通用协议?,swift,Swift,我想用一个方法创建一个协议,该方法接受一个泛型输入并返回一个泛型值 这是我到目前为止尝试过的,但它会产生语法错误 使用未声明的标识符T 我做错了什么 protocol ApiMapperProtocol { func MapFromSource(T) -> U } class UserMapper: NSObject, ApiMapperProtocol { func MapFromSource(data: NSDictionary) -> UserModel {
protocol ApiMapperProtocol {
func MapFromSource(T) -> U
}
class UserMapper: NSObject, ApiMapperProtocol {
func MapFromSource(data: NSDictionary) -> UserModel {
var user = UserModel() as UserModel
var accountsData:NSArray = data["Accounts"] as NSArray
return user
}
}
协议有点不同。看看“关联类型” 这就是您在示例中使用它的方式
protocol ApiMapperProtocol {
associatedtype T
associatedtype U
func MapFromSource(_:T) -> U
}
class UserMapper: NSObject, ApiMapperProtocol {
typealias T = NSDictionary
typealias U = UserModel
func MapFromSource(_ data:NSDictionary) -> UserModel {
var user = UserModel()
var accountsData:NSArray = data["Accounts"] as NSArray
// For Swift 1.2, you need this line instead
// var accountsData:NSArray = data["Accounts"] as! NSArray
return user
}
}
要详细说明一下,如果您想创建一个使用特定ApiMapperProtocol
的方法,请执行以下操作:
protocol ApiMapperProtocol {
associatedtype T
associatedtype U
func mapFromSource(T) -> U
}
class UserMapper: NSObject, ApiMapperProtocol {
// these typealiases aren't required, but I'm including them for clarity
// Normally, you just allow swift to infer them
typealias T = NSDictionary
typealias U = UserModel
func mapFromSource(data: NSDictionary) -> UserModel {
var user = UserModel()
var accountsData: NSArray = data["Accounts"] as NSArray
// For Swift 1.2, you need this line instead
// var accountsData: NSArray = data["Accounts"] as! NSArray
return user
}
}
class UsesApiMapperProtocol {
func usesApiMapperProtocol<
SourceType,
MappedType,
ApiMapperProtocolType: ApiMapperProtocol where
ApiMapperProtocolType.T == SourceType,
ApiMapperProtocolType.U == MappedType>(
apiMapperProtocol: ApiMapperProtocolType,
source: SourceType) -> MappedType {
return apiMapperProtocol.mapFromSource(source)
}
}
您可以将模板方法与类型擦除一起使用
protocol HeavyDelegate : class {
func heavy<P, R>(heavy: Heavy<P, R>, shouldReturn: P) -> R
}
class Heavy<P, R> {
typealias Param = P
typealias Return = R
weak var delegate : HeavyDelegate?
func inject(p : P) -> R? {
if delegate != nil {
return delegate?.heavy(self, shouldReturn: p)
}
return nil
}
func callMe(r : Return) {
}
}
class Delegate : HeavyDelegate {
typealias H = Heavy<(Int, String), String>
func heavy<P, R>(heavy: Heavy<P, R>, shouldReturn: P) -> R {
let h = heavy as! H
h.callMe("Hello")
print("Invoked")
return "Hello" as! R
}
}
let heavy = Heavy<(Int, String), String>()
let delegate = Delegate()
heavy.delegate = delegate
heavy.inject((5, "alive"))
protocol-HeavyDelegate:class{
func重型(重型:重型,应返回:P)->R
}
班重{
typealias参数=P
typealias返回=R
弱var委托:HeavyDelegate?
func注入(p:p)->R{
如果委托!=nil{
返回代理?.heavy(self,shouldReturn:p)
}
归零
}
func callMe(r:返回){
}
}
类委托:HeavyDelegate{
类型别名H=重型
func重型(重型:重型,应返回:P)->R{
设h=重如!h
h、 叫我(“你好”)
打印(“已调用”)
返回“Hello”作为!R
}
}
让重
让delegate=delegate()
重载.delegate=委托
重。注入((5,“活着”))
为了实现泛型,并让它像这样声明让userMapper:ApiMapperProtocol=userMapper()
您必须拥有一个符合协议的泛型类,该协议返回泛型元素
protocol ApiMapperProtocol {
associatedtype I
associatedType O
func MapFromSource(data: I) -> O
}
class ApiMapper<I, O>: ApiMapperProtocol {
func MapFromSource(data: I) -> O {
fatalError() // Should be always overridden by the class
}
}
class UserMapper: NSObject, ApiMapper<NSDictionary, UserModel> {
override func MapFromSource(data: NSDictionary) -> UserModel {
var user = UserModel() as UserModel
var accountsData:NSArray = data["Accounts"] as NSArray
return user
}
}
如何创建和使用通用协议 协议通用{
associatedtype T
associatedtype U
func operation(_ t:T)->U
}
//使用通用协议
结构测试:通用{
associatedtype T
associatedtype U
func operation(_ t:T)->U
typealias T = UserModel
typealias U = Any
func operation(_ t: UserModel)->Any {
let dict = ["name":"saurabh"]
return dict
}
}这是一篇非常好的评论,投了赞成票。几个愚蠢的问题:为什么他们决定使用
作为代码>而不是Swift 1.2中的
?第二:您能告诉我为什么我们需要在符合协议的类中再次定义类型别名
(即类型别名T=NSDictionary类型别名U=UserModel
)?提前谢谢。我不知道他们为什么从as
切换到as代码>。检查devforum。typealias T=NSDictionary
和typealias U=UserModel
不是必需的。我更新了示例以反映这一点。as!表明它可能失败。使开发人员更清楚。它位于答案的底部。请注意,ApiMapperProtocol的唯一用途是用于一般约束。这不像你能写let x:ApiMapperProtocol=UserMapper(),为什么苹果坚持让一切都变得如此违反直觉?@Ben在这种情况下,你如何才能实现let x:ApiMapperProtocol=UserMapper()。@denis\lor如果x
是本地的,那么你就不需要明确地说出它的类型,所以let x=UserMapper()@ BeLeGeReRo。我发现如果使用中间泛型类中的一个类,你可以做一些事情,比如让X:APimaPrPrime= UrMaPiPror():这个帖子不包含任何解释。您也已经按原样发布了,请检查我的回答:在这种情况下制定协议有什么意义?它不用于userMapper
的声明中。
typealias T = UserModel
typealias U = Any
func operation(_ t: UserModel)->Any {
let dict = ["name":"saurabh"]
return dict
}