ole
(Ole Begemann)
1
I have a question for @hborla and @Slava_Pestov about your (excellent!) WWDC 2022 talks Embrace Swift generics and Design protocol interfaces in Swift. I though I'd ask this here instead of on the Apple Developer Forums because it's 100% about a language feature.
In them, you have this feedAnimal method that calls type(of: animal) on a some Animal value in order to get at the associated type FeedType:
extension Farm {
private func feedAnimal(_ animal: some Animal) {
let crop = type(of: animal).FeedType.grow()
let feed = crop.harvest()
animal.eat(feed)
}
}
I understand that you wanted to show the new some Animal syntax, but to me this looks like a code smell because type(of:) is a runtime construct in my understanding.
I would have written this with a named type parameter, which would allow me to get rid of the type(of:):
func feedAnimal<A: Animal>(_ animal: A) {
let crop = A.FeedType.grow()
…
}
Question: is there a difference between these two variants in terms of the generated code? Is the version using type(of:) less efficient? Or are they identical?
7 Likes
type(of:) is always identical to the explicit version when the type(of:) is the base of a member type lookup.
6 Likes
ole
(Ole Begemann)
3
That's good to know, thanks!
Ray_Fix
(Ray Fix)
4
Thanks for Ole's interesting question and Slava's informative reply!
I played around with a simplified version of the code with Compiler Explorer using the Swift 5.7 nightly.
In the no-flags version, there is always an extra call to swift_getDynamicType@PLT in there for the type(of:) version. But if you add -O for optimization they are indeed the same. If fact one method just aliases the other! 


I changed the signature of the method just slightly so I could compare. Yep, they're the same.
7 Likes