Hello, new to the Swift community here and coming from Julia language background. On my little adventure with the Swift Programming Language official book I have been going through Protocols, Generics, Extensions, and finally Opaque Types. I stumbled upon the interesting example from the book where it defines a brand new protocol (if I understand correctly) called Container
and then it extends the known Array
type to conform to that protocol.
protocol Container {
associatedtype Item
var count: Int { get }
subscript(i: Int) -> Item { get }
}
extension Array: Container { }
The example then proceeds to demonstrate some interesting aspects of opaque types. Something like (after some edits by me)
extension Container {
var isContainer: Bool { true }
}
func makeOpaqueContainer<T>(item: T) -> some Container {
return [item]
}
let opaqueContainer = makeOpaqueContainer(item: 12)
print(type(of: opaqueContainer)) // Array<Int>
let twelve = opaqueContainer[0]
print(opaqueContainer.isContainer) // true
print(type(of: twelve)) // Int
At this point, again coming from Julia language background, a question came to mind: how can we tell at run-time which function exactly is being called. In Julia there exists a popular macro @which
that can be placed on the same line with a function call to print out which method is being dispatched, and that can greatly help with debugging and with understanding how the compiler is reasoning about the code. Is there a Swift equivalent of such @which
functionality? My quick search led me to this thread which is discussing some topics way over my head for a beginner, yet this particular comment helped me explore more:
extension Container {
func whatAmI() { print("Container") }
}
extension Array {
func whatAmI() { print("Array") }
}
func whatIsIt<C: Container>(_ value: C) {
value.whatAmI()
}
let x = [1, 2, 3]
x.whatAmI() // Array
whatIsIt(x) // Container
let y: some Container = [1, 2, 3]
y.whatAmI() // Container
print(type(of: y)) // Array<Int>
print(y[1]) // 2
I'm particularly curious about the very last line. Is there a way to annotate that line with @which
-similar construct to let us know what subscript function exactly is being called for that some Container
, together with the exact concrete type that is being resolved by the compiler? For example
print(@which y[1]) // Array<Int>.subscript
Having such feature in the Julia language was really helpful and I'd very much like to have a similar feature to help me validate my reasoning about Swift code! Thanks in advance!