Estou trabalhando com Swift e encontrei um problema ao usar o método contains em um array. O código a seguir funciona bem:
let result = ["hello", "world"].contains(Optional("hello")) // ✅ Works fine
Entretanto, quando tento usar o mesmo método contains com o array declarado em uma constante (ou variável) separada, recebo um erro de compilação:
let stringArray = ["hello", "world"]
let result = stringArray.contains(Optional("hello")) // ❌ Compile-time error
O compilador produz a seguinte mensagem de erro:
Cannot convert value of type 'Optional<String>' to expected argument type 'String'
Ambos os exemplos parecem conceitualmente semelhantes, mas o segundo causa um erro de compilação, enquanto o primeiro funciona bem.
Isso me confunde porque eu sei que o Swift promove automaticamente um valor não opcional para um opcional ao compará-lo com um valor opcional. Isso significa que "hello" deve ser convertido implicitamente para Optional("hello") para a comparação. ( 🔗 Referência )
O que entendi até agora:
O método contains(_:) é definido como:
func contains(_ element: Self.Element) -> Bool
Internamente, ele chama
contains(where:)
, como visto no código-fonte do Swift:contains(where:)
recebe um fechamento que aplica o==
operador para comparação.Como o Swift permite comparar
String
eString?
diretamente (String
é implicitamente promovido paraString?
quando comparado com um opcional), eu esperavacontains(where:)
que funcionasse da mesma maneira.
Minhas perguntas:
- Por que o primeiro exemplo funciona, mas o segundo falha com um erro de tempo de compilação?
- O que exatamente causa esse erro no segundo caso, mesmo que ambos os casos envolvam a comparação de um valor opcional com um valor não opcional?
- Comporta
contains(_:)
-se de forma diferente quando usado com uma variável de array explícita em vez de um literal de array direto? Se sim, por quê?
Sei que há diferentes maneiras de resolver isso, como usar coalescência nula ou vinculação opcional, mas o que realmente estou procurando é uma explicação detalhada do porquê esse problema ocorre no nível de tempo de compilação.
Alguém pode explicar a razão subjacente para esse comportamento?