4

Is it possible to create a subscript that can be invoked with explicit argument labels?

struct MyType {
    subscript (label: Bool) -> String? {
        return nil
    }
}

let test = MyType()
let value1 = test[true] // ok
let value2 = test[label: true] // Extraneous argument label 'label:' in subscript

Attempting to use the label results in the error:

Extraneous argument label 'label:' in subscript

The new key path feature looks like it uses subscripts with argument labels, but that may be compiler magic that isn't available to the public:

let value = someThing[keyPath: \.property]
pkamb
  • 33,281
  • 23
  • 160
  • 191
jeremyabannister
  • 3,796
  • 3
  • 16
  • 25

1 Answers1

4

External argument labels in subscript aren't used by default, so unlike for normal functions, if you want to have external argument labels, you need to specify that explicitly.

struct MyType {
    subscript(label label: Bool) -> String? {
        return nil
    }
}

let test = MyType()
let value = test[label: true]
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • Thanks very much. I saw this statement written in Ray Wenderlich's [tutorial](https://www.raywenderlich.com/9088-custom-subscripts-in-swift) but for some reason it didn't click that it meant writing it twice. I was like "but `subscript (label: Bool) -> String?` _is_ explicit!" – jeremyabannister Sep 18 '19 at 15:20
  • 1
    @jeremyabannister glad I could help :) Yeah, this is quite a confusing implementation detail, especially because it is opposite to what normal functions do. – Dávid Pásztor Sep 18 '19 at 15:40