Cool. I haven't seen Foo<_>
before. Changing it to Foo<Never>
does the same.
And changing it to Foo<Int>
causes an infinite recursion in runtime.
1 Like
It's a type placeholder, introduced in Swift 5.6. It's the least syntax you need to refer to a version of the outer type that isn't the one that's equivalent to Self
. (And again, the compiler knows which specific T
to use. Given that the type is really irrelevant, I think _
is the way to go, rather than being explicit.)
I.e. Foo
means something different when not working "within Foo
". But Foo<_>
doesn't.
extension Foo {
static var staticVar: Int {
Foo<_>.staticVar // Foo<Never>.staticVar
Foo.staticVar // Foo<T>.staticVar AKA Self.staticVar — infinite recursion
}
}
Foo<_>.staticVar // Foo<Never>.staticVar
Foo.staticVar // Foo<Never>.staticVar
Only if you didn't define the stored property where T == Int
!
struct Foo<T> {
static var fooT: String {
Foo<_>.fooT // Foo<Int>.fooT
}
}
extension Foo where T == Int {
static var fooT = "🦶"
}
enum 🐾 { }
Foo<🐾>.fooT // "🦶"
Foo.fooT // "🦶"
I question though, even though you can do this shadowing, is there a reason to? Isn't the stored property being in the one type good enough, rather than having to be forwarded to the rest of them?