Swift subscript with different signature for the getter and setter

扶醉桌前 提交于 2019-11-28 10:55:05

问题


Is it possible to have a subscript in Swift that has different signatures for the getter and setter?

For example, I want the getter to return a Set<Int> and the setter to take an Int (not a Set<Int>).

This code won't compile but it gives you an idea of what I'm trying to do:

struct Foo{

    subscript(index: Int)->String{
        get{
            return "bar" // returns a String
        }
        set(newValue: String?){ // takes a String? instead of a String
            print(newValue)
        }
    }
}

How can I do this?


回答1:


This is very ugly, and I strongly discourage you from doing so, but technically this is possible:

struct Foo {

    subscript(concreteValueFor index: Int) -> String {
        return "Get concrete \(index)"
    }

    subscript(optionalValueFor index: Int) -> String? {
        get { return nil }
        set { print("Set optional \(index)") }
    }

}

var foo = Foo()

foo[concreteValueFor: 1]            // Returns "Get concrete 1"
foo[optionalValueFor: 2] = ""       // Prints "Set optional 2"

For a multimap some time ago I made something like this:

public struct Multimap<Key: Hashable, Value: Hashable>: CollectionType {

    public typealias _Element = Set<Value>
    public typealias Element = (Key, _Element)
    public typealias Index = DictionaryIndex<Key, _Element>
    public typealias Generator = DictionaryGenerator<Key, _Element>

    private typealias Storage = [Key: _Element]

    private var storage = Storage()

    public var startIndex: Index { return storage.startIndex }
    public var endIndex: Index { return storage.endIndex }

    public subscript(position: Index) -> _Element { return storage[position].1 }
    public subscript(position: Index) -> Element { return storage[position] }

    subscript(key: Key) -> Set<Value> {
        get { return storage[key] ?? Set<Value>() }
        set { storage[key] = newValue.isEmpty ? nil : newValue }
    }

    public func generate() -> Generator { return storage.generate() }

}

Usage:

var foo = Multimap<Int, String>()

foo[0]                      // Returns an emtpy Set<String>
foo[0].insert("Ook")        // Inserts a value at index 0
foo[0].insert("Eek")
foo[0]                      // Now this returns a set { "Ook", "Eek" }
foo[1].insert("Banana")
foo[1].insert("Book")
foo[0].unionInPlace(foo[1])
foo[0]                      // Returns a set { "Banana", "Ook", "Eek", "Book" }


来源:https://stackoverflow.com/questions/34342620/swift-subscript-with-different-signature-for-the-getter-and-setter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!