protocol Animal {
func makeNoise()
static var species: String { get }
}
struct Dog: Animal {
func makeNoise() { print("Woof") }
static var species: String = "Canus familiaris"
}
struct Cat: Animal {
func makeNoise() { print("Meow") }
static var species: String = "Felis catus"
}
var animal: Animal // `Animal` is used here as a type.
animal = Dog()
animal.makeNoise() // Prints "Woof".
animal = Cat()
animal.makeNoise() // Prints "Meow".
func declareAnimalSpecies<T: Animal>(_ animal: T) {
animal.makeNoise()
print("My species is known as (T.species)")
}
let dog = Dog()
declareAnimalSpecies(dog)
// Prints:
// "Woof"
// "My species is known as Canus familiaris"
declareAnimalSpecies(animal) // <- not show error here
// error: protocol type 'Animal' cannot conform to 'Animal'...`
Estou pegando um código de exemplo do swift git . Pelo que entendi, o animal
tipo de 's é any Animal
so quando ele é passado para function declareAnimalSpecies
, o compilador inferirá que T é any Animal
e, por any Animal cannot conform to Animal
isso, espero que ele mostre esse erro.
Isso é permitido desde a implementação do SE-0352 . Isso nos permite "abrir caixas existenciais" ao chamar métodos genéricos. O SE-0375 nos permite fazer o mesmo com parâmetros opcionais.
animal
é uma "caixa" existencial que, em tempo de execução, contém um tipo concreto real que está em conformidade comAnimal
dentro de at. Em vez de olhar apenas para as restrições de tipo e dizer "any Animal
não está em conformidade comAnimal
", o compilador agora é capaz de ver que esta é uma caixa, e nela deve haver algum tipo concreto . Em tempo de execução, é garantido que há umT
que está em conformidade com sua restrição de tipo.Como contra-exemplo, considere
Isso não é permitido porque as caixas existenciais
a
podemb
conter diferentes tipos concretos em tempo de execução, portanto, não há necessariamente um únicoT
tipo que pode ser passado parafoo
.É importante notar que, do ponto de vista do sistema de tipos,
any Animal
ainda não está em conformidade comAnimal
. Se você temvocê ainda não consegue escrever
Foo<any Animal>
. Não há caixas existenciais para abrir neste caso.