通用协议属性声明

时间:2019-03-29 06:29:45

标签: swift

假设我有一个与类型T相关的协议

protocol Helper{
    associatedtype T
    func help(_ item: T)
}

在一个类中,我想声明一个属性

class Manager<T>{
    let item: T?
    let helper: Helper<T>
//Error: Cannot specialize non-generic type 'Helper'

    let anotherHelper: Helper 
//Error: Protocol 'Helper' can only be used as a generic constraint because it has Self or associated type requirements
}

我如何以这样的方式声明和使用helper属性,使其强制执行符合Helper协议的类的类型?

我敢肯定,很多有Java / C#或其他类似语言背景的人在尝试做类似事情时都会被困住

2 个答案:

答案 0 :(得分:0)

在这种情况下,您可以将T中的Manager<T>设为Helper

class Manager<T> where T : Helper {
    let item: T.T?
    let helper: T

    init(helper: T) {
        self.helper = helper
        item = nil
    }
}

如果您想要Helper<Int>,请执行以下操作:

class IntHelper : Helper {
    typealias T = Int

     // ... 
}

然后使用Manager<IntHelper>

答案 1 :(得分:0)

您可能需要一种类型的橡皮擦:

struct AnyHelper<T>: Helper {
    private let helpFunc: (T) -> Void

    init<H>(_ helper: H) where Helper.T == T {
        helpFunc = helper.help
    }

    func help(_ item: T)
        helpFunc(item)
    }
}

,然后在您的课程中使用类型橡皮擦:

class Manager<T>{
    let item: T?
    let helper: AnyHelper<T>

    init<H>(item: T, helper: H) where H.T == T {
        self.item = item
        self.helper = AnyHelper(helper)
    }
}