In the following code, I have a generic protocol Var
and it have a private implementation class LambdaVar
. Now I want to have a function that return an instance of the LambdaVar
without expose it publicly.
在下面的代码中,我有一个通用协议Var,它有一个私有实现类LambdaVar。现在我想要一个函数,它返回一个LambdaVar实例,而不公开它。
But I can't find a way to define a function that return a generic protocol type.
但是我找不到一种方法来定义返回通用协议类型的函数。
public protocol Var {
typealias ValueType
var value : ValueType { get }
}
struct LambdaVar<T> : Var {
let _get : Void -> T
init(_ f : Void -> T)
{
_get = f
}
var value : T {
get {
return _get()
}
}
}
public func transform<T : Var, U>(v : T, f : T.ValueType -> U) -> Var<U> {
return LambdaVar<U>() { f(v.value) } // ^^^^^^ what to put here?
}
Error:
错误:
Playground execution failed: <EXPR>:26:67: error: cannot specialize non-generic type 'Var'
public func transform<T : Var, U>(v : T, f : T.ValueType -> U) -> Var<U> {
^
<EXPR>:26:67: error: protocol 'Var' can only be used as a generic constraint because it has Self or associated type requirements
public func transform<T : Var, U>(v : T, f : T.ValueType -> U) -> Var<U> {
1 个解决方案
#1
2
You should create simple wrapper type of Var
like SequenceOf<T>
:
您应该创建类似Var的简单包装类型SequenceOf
struct VarOf<T>:Var {
let f:Void->T
init<V:Var where V.ValueType == T>(_ v:V) {
f = { v.value }
}
var value:T {
return f()
}
}
func transform<T : Var, U>(v : T, f : T.ValueType -> U) -> VarOf<U> {
return VarOf(LambdaVar<U>({ f(v.value) }))
}
let intVar = VarOf(LambdaVar({ 12 }))
let floatVar = transform(intVar, { Float($0) })
floatVar.value // -> 12.0
#1
2
You should create simple wrapper type of Var
like SequenceOf<T>
:
您应该创建类似Var的简单包装类型SequenceOf
struct VarOf<T>:Var {
let f:Void->T
init<V:Var where V.ValueType == T>(_ v:V) {
f = { v.value }
}
var value:T {
return f()
}
}
func transform<T : Var, U>(v : T, f : T.ValueType -> U) -> VarOf<U> {
return VarOf(LambdaVar<U>({ f(v.value) }))
}
let intVar = VarOf(LambdaVar({ 12 }))
let floatVar = transform(intVar, { Float($0) })
floatVar.value // -> 12.0