【问题标题】:How to create a function that returns a generic protocol type?如何创建返回通用协议类型的函数?
【发布时间】:2014-10-21 10:29:24
【问题描述】:

在下面的代码中,我有一个通用协议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> {

【问题讨论】:

  • 我认为您想要实现的目标在 swift 中是不可行的 - 请参阅 this answer。具有泛型的协议不能用作具体类型

标签: swift


【解决方案1】:

您应该创建Var 的简单包装类型,例如SequenceOf&lt;T&gt;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    相关资源
    最近更新 更多