Swift - a general type of function return function

I want to use a generic protocol type as the return type of a function as follows:

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>() } } 

But this code compiled with errors:

  • Unable to specialize non-generic type 'P'
  • Generic tag 'T' not used in function signature

Is there a way to achieve a similar function using Swift?

+5
source share
1 answer

The problem is that you cannot use the P<T> syntax. P is a protocol, that is, it cannot be considered as a generic type ( Cannot specialize non-generic type 'P' ), although it can have a specified associatedtype .

In fact, since it has an associatedtype , you can no longer use the protocol type itself directly - you can use it only as a general restriction.

The solution to your problem is to simply change your function signature to createC<T>() -> C<T> , exactly what it returns!

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

I'm not quite sure what you think you will get from the opportunity to return the type of protocol here. If your code is just a simplification and you want to return an arbitrary instance that matches P , you can use type erasure.

 class AnyP<T> : P { private let _get : () -> T? private let _set : (T) -> () init<U:P where UT == 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>()) } } 
+5
source

All Articles