Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

210
Views
Comportamiento opcional y genérico extraño en Swift 4.2 después de actualizar a iOS 12.2 (Xcode 10.2)

Acabamos de actualizar Xcode a 10.2 (de ahí iOS 12.2 SDK) y comenzamos a ver un comportamiento extraño con respecto al comportamiento de Swift Generics y Optionals . Hemos mantenido la versión de Swift en 4.2, por lo que no hay actualización de Swift 5. El único cambio fue actualizar a Xcode 10.2 desde Xcode 10.1.

Aquí hay un código de muestra que ilustra las rarezas. Los comentarios muestran lo que ha cambiado entre versiones. Idealmente, no debería haber ningún cambio.

 class Phone<T> {} extension Phone { class func create(initial: T? = nil) -> Phone<T> { if let _ = initial { print("Regular: Unwrapping worked.") } return Phone() } } extension Phone where T == Void { class func create(initial: T? = nil) -> Phone<T> { if let _ = initial { print("T == Void: Unwrapping worked.") } return Phone() } } var phone: Phone<Int?> = Phone() var phone2: Phone<Int?> = Phone() var phone3: Phone<Int?> = Phone() // unwrapping works iOS 12.1, doesn't work in 12.2 phone = Phone.create(initial: Optional(nil)) // unwrapping works iOS 12.1, doesn't work in 12.2 phone2 = Phone.create(initial: Optional<Int?>(nil)) // doesn't compile in iOS 12.1, unwrapping works in iOS 12.2 phone3 = Phone.create(initial: Optional<Int>(nil)) // doesn't compile in iOS 12.1, unwrapping doesn't work in 12.2 (uses the T == Void function) let phone4 = Phone.create(initial: Optional(nil))

Hemos revisado las notas de la versión de Xcode 10.2, pero no hemos detectado ningún cambio en los opcionales o genéricos. Es realmente difícil entender qué está causando este cambio de comportamiento entre versiones.

Es especialmente interesante cómo phone2 y phone3 se comportan de manera diferente. Hay algunas cosas extrañas que suceden en el ejemplo de código anterior, por lo que la pregunta es si alguien sabe qué podría haber causado los cambios de comportamiento en esta versión.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Esto se debe a SE-0213: Inicialización literal a través de coerción , lo que significa que el compilador ahora trata Optional(nil) como nil as Optional . Anteriormente, con Optional(nil) , obtendría un valor nil envuelto , por ejemplo, Int??.some(nil) , sin embargo, ahora solo obtiene nil .

Entonces por lo siguiente:

 let phone: Phone<Int?> = Phone.create(initial: Optional(nil))

el compilador lo está tratando como:

 let phone: Phone<Int?> = Phone.create(initial: nil as Optional)

que es equivalente a:

 let phone: Phone<Int?> = Phone.create(initial: nil)

¿Porque ha especificado que el parámetro genérico T sea Int? , el parámetro initial: toma un Int?? . Por lo tanto, al pasar nil , está pasando Int??.none y, por lo tanto, falla el desenvolvimiento.

Una forma de restaurar el comportamiento anterior es especificar .init explícitamente para obligar al compilador a llamar al inicializador:

 let phone: Phone<Int?> = Phone.create(initial: Optional.init(nil))

Ahora está pasando un Int??.some(nil) al parámetro y el desenvolvimiento se realiza correctamente.

Sin embargo, me preguntaría por qué estás tratando con opciones doblemente envueltas en primer lugar; recomiendo encarecidamente evitarlas a menos que sea absolutamente necesario.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!