Unclear mechanics of Swift 5.7's 'any' keyword

It's right before Moving between any and some.

To have the effects of opening persist over multiple statements, factor that code out into a generic function


Applied here, what you're looking for is $0 to transform into a more magical version of this:

func animal(_ animal: some Animal) -> some Animal {
  animal
}

AKA this, without a named constant:

let animal: some Animal = animal

But it won't do that. When you input an "any" into something like that, you get an any back out, despite what the keyword on the return type might seem to suggest.

let animal = animal($0) // any Animal
let food = provider.getFood(for: animal) // Any

You also cannot get around the problem using a closure, i.e.

func unbox<A: Animal>(_ animal: A, _ ƒ: (A) -> Void) {
  ƒ(animal)
}
unbox($0) {
  let food = provider.getFood(for: $0)
  $0.eat(food)
}

But you can define the necessary function locally:

animals.forEach {
  func feed(_ animal: some Animal) {
    animal.eat(provider.getFood(for: animal))
  }
  feed($0)
}

It looks ridiculous in context! No clue if it's solvable.

2 Likes