无法转换类型'(T) - >的值虚空”

时间:2017-10-10 18:24:39

标签: swift generics closures

示例:

struct Wrapper<T> {
    var key: Int = 0
    var listeners: [Int: (T) -> Void] = Dictionary()

    mutating func add(_ handler:@escaping (T) -> Void) {
        self.key += 1
        self.listeners[self.key] = handler
    }

    func get(key: Int) -> (T) -> Void {
        return self.listeners[key]!
    }
}

测试协议:

protocol CommonProtocol {

}

创建测试类Wrapper的类

class C {
    var wrapper: Wrapper = Wrapper<CommonProtocol>()

    func add<T: CommonProtocol>(_ handler: @escaping (T) -> Void) {
        self.wrapper.add(handler) //Cannot convert value of type '(T) -> Void' to expected argument type '(CommonProtocol) -> Void'
    }
}

Image with error

我收到错误:

Cannot convert value of type '(T) -> Void' to expected argument type '(CommonProtocol) -> Void'

问题:

  

为什么(T) -> Void无法投放到(CommonProtocol) -> VoidT   显式声明为<T: CommonProtocol>

这是我的第一个问题,如果您有任何建议,请随时与我联系

1 个答案:

答案 0 :(得分:0)

您无需使string text = " SELECT ID FROM Items i1 WHERE i1.ParentID <> null AND NOT EXISTS(SELECT ID FROM Items i2 WHERE i2.ID = i1.ParentID)"; string sql = " DELETE FROM Items WHERE ID IN (" + text + ")"; 通用。 当您在func add中指定时,明确告诉编译器您的函数接受继承 func add<T: CommonProtocol>...的所有类型,但您的Wrapper指定接受CommonProtocol不是继承类型。< / p>

解决方案

任何类型擦除类C:

CommonProtocol

或者如果类型T对您来说实际上并不重要,那么:

Class C<T: CommonProtocol> {
    var wrapper: Wrapper<T>
    ....
}

但第二个根本没有意义。你必须在每次使用这种方法的时候贬低它(而且低点非常糟糕:D)

注意:它实际上与此问题无关,但您的一个选择是键入 - 删除func add(_ handler: @escaping (CommonProtocol) -> Void)