closures - traductor - tradusir en ingles
¿Cómo guardo un cierre en Rust? (1)
Esto es incorrecto : el equivalente directo sería Box<FnMut(uint) -> uint>
. Esto es efectivamente lo que la sintaxis antigua en realidad quería decir.
Corrección : como señaló dbaupp, eso no es correcto. Cierres de estilo antiguo que utilizan el ||
sintaxis eran referencias a cierres almacenados en la pila, haciéndolos equivalentes a &''a mut FnMut(uint) -> uint
. Fueron los proc
que fueron asignados en el heap, y fueron equivalentes a Box<FnOnce(uint) -> uint>
(solo se puede llamar a un proc
una vez). Mis disculpas por el error.
En cuanto a qué tipo usarías en tu tercer fragmento de código, no hay ninguno ; los tipos de cierre son anónimos y no pueden nombrarse directamente. En cambio, escribirías:
let foo = Foo { foo: |x| x + 1 };
Si está escribiendo código en un contexto donde necesita especificar que desea un Foo
, debería escribir:
let foo: Foo<_> = Foo { foo: |x| x + 1 };
_
Le dice al sistema de tipo que infiera el tipo genérico real para usted.
La regla general sobre qué usar, en orden descendente:
- Parámetros genéricos:
struct Foo<F: FnMut(uint) -> uint>
. Este es el más eficiente, pero significa que una instancia específica deFoo
solo puede almacenar un cierre, ya que cada cierre tiene un tipo de concreto diferente. - Referencias de
&''a mut FnMut(uint) -> uint
:&''a mut FnMut(uint) -> uint
. Hay un indirecto de puntero, pero ahora puede almacenar una referencia a cualquier cierre que tenga una firma de llamada compatible. - Cierres en caja:
Box<FnMut(uint) -> uint>
. Esto implica asignar el cierre en el montón, pero no tiene que preocuparse por el tiempo de vida. Al igual que con una referencia, puede almacenar cualquier cierre con una firma compatible.
Solía tener algo como:
struct Foo {
pub foo: |uint| -> uint,
}
Ahora la sintaxis de cierre es obsoleta. Puedo hacer algo como:
struct Foo<F: FnMut(uint) -> uint> {
pub foo: F,
}
Pero entonces, ¿cuál es el tipo de objeto Foo
que creo?
let foo: Foo<???> = Foo { foo: |x| x + 1 };
También podría usar una referencia:
struct Foo<''a> {
pub foo: &''a mut FnMut(uint) -> uint
}
Pero creo que es más lento porque a) el puntero deref, yb) ahora no hay especialización para el tipo de FnMut
que realmente termina siendo utilizado.