Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

228
Visualizações
¿Cómo se capturan exactamente las estructuras en cierres de escape?

Me parece lógico que escapar de los cierres capture las estructuras mediante la copia. Pero si ese fuera el caso, el siguiente código no tiene sentido y no debería compilarse:

 struct Wtf { var x = 1 } func foo(){ var wtf = Wtf() DispatchQueue.global().async { wtf.x = 5 } Thread.sleep(forTimeInterval: 2) print("x = \(wtf.x)") }

Sin embargo, se compila con éxito e incluso imprime 5 cuando se llama a foo. ¿Cómo es esto posible?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Si bien puede tener sentido que se copie una estructura, como lo demuestra su código, no lo es. Esa es una herramienta poderosa. Por ejemplo:

 func makeCounter() -> () -> Int { var n = 0 return { n += 1 // This `n` is the same `n` from the outer scope return n } // At this point, the scope is gone, but the `n` lives on in the closure. } let counter1 = makeCounter() let counter2 = makeCounter() print("Counter1: ", counter1(), counter1()) // Counter1: 1 2 print("Counter2: ", counter2(), counter2()) // Counter2: 1 2 print("Counter1: ", counter1(), counter1()) // Counter1: 3 4

Si se copiara n en el cierre, esto no podría funcionar. El punto es que el cierre captura y puede modificar el estado fuera de sí mismo. Esto es lo que separa un cierre (que "cierra" el ámbito donde se creó) y una función anónima (que no lo hace).

(La historia del término "cerrar" es un poco oscura. Se refiere a la idea de que las variables libres de la expresión lambda han sido "cerradas", pero en mi opinión, "atado" sería un término mucho más obvio, y así es como describimos esto en todas partes. Pero el término "cierre" se ha utilizado durante décadas, así que aquí estamos.)

Tenga en cuenta que es posible obtener semántica de copia. Solo tienes que pedirlo:

 func foo(){ var wtf = Wtf() DispatchQueue.global().async { [wtf] in // Make a local `let` copy var wtf = wtf // To modify it, we need to make a `var` copy wtf.x = 5 } Thread.sleep(forTimeInterval: 2) // Prints 1 as you expected print("x = \(wtf.x)") }

En C++, las lambdas tienen que ser explícitas acerca de cómo capturar valores, vinculando o copiando. Pero en Swift, optaron por hacer que el enlace sea el predeterminado.

En cuanto a por qué se le permite acceder a wtf después de que haya sido capturado por el cierre, eso es solo una falta de semántica de movimiento en Swift. No hay forma en Swift hoy de expresar "esta variable se ha pasado a otra cosa y ya no se puede acceder a ella en este ámbito". Esa es una limitación conocida del lenguaje, y se está trabajando mucho para solucionarlo. Consulte el Manifiesto de propiedad para obtener más información.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda