斯威夫特协议通用的函数返回类型

问题描述:

我要使用通用的协议类型为函数的返回类型是这样的:斯威夫特协议通用的函数返回类型

protocol P { 
    associatedtype T 
    func get() -> T? 
    func set(v: T) 
} 

class C<T>: P { 
    private var v: T? 
    func get() -> T? { 
    return v 
    } 
    func set(v: T) { 
    self.v = v 
    } 
} 

class Factory { 
    func createC<T>() -> P<T> { 
    return C<T>() 
    } 
} 

但这个代码有错误编译抱怨:

  1. 不能专注非通用类型 'P'
  2. 通用参数 'T' 是不是在功能签名使用

有什么办法可以实现与Swift类似的功能吗?

+0

哪些行有错误?我认为我有一个好主意,其中#2不是#1。 – tktsubota

+0

@TroyT代码行'func createC () - > P { – ufosky

问题是你不能使用语法P<T>P是一个协议,这意味着它不能被视为一般类型(Cannot specialize non-generic type 'P'),即使它可能有给定associatedtype

事实上,因为它有一个associatedtype,你现在甚至不能直接使用的协议类型本身 - 你只能用它作为通用约束。

解决您的问题只是将您的功能签名更改为createC<T>() -> C<T>,因为这正是它返回的!

class Factory { 
    func createC<T>() -> C<T> { 
     return C<T>() 
    } 
} 

我不完全确定你认为你能从这里返回协议类型获得什么。如果您的代码仅仅是一个简化,并且您希望能够返回符合P的任意实例,则可以使用type erasure

class AnyP<T> : P { 

    private let _get :() -> T? 
    private let _set : (T) ->() 

    init<U:P where U.T == T>(_ base:U) { 
     _get = base.get 
     _set = base.set 
    } 

    func get() -> T? {return _get()} 
    func set(v: T) {_set(v)} 
} 

class Factory { 
    func createC<T>() -> AnyP<T> { 
     return AnyP(C<T>()) 
    } 
}