Tuplas y unidad

Move no es totalmente compatible con tuplas, como cabr铆a esperar si provienen de otro idioma y las tienen como valor de primera clase . Sin embargo, para admitir m煤ltiples valores de retorno, Move tiene expresiones tipo tupla. Estas expresiones no dan como resultado un valor concreto en tiempo de ejecuci贸n (no hay tuplas en el c贸digo de bytes) y, como resultado, son muy limitadas: s贸lo pueden aparecer en expresiones (normalmente en la posici贸n de retorno de una funci贸n); no pueden vincularse a variables locales; no se pueden almacenar en estructuras; y los tipos de tupla no se pueden utilizar para crear instancias de gen茅ricos.

De manera similar, la unidad() es un tipo creado por el lenguaje fuente de Move para estar basado en expresiones. El valor unitario ()no da como resultado ning煤n valor de tiempo de ejecuci贸n. Podemos considerar que la unidad ()es una tupla vac铆a y cualquier restricci贸n que se aplique a las tuplas tambi茅n se aplica a la unidad.

Puede parecer extra帽o tener tuplas en el idioma dadas estas restricciones. Pero uno de los casos de uso m谩s comunes de tuplas en otros lenguajes es que las funciones permitan que las funciones devuelvan m煤ltiples valores. Algunos lenguajes solucionan esto obligando a los usuarios a escribir estructuras que contengan m煤ltiples valores de retorno. Sin embargo, en Move, no puedes poner referencias dentro de estructuras. Esto requer铆a que Move admitiera m煤ltiples valores de retorno. Todos estos m煤ltiples valores de retorno se insertan en la pila en el nivel de c贸digo de bytes. En el nivel de origen, estos m煤ltiples valores de retorno se representan mediante tuplas.

Literales

Las tuplas se crean mediante una lista de expresiones separadas por comas dentro de par茅ntesis.

Sintaxis

Tipo

Descripci贸n

()

(): ()

Unidad, la tupla vac铆a o la tupla de aridad 0

(e1, ..., en)

(e1, ..., en): (T1, ..., Tn)donde e_i: Tist 0 < i <= nyn > 0

Una ntupla, una tupla de arity n, una tupla con nelementos

Tenga en cuenta que (e)no tiene tipo (e): (t), es decir, no hay una tupla con un elemento. Si solo hay un elemento dentro del par茅ntesis, los par茅ntesis solo se usan para desambiguaci贸n y no tienen ning煤n otro significado especial.

A veces, las tuplas con dos elementos se denominan "pares" y las tuplas con tres elementos se denominan "triples".

Ejemplos

Copiar

address 0x42 {
module example {
    // all 3 of these functions are equivalent

    // when no return type is provided, it is assumed to be `()`
    fun returns_unit_1() { }

    // there is an implicit () value in empty expression blocks
    fun returns_unit_2(): () { }

    // explicit version of `returns_unit_1` and `returns_unit_2`
    fun returns_unit_3(): () { () }


    fun returns_3_values(): (u64, bool, address) {
        (0, false, @0x42)
    }
    fun returns_4_values(x: &u64): (&u64, u8, u128, vector<u8>) {
        (x, 0, 1, b"foobar")
    }
}
}

Operaciones

La 煤nica operaci贸n que se puede realizar actualmente con tuplas es la desestructuraci贸n.

Desestructurando

Para tuplas de cualquier tama帽o, se pueden desestructurar en un letenlace o en una asignaci贸n.

Por ejemplo:

Copiar

address 0x42 {
module example {
    // all 3 of these functions are equivalent
    fun returns_unit() {}
    fun returns_2_values(): (bool, bool) { (true, false) }
    fun returns_4_values(x: &u64): (&u64, u8, u128, vector<u8>) { (x, 0, 1, b"foobar") }

    fun examples(cond: bool) {
        let () = ();
        let (x, y): (u8, u64) = (0, 1);
        let (a, b, c, d) = (@0x0, 0, false, b"");

        () = ();
        (x, y) = if (cond) (1, 2) else (3, 4);
        (a, b, c, d) = (@0x1, 1, true, b"1");
    }

    fun examples_with_function_calls() {
        let () = returns_unit();
        let (x, y): (bool, bool) = returns_2_values();
        let (a, b, c, d) = returns_4_values(&0);

        () = returns_unit();
        (x, y) = returns_2_values();
        (a, b, c, d) = returns_4_values(&1);
    }
}
}

Para obtener m谩s detalles, consulte Mover variables.

Subtipificaci贸n

Junto con las referencias, las tuplas son los 煤nicos tipos que tienen subtipos en Move. Las tuplas tienen subtipos s贸lo en el sentido de que subtipos con referencias (de forma covariante).

Por ejemplo:

Copiar

let x: &u64 = &0;
let y: &mut u64 = &mut 1;

// (&u64, &mut u64) is a subtype of (&u64, &u64)
// since &mut u64 is a subtype of &u64
let (a, b): (&u64, &u64) = (x, y);

// (&mut u64, &mut u64) is a subtype of (&u64, &u64)
// since &mut u64 is a subtype of &u64
let (c, d): (&u64, &u64) = (y, y);

// error! (&u64, &mut u64) is NOT a subtype of (&mut u64, &mut u64)
// since &u64 is NOT a subtype of &mut u64
let (e, f): (&mut u64, &mut u64) = (x, y);

Propiedad

Como se mencion贸 anteriormente, los valores de tupla realmente no existen en tiempo de ejecuci贸n. Y actualmente no se pueden almacenar en variables locales debido a esto (pero es probable que esta caracter铆stica est茅 disponible pronto). Como tal, las tuplas s贸lo se pueden mover actualmente, ya que copiarlas requerir铆a colocarlas primero en una variable local.

Last updated