2010-10-17 23 views
12

Necesito saber un nombre correcto para esta genial función que ofrecen algunos idiomas.¿Cuál es el nombre de una función [foo, bar] = ["foo", "bar"]?

FYI: En algunos idiomas es posible hacer una asignación múltiple asignando una estructura de valores a una estructura de "variables". En el ejemplo del título de la pregunta, asigna "foo" a foo y "bar" a la barra.

+0

Función interesante? De Verdad? Nunca había escuchado sobre eso antes pero lo encuentro solo confuso. Pronto necesitaremos algunas herramientas para hacer que el código "programable sea legible". – Damien

+8

@Damien: Wow, forma de reaccionar de forma exagerada. –

+8

@Damien: [blub] (http://www.paulgraham.com/avg.html) mucho? –

Respuesta

22

Se llama generalmente desestructuración unen en los lenguajes funcionales (que no hacer han asignaciones) y asignación de desestructuración en idiomas imperativos.

Algunos idiomas proporcionan subconjuntos de esa característica y luego la llaman algo diferente. Por ejemplo, en Python funciona con tuplas, listas o secuencias y se llama Tupla desembalaje, Lista de desembalar o Secuencia desembalaje, en Ruby, funciona con matrices (u objetos que sean convertibles a un array) y es llamada asignación en paralelo.

Destructuring bind puede ser arbitrariamente complejo. P.ej. este (imaginario) se unen

[Integer(a), b, 2, c] = some_array 

sería asignar el primer elemento de some_array a a, el segundo elemento a b y el cuarto elemento de c, pero solamente si el primer elemento es un Integer, el tercer elemento es igual a 2 y la longitud es 4. Por lo tanto, esto incluso incorpora alguna lógica condicional.

bind desestructurada es un subconjunto de más general coincidencia de patrones, que es una característica estándar de los lenguajes funcionales como Haskell, ML, OCaml, F #, Erlang y Scala. La diferencia es que el enlace de desestructuración solo permite desmantelar una estructura y vincular sus componentes a variables, mientras que la coincidencia de patrones también coincide con los valores dentro de esas estructuras y le permite tomar decisiones y, en particular, permite ejecutar código arbitrario en el contexto de las vinculaciones. (Puede ver el enlace imaginario anterior a mitad de camino entre el enlace desestructurado y la coincidencia de patrones.)

Aquí está el ejemplo clásico de una función reverse en un lenguaje imaginario, escrito usando la coincidencia de modelos:

def reverse(l: List): List { 
    match l { 
    when []    { return [] } 
    when [first :: rest] { return (reverse(rest) :: first) } 
    } 
} 
+0

En realidad, en Python, funciona para cualquier secuencia. –

+0

@Matthew Flaschen: Gracias. Agregué * Sequence Unpacking * y dejé caer la palabra "solo" de la descripción. –

+0

Debería haber sido más claro en mi respuesta (actualizada) y en el comentario. Las tuplas y las listas son tipos particulares de secuencia en Python, por lo que el desempaquetado de tuplas y el desempaquetado de listas son solo casos especiales de desempaquetado de secuencias. –

2

Si ve el lado derecho como una tupla, podría ver la asignación como un tipo de Tuple Unpacking.

4

Se llama asignación paralelo en Ruby y otros idiomas.

3

Perl y PHP llaman asignación lista

Perl:

my ($foo, $bar, $baz) = (1, 2, 3); 

PHP:

list($foo, $bar, $baz) = array(1, 2, 3); 
2

En Erlang se ... bueno, no es tarea, que es la coincidencia de patrones (ya que no hay ninguna asignación, como tal, en Erlang).

$ erl 
Erlang R14B (erts-5.8.1) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:true] 

Eshell V5.8.1 (abort with ^G) 
1> [H1, H2, H3| Rest] = [1,2,3,4,5]. 
[1,2,3,4,5] 
2> H1. 
1 
3> H2. 
2 
4> H3. 
3 
5> Rest. 
[4,5] 

¿Por qué se llama "coincidencia de patrón"? Porque en realidad está combinando patrones. Mira:

6> [1,2,3,4,A] = [1,2,3,4,5]. 
[1,2,3,4,5] 
7> A. 
5 
8> [1,2,3,4,A] = [1,2,3,4,6]. 
** exception error: no match of right hand side value [1,2,3,4,6] 

En el primero hicimos lo que equivale en realidad a una afirmación de que la lista sería comenzar con [1,2,3,4] y que el quinto valor podría ser cualquier cosa, pero por favor, que se unen en la variable no unido A. En el segundo caso, hicimos lo mismo, excepto que A está ahora vinculado, por lo que estamos buscando explícitamente la lista [1,2,3,4,5] (porque A ahora es 5).

2

En Clojure se llamaría desestructuración. Ejemplo simple:

(let [[foo bar] ["foo" "bar"]] 
    (println "I haz" foo "and" bar)) 

También se usa a menudo en las definiciones de funciones, p. Ej. la siguiente desestructura un argumento único punto en componentes x e y:

(defn distance-from-origin [[x y]] 
    (sqrt (+ (* x x) (* y y)))) 

También se puede utilizar la misma técnica para desestructurar estructuras de datos anidadas o mapas clave asociativos/valor.

Cuestiones relacionadas