问题
I am writing a program that can have either a list or a string as an argument. How can I tell the difference between a string and a list programmatically in Erlang. Something like:
print(List) -> list;
print(String) -> string.
回答1:
io_lib:printable_list might be what you are looking for. However it doesn't handle unicode only latin-1 encodings. If you need to detect unicode strings I think you might be out of luck. The best bet is pseudo typing your lists like so: {string, [$a, $b, $c]}. Kind of a build your types.
use a constructor like so string(L) when is_list(L) -> {string, L}.
and just use that typing construct all through your app.
On the other hand you could just treat all strings as just lists and not make the distinction.
回答2:
Best thing what you can do is tagging your structures as Jeremy Wall suggested. Anyway you can decide check input to your module/subsystem/application/...
is_string([]) -> true;
is_string([X|T]) -> is_integer(X) andalso X>=0 andalso is_string(T);
is_string(_) -> false.
Unfortunately it is expensive operation and you can't use it in guards.
回答3:
Erlang implements different functions to test if a list is a flat list in module io_lib. Despite Jeremy Wall comment there is a function to test if a flat list contains unicode characters as well as latin1 version.
If you want to test for flat unicode lists you can use io_lib:char_list(Term) http://erlang.org/doc/man/io_lib.html#char_list-1
io_lib:char_list/1 function implementation is:
char_list([C|Cs]) when is_integer(C), C >= 0, C < 16#D800;
is_integer(C), C > 16#DFFF, C < 16#FFFE;
is_integer(C), C > 16#FFFF, C =< 16#10FFFF ->
char_list(Cs);
char_list([]) -> true;
char_list(_) -> false.
One good choice for checking latin1 encoded strings is io_lib:latin1_char_list(Term) http://erlang.org/doc/man/io_lib.html#latin1_char_list-1
io_lib:latin1_char_list/1 function implementation is:
latin1_char_list([C|Cs]) when is_integer(C), C >= $\000, C =< $\377 ->
latin1_char_list(Cs);
latin1_char_list([]) -> true;
latin1_char_list(_) -> false.
Check the io_lib module documentation for other similar functions.
回答4:
Why would you need to separate these? Strings are lists in erlang (most of the time).
来源:https://stackoverflow.com/questions/2479713/determining-if-an-item-is-a-string-or-a-list-in-erlang