Swift Collection一致性默认值

时间:2018-01-18 11:06:53

标签: swift

在我的应用程序中,我有一些符合Collection的对象。我这样做是因为我得到了for循环语法和所有filter / map / etc方法。但我注意到它总是一样的。我有一个私人阵列,我只是转发电话。所以我想我会将Collection协议包装在另一个协议中,如下所示:

protocol CollectionTrait: Collection {
    associatedtype CollectionType: Collection

    var _items: CollectionType { get }
}

extension CollectionTrait {
    var startIndex: CollectionType.Index {
        return _items.startIndex
    }

    var endIndex: CollectionType.Index {
        return _items.endIndex
    }

    func index(after i: CollectionType.Index) -> CollectionType.Index {
        return _items.index(after: i)
    }

    subscript(index: CollectionType.Index) -> CollectionType.Element {
        get {
            return _items[index]
        }
    }
}

这可以使用如下:

class Words: CollectionTrait {
    let _items = [
        "foo", "bar", "baz"
    ]
}

let words = Words()
for word in words {
    print(word)
}

我觉得这很好,我现在唯一的问题是_items需要公开,但我有点希望它是私密的,因为我更喜欢不要暴露它。所以现在我用下划线作为前缀,以表明它不应该被使用。有人知道强行这种行为的方法吗?或者通常是一种更好的方法来避免没有继承的代码重复(在我的情况下并不总是可行)

1 个答案:

答案 0 :(得分:0)

如果您将代码拆分为多个文件,则可以将CollectionTrait定义为private协议并与fileprivate一致。如果在一个文件中,您有:

private protocol CollectionTrait: Collection {
    associatedtype CollectionType: Collection

    var _items: CollectionType { get }
}

extension CollectionTrait {
    var startIndex: CollectionType.Index {
        return _items.startIndex
    }

    var endIndex: CollectionType.Index {
        return _items.endIndex
    }

    func index(after i: CollectionType.Index) -> CollectionType.Index {
        return _items.index(after: i)
    }

    subscript(index: CollectionType.Index) -> CollectionType.Element {
        get {
            return _items[index]
        }
    }
}

class Words: CollectionTrait {
    fileprivate let _items = [
        "foo", "bar", "baz"
    ]
}

在另一个文件中,如果您尝试使用Words,则可以:

let words = Words()
for word in words {
    print(word)
}

但尝试直接访问words._items会出错,因为它是fileprivate