2014-05-13 11 views
7

In lingue tipizzate staticamente con generici, come C#, posso specificare nella firma del metodo che ciascuna delle chiavi della mappa è un atomo e ogni valore è un elenco di {string, int} tuple. Come definisco la specifica del tipo per argomenti di funzioni come quella in Elixir?elisir: definizione delle specifiche del tipo per mappe/hashdicts

PS: se stai leggendo questo e hai una valutazione> 1500, potresti creare un tag di specifica del tipo.

+0

Non ho familiarità con elisir, ma sostiene di essere un "linguaggio dinamico", che di solito significa che non ha un sistema di tipo formale. Quindi ... usa un commento? – luqui

+4

ha specifiche di tipo, che possono essere utilizzate dallo strumento di analisi statico Dialyzer - http://elixir-lang.org/docs/stable/Kernel.Typespec.html – tldr

risposta

12

Si potrebbe definire in questo modo:

@type bar :: %{atom => [{binary, integer}]} 

@spec foo(bar) :: bar 
def foo(bar), do: bar 

È possibile che definisce un nuovo tipo, che è la vostra mappa di chiavi atomo a liste di tuple/intero binario, e poi usa quel tipo nel tipo specifiche per foo.

+0

solo per sicurezza, devo specificarlo come tipo in anticipo, non posso semplicemente metterlo in linea? In tal caso, dovrei conservare tutti i miei tipi personalizzati in un modulo separato e solo importarli, per evitare di incollare la definizione del tipo in più moduli? – tldr

+2

Si può definitivamente in linea, ma trovo difficile da leggere se si dispone di più tipi complessi tutti in linea. È anche un po 'più esplicito su * cosa * il tipo è, piuttosto che solo la struttura di esso. Puoi definire i tipi in altri moduli e usarli tramite 'Module.type_name'. – bitwalker

+0

grandioso, grazie! In questo senso, l'analisi statica di Elixir è più granulare di quella di Go poiché Go non ti consente di definire funzioni che accettano i tuoi tipi personalizzati come argomenti. (Ignora se non hai usato Go) – tldr

1

Per linea spec va in questo modo:

defmodule LousyCalculator do 
    @spec add(number, number) :: {number, String.t} 
    def add(x, y), do: {x + y, "You need a calculator to do that?!"} 

    @spec multiply(number, number) :: {number, String.t} 
    def multiply(x, y), do: {x * y, "Jeez, come on!"} 
end 

Se vi aspettate una struttura quindi il tipo è:

@spec struct_returner_and_getter(%Struct_name1{}) :: %Struct_name2{} 

Fonte: http://elixir-lang.org/getting-started/typespecs-and-behaviours.html

Problemi correlati