web-dev-qa-db-fra.com

Listes d'élixir interprétées comme des listes de caractères

Je commence juste avec Elixir. J'écris des tests en utilisant ExUnit pour des fonctions énumérables simples que j'implémente moi-même, sans utiliser le module Enum standard.

Dans mes tests, je trouve que chaque fois que je fais référence à la liste [7, 8, 9], une fois imprimé dans stdout, je vois la liste des caractères '\a\b\t'. Pourquoi ce genre de chose se produit-il?

46
George Taveras

Elixir a deux types de chaînes: les binaires (entre guillemets doubles) et les listes de caractères (entre guillemets simples). Cette dernière variante est héritée d'Erlang et est représentée en interne sous la forme d'une liste d'entiers, qui correspondent aux points de code de la chaîne.

Lorsque vous utilisez des fonctions comme inspect et IO.inspect, Elixir essaie d'être intelligent et de formater une liste d'entiers sous forme de chaîne pour une lisibilité facile. Cependant, dans certains cas, vous vous retrouvez avec une chaîne non-sens simplement parce que tous les entiers de votre liste sont des points de code valides. Par exemple, les caractères A à Z sont représentés par les entiers 65 à 90 en ASCII.

iex> IO.inspect [65, 66, 67]
'ABC'

Si vous souhaitez imprimer une liste brute, vous pouvez utiliser le charlists: :as_lists option. Pour une liste complète des options, lancez iex et tapez h Inspect.Opts.

iex> IO.inspect [65, 66, 67], charlists: :as_lists
[65, 66, 67]

Avec Elixir <1.4, vous pouvez utiliser char_lists: false.

Soit dit en passant, ce n'est pas le seul cas où Elixir vous cache les blocs de construction sous-jacents, cela se produit également avec les binaires (chaînes entre guillemets doubles) et les structures.

La raison la plus profonde à cela est qu'Elixir et Erlang n'ont pas de types définis par l'utilisateur, il n'y a donc aucun moyen de faire la distinction entre une liste et une seule chaîne entre guillemets, car les deux ne sont que des listes. Cependant, cela peut également être une force dans d'autres situations. Par exemple, cela nous permet de sérialiser trivialement n'importe quelle structure de données dans Elixir et Erlang, car elle ne peut être construite qu'à partir des blocs de construction de base fournis avec le langage.

78
Patrick Oscity

Bien que la réponse de @ Patrick soit absolument correcte, vous pouvez également configurer IEx pour toujours afficher charlists en tant que listes régulières au lieu d'appeler manuellement inspect à chaque fois:

iex> IEx.configure(inspect: [charlists: :as_lists])
# => :ok

iex> [65, 66, 67]
# => [65, 66, 67]

iex> 'ABC'
# => [65, 66, 67]

Voici un liste complète des options prises en charge

10
Sheharyar