Swift getter 和 setter 具有不同签名的下标
Swift subscript with different signature for the getter and setter
是否可以在 Swift 中包含一个 subscript
,它对 getter
和 setter
具有不同的签名?
例如,我希望 getter
到 return 一个 Set<Int>
并且 setter
需要一个 Int
(而不是 Set<Int>
).
此代码无法编译,但它可以让您了解我正在尝试做什么:
struct Foo{
subscript(index: Int)->String{
get{
return "bar" // returns a String
}
set(newValue: String?){ // takes a String? instead of a String
print(newValue)
}
}
}
我该怎么做?
这非常丑陋,我强烈建议您不要这样做,但从技术上讲这是可能的:
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"
前段时间我做了一个多图:
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() }
}
用法:
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" }
是否可以在 Swift 中包含一个 subscript
,它对 getter
和 setter
具有不同的签名?
例如,我希望 getter
到 return 一个 Set<Int>
并且 setter
需要一个 Int
(而不是 Set<Int>
).
此代码无法编译,但它可以让您了解我正在尝试做什么:
struct Foo{
subscript(index: Int)->String{
get{
return "bar" // returns a String
}
set(newValue: String?){ // takes a String? instead of a String
print(newValue)
}
}
}
我该怎么做?
这非常丑陋,我强烈建议您不要这样做,但从技术上讲这是可能的:
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"
前段时间我做了一个多图:
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() }
}
用法:
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" }