elixir - palabras - meta tags importantes
¿Cuál es el beneficio de las listas de palabras clave? (3)
El principal beneficio de las listas de palabras clave es la compatibilidad con el elixir existente y la base de código de erlang.
También agregan azúcar sintáctica si se usan como argumentos de funciones que se asemejan, por ejemplo, a una sintaxis de ruby:
def some_fun(arg, opts // []), do: ...
some_fun arg, opt1: 1, opt2: 2
El principal inconveniente de utilizar listas de palabras clave es que no es posible realizar una coincidencia parcial de patrones en ellas:
iex(1)> m = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(2)> %{a: a} = m
%{a: 1, b: 2}
iex(3)> a
1
iex(4)> k = [a: 1, b: 2]
[a: 1, b: 2]
iex(5)> [a: a] = k
** (MatchError) no match of right hand side value: [a: 1, b: 2]
Vamos a extenderlo a los argumentos de la función. Imagine que necesitamos manejar una función de uso múltiple basada en el valor de una de las opciones:
def fun1(arg, opt1: opt1) when is_nil(opt1), do: do_special_thing
def fun1(arg, opts), do: do_regular_thing
def fun2(arg, %{opt1: opt1}) when is_nil(opt1), do: do_special_thing
def fun2(arg, opts), do: do_regular_thing
Esto nunca ejecutará el do_special_thing
:
fun1("arg", opt1: nil, opt2: "some value")
doing regular thing
Con los argumentos del mapa, funcionará:
fun2("arg", %{opt1: nil, opt2: "some value"})
doing special thing
En el elixir tenemos Mapas:
> map = %{:a => "one", :b => "two"} # = %{a: "one", b: "two"}
> map.a # = "one"
> map[:a] # = "one"
También tenemos listas de palabras clave:
> kl = [a: "one", b: "two"] # = [a: "one", b: "two"]
> kl2 = [{:a, "one"},{:b, "two"}] # = [a: "one", b: "two"]
> kl == kl2 # = true
> kl[:a] # = "one"
> kl.a # = ** (ArgumentError)
¿Por qué ambos?
¿Sintaxis? ¿Es porque las listas de palabras clave tienen una sintaxis más flexible que les permite definirse sin curlys e incluso sin corchetes como el último parámetro de una llamada a función? Entonces, ¿por qué no darle a Maps este azúcar sintáctico?
¿Llaves duplicadas? ¿Es porque las listas de palabras clave pueden tener claves duplicadas? ¿Por qué querrías acceso a estilo de mapa y claves duplicadas?
¿Actuación? ¿Es porque las listas de palabras clave tienen un mejor rendimiento? Entonces, ¿por qué tienen Mapas? ¿Y no deberían los mapas ser más eficientes al buscar miembros por clave que una lista de tuplas?
JS Array y Ruby Hash como apariencia? ¿Es asi?
Entiendo que estructuralmente son representaciones de datos diferentes. Para mí, parece que las listas de palabras clave en el elixir sirven para complicar el lenguaje a través de una sintaxis excepcional (3 variantes sintácticas diferentes), usan superposición de casos con mapas y un beneficio poco claro.
¿Cuál es el beneficio de usar listas de palabras clave?
Los mapas solo permiten una entrada para una clave en particular, mientras que las listas de palabras clave permiten que la clave se repita. Los mapas son eficientes (especialmente a medida que crecen), y se pueden usar en la coincidencia de patrones de Elixir.
En general, use listas de palabras clave para cosas tales como parámetros de línea de comandos y para pasar opciones, y use mapas (u otra estructura de datos, HashDict) cuando desee una matriz asociativa.
┌──────────────┬────────────┬───────────────────────┐
│ Keyword List │ Map/Struct │ HashDict (deprecated) │
┌──────────────────┼──────────────┼────────────┼───────────────────────┤
│ Duplicate keys │ yes │ no │ no │
│ Ordered │ yes │ no │ no │
│ Pattern matching │ yes │ yes │ no │
│ Performance¹ │ — │ — │ — │
│ ├ Insert │ very fast² │ fast³ │ fast⁴ │
│ └ Access │ slow⁵ │ fast³ │ fast⁴ │
└──────────────────┴──────────────┴────────────┴───────────────────────┘
Las listas de palabras clave son livianas y tienen una estructura simple debajo de ellas, lo que las hace muy flexibles. Puedes pensar en ellos como azúcar de sintaxis sobre una convención de Erlang, lo que facilita la interfaz con Erlang sin escribir un código demasiado feo. Por ejemplo, las listas de palabras clave se utilizan para representar argumentos de función, que es una propiedad heredada de Erlang. En algunos casos, las listas de palabras clave son su única opción, especialmente si necesita duplicar claves u ordenarlas. Simplemente tienen diferentes propiedades que las otras alternativas, lo que las hace más adecuadas para algunas situaciones y menos para otras.
Los mapas (y las estructuras) se utilizan para almacenar datos reales de carga, ya que tienen una implementación basada en hash. Las listas de palabras clave internamente son solo listas que deben atravesarse para cada operación, por lo que no tienen las propiedades de las estructuras de datos de clave-valor clásicos, como el acceso de tiempo constante.
Elixir también introdujo HashDict
como una solución para el mal rendimiento de los mapas en el momento en que fue escrito . Sin embargo, esto se soluciona ahora a partir de Elixir 1.0.5 / Erlang 18.0 y HashDict
quedará obsoleto en futuras versiones .
Si profundiza en la biblioteca estándar de Erlang, existen aún más estructuras de datos que almacenan pares clave / valor:
- proplists : similar a las listas de palabras clave de Elixir
- maps : igual que los mapas de Elixir
- dict - diccionarios de valores-clave construidos a partir de primitivas de Erlang
- gb_trees - árbol general equilibrado
También tiene estas opciones cuando necesita almacenar pares clave / valor en múltiples procesos y / o máquinas virtuales:
¹ Hablando en general, pero por supuesto depende ™.
² El mejor caso es simplemente anteponerse a una lista.
³ Se aplica a Elixir 1.0.5 y superior, puede ser más lento en versiones anteriores.
⁴ HashDict
ahora está en desuso.
⁵ Requiere una búsqueda lineal que en promedio escanea la mitad de los elementos.