Determining if an item is a string or a list in Erlang

耗尽温柔 提交于 2019-12-23 10:54:11

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!