Assuming I have a Protocol Identifiable, which enforces, that every implementing object has a readable Id-string property, would it at all be possible, to extend Dictionary to accept new elements without explicitly providing an Index, but store the element under it's own Id?
Pseudo Code:
class Object : Identifiable {}
var object = Object(id: "123")
var dictionary = Dictionarystring:Identifiable()
dictionary = object
...which saves me doing dictionary[object.id] = object
I think it could be easily done with a method, but using a subscript would feel more natural.
Such a subscript would be write-only, so I don't think it's "natural". And Swift doesn't allow write-only properties and subscripts. One of the reasons for this is that you should be able to do this
var p: (a: Int, b: Int) {
get { ... }
set { ... }
}
p.a = 42
And that requires both getter and setter because it's essentially equivalent to this
var temp = p
temp.a = 42
p = temp
So, while it's theoretically possible to have write-only properties and subscripts, the constraints that should be applied to them make them hardly usable.
If you’re writing your own type wrapping the dictionary, insert(_:) would be a reasonable name for this operation. But adding a method like that to Dictionary itself would be confusing to me if I were to read code that used it.
Empty subscript is fine, I use it as an alias for UnsafePointer.pointee in my personal projects. I agree that the lack of a getter makes me question whether it’s a good idea here, though. I also agree that marking the getter unavailable should not be ignored entirely—either it should be a de facto way to get set-only storage declarations, or the compiler should at least warn that the attribute will be ignored in that position.
Edited for brevity from source. pointee could have been avoided by an = 0. I bet it was decided against because people don't teach each other to recognize empty square brackets.
extension UnsafePointer where Pointee: ~Copyable {
@_alwaysEmitIntoClient public var pointee: Pointee {
@_transparent unsafeAddress { self }
}
}
extension UnsafePointer where Pointee: ~Copyable {
@_alwaysEmitIntoClient public subscript(i: Int) -> Pointee {
@_transparent unsafeAddress { self + i }
}
}