Variable in Erlang

2019-07-04 02:56发布

I have a very simple Erlang program:

-module(test).
-export([start/0]).

Code = "Z00887". 
start() -> io:fwrite(Code).

And I have follows two errors:

c:/erl6.1/dev/test.erl:4: syntax error before: Code
c:/erl6.1/dev/test.erl:5: variable 'Code' is unbound

Could you please help me correctly using variables in my code.

标签: erlang
1条回答
我只想做你的唯一
2楼-- · 2019-07-04 03:28

You are defining a variable that is global to the module, which is not allowed. Remember, "variables" in Erlang are really "symbols", so there is no concept of a "global" constant across all functions or processes. The closest thing to this in Erlang would be a macro defined in the module, but if a value is only needed in one place and you want to name it then this must be done within the function definition.

Also, do not use io:fwrite/1 or io:format/1. The problem is the possible inclusion of escape characters in the string you are passing. For example, this causes an error: Code = "Wee~!", io:format(Code). and it will not be caught by the compiler.

The most common thing to do is define a variable within the function:

-module(foo).
-export([start/0]).

start() ->
    Code = "Z00887",
    io:fwrite("~p~n", [Code]).

You could also just use the value directly:

-module(foo).
-export([start/0]).

start() ->
    io:fwrite("Z00887~n").

Or you could define a macro across the whole module:

-module(foo).
-export([start/0]).

-define(CODE, "Z00887").

start() ->
    io:fwrite("~p~n", [?CODE]).

Or you could even define a stub function that returns what you want:

-module(foo).
-export([start/0]).

start() ->
    io:fwrite("~p~n", [code()]).

code() -> "Z00887".

This last version is actually not as weird as it may seem at first. Very often when developing some code early on you will know you need a value somewhere that you will need to derive in some way, but don't want to worry about the details of it just yet. A stub function is an excellent way to hide the details of how you will do that in the future without writing macro code, variable definitions, etc. that you will have to remember to go back and change later. For example, the last example above will almost certainly change to something like this in the future:

-module(foo).
-export([start/0]).

start() ->
    io:fwrite("~p~n", [code()]).

code() ->
    {ok, Code} = some_init_module:get_code(),
    Code.

Keep this in mind. It makes Erlang almost as prototype-friendly as Guile or Scheme.

查看更多
登录 后发表回答