在以下代码中,我有一个通用协议Var
,它有一个私有实现类LambdaVar
。现在我希望有一个函数返回LambdaVar
的实例而不公开它。
但是我无法找到一种方法来定义返回通用协议类型的函数。
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?
}
错误:
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> {
答案 0 :(得分:2)
您应该创建Var
的简单包装类型,例如SequenceOf<T>
:
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