2015-09-27 12 views
26

Nuovo per Elixir da Ruby e sto cercando di stampare i valori di matrice di una mappa utilizzando il seguente codice:Come stampare i valori degli array di una mappa in Elixir?

mappa-script.ex

list = [0, 1] 
map = %{0 => [1, 2], 1 => [2, 3]} 

Enum.each list, fn n -> 
    IO.puts map[n] 
end 

uscita:

^A^B 
^B^C 

Cosa sto sbagliando? Elixir è simile a Ruby, ma si comporta in modo diverso ....

+4

È un grosso errore ritenere che, poiché l'elisir ha l'aspetto di Ruby, si comporterà anche come Ruby. –

risposta

59

si dovrebbe usare IO.inspect invece di IO.puts per stampare la rappresentazione interna di un valore:

iex> IO.puts [1, 2] 
^A^B       # prints "^A^B" 
:ok       # return value of IO.puts 

iex> IO.inspect [1, 2] 
[1, 2]      # prints "[1, 2]" 
[1, 2]      # return value of IO.inspect 

Tuttavia si potrebbe comunque ottenere problemi con alcuni valori speciali :

iex> IO.inspect [97, 98] 
'ab'       # prints "'ab'" 
'ab'       # return value of IO.inspect 

Per spiegare questo comportamento, è necessario capire come funzionano le stringhe in elisir. Ci sono due tipi di stringhe. Stringhe binarie (doppie virgolette) e liste di caratteri (quotate singole). Internamente, sono costruiti da primitive più semplici. stringhe binarie sono costruiti da binari, e le liste dei personaggi sono costruiti sulla base di liste:

iex> "ab"     # a binary string 
"ab" 

iex> <<97, 98>>    # the same string in binary syntax 
"ab" 

iex> 'ab'     # a character list 
'ab' 

iex> [97, 98]    # the same character list in list syntax 
'ab' 

Potrebbe sembrare confuso in un primo momento, ma questo accade a causa di due cose. Innanzitutto, non esiste un tipo di stringa incorporato, poiché le stringhe sono state create da altri tipi primitivi. Secondo, non ci sono tipi definiti dall'utente in elisir. Quindi, quando Elixir vede una lista con solo numeri interi, prova a stamparla come stringa per comodità. Tuttavia, sotto il cofano è ancora solo una lista di numeri interi.

Negli esempi sopra, 97 e 98 rappresentano i punti di codice unicode per i caratteri a e b così questi verranno visualizzati come una stringa, anche se si utilizza IO.inspect.

Ora si può vedere perché stampato ^A^B nei tuoi esempi - questi sono solo control characters from the ASCII encoding, che capita di essere rappresentato dalle codepoints 1 e 2.

Tuttavia, è possibile passare l'opzione char_lists: :as_lists al fine di stampare gli elenchi prime, senza un tentativo di fare una conversione:

iex> IO.inspect [97, 98], char_lists: :as_lists 
[97, 98]           # prints '[97, 98]' 
'ab'            # Iex still shows the return value as 'ab' 

Se aprite iex e digita h Inspect.Opts, si vedrà che Elixir fa questo tipo di cosa con altri valori, in particolare struct e binari.

+0

@ patrick-oscity Ottima risposta .. davvero chiaro come le cose sono implementate. Comunque mi piacerebbe chiedere, perché non c'è un tipo String incorporato .. lo implementeranno o è in modo elisir ...? – VoidZero

+1

@VoidZero è qualcosa che è sepolto nel profondo della VM di erlang, quindi non cambierà probabilmente. Detto questo, le stringhe binarie funzionano molto bene, quindi non c'è praticamente bisogno di qualcosa di diverso. –

Problemi correlati