两个协议

时间:2015-12-15 20:28:16

标签: swift generics swift-protocols

我已在swift 2

中设置了以下两个协议
  • 生成(缺少一个更好的名称),它包含一个项目数组,并提供数据源,如count和subscript等功能
public protocol Generative {
    typealias GeneratedType

    var elements: [GeneratedType] { get }
}

public extension Generative {
    func count() -> Int {
        return elements.count
    }

    subscript(index:Int) -> GeneratedType? {
        if index >= count() {
            return nil
        }
        return elements[index]
    }

}

public protocol Selectable {
    typealias SelectableType: Hashable

    var selectedElements: Set<SelectableType> { get set }

}

extension Selectable {
    public func isSelected(elem: SelectableType) -> Bool {
        return selectedElements.contains(elem)
    }

    public mutating func addSelection(elem: SelectableType) {
        selectedElements.insert(elem)
    }

    public mutating func removeSelection(elem: SelectableType) {
        selectedElements.remove(elem)
    }

    public mutating func clearSelections() {
        selectedElements.removeAll()
    }
}

因此,如果一个对象实现了Generative和Selectable,那么我希望它能够返回所选的索引,所以我写了这个函数:

func selectedIndices<S: Selectable where S: Generative, S.GeneratedType == S.SelectableType>(ds: S) -> [NSIndexPath] {
    var selections: [NSIndexPath]  {
        return ds.selectedElements
            .map{ (p: S.GeneratedType) -> NSIndexPath? in
                if let idx = ds.elements.indexOf(p) { idx
                    return NSIndexPath(forRow: idx, inSection: 0)
                }
                return nil
            }
            .filter{ $0 != nil }
            .map{ $0! }
    }


    return selections
}

由于某种原因链接器打印出来:

  

命令因信号失败:分段错误:11

不确定为什么会这样,我无法找到另一种方法来指定此函数来处理实现这两种协议及其相关类型匹配的对象... 有什么想法吗?

P.S。要点中的代码:https://gist.github.com/edwardIshaq/715b0e134fb47d2e28cc

-------更新 删除计算属性似乎可以解决问题:

func selectedIndices<S: Selectable where S: Generative, S.GeneratedType == S.SelectableType>(ds: S) -> [NSIndexPath] {
    return ds.selectedElements
        .flatMap { (p: S.GeneratedType) -> NSIndexPath? in
            if let idx = ds.elements.indexOf(p) { idx
                return NSIndexPath(forRow: idx, inSection: 0)
            }
            return nil
    }
}

1 个答案:

答案 0 :(得分:2)

编译器永远不会崩溃,但看起来原因更简单,似乎与在内部使用计算属性的泛型函数有关,这很简单,我可以得到它:

QDBusArgument

作为一种解决方法,请尝试重构代码以不使用计算属性。

您可以这样做,并将其写为两个协议的扩展,如下所示:

// swiftc crashes when compiling this
func f<T>(t: T) -> Int {
    var v: Int {
        return 0
    }
    return v
}