Cierres

Los cierres o expresiones lambda tienen tipos que no pueden nombrarse. Sin embargo, implementan traits especiales Fn, FnMut y FnOnce:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Speaker Notes

This slide should take about 20 minutes.

Un Fn (por ejemplo, add_3) no consume ni modifica los valores capturados, o quizá no captura nada en absoluto. Se puede llamar varias veces al mismo tiempo.

Un FnMut (por ejemplo, accumulate) puede modificar los valores capturados. Se puede llamar varias veces, pero no de forma simultánea.

Si tienes un FnOnce (por ejemplo, multiply_sum), solo puedes llamarlo una vez. Puede consumir valores capturados.

FnMut es un subtipo de FnOnce, mientras que Fn es un subtipo de FnMut y FnOnce. Es decir, puedes utilizar un FnMut siempre que se llame a un FnOnce, y puedes usar un Fn siempre que se llame a un FnMut o a un FnOnce.

When you define a function that takes a closure, you should take FnOnce if you can (i.e. you call it once), or FnMut else, and last Fn. This allows the most flexibility for the caller.

In contrast, when you have a closure, the most flexible you can have is Fn (it can be passed everywhere), then FnMut, and lastly FnOnce.

El compilador también infiere Copy (por ejemplo, add_3) y Clone (por ejemplo, multiply_sum), dependiendo de lo que capture el cierre.

De forma predeterminada, los cierres capturan, si pueden, por referencia. La palabra clave move hace que capturen por valor.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX