在Erlang中将布尔赋值给原子或变量
我刚刚学会了编程,对Java感到很舒服。。。目前为止但现在我在学校有一个作业,我们在那里使用Erlang。我有一些问题 因此,我有3个简单(我认为)的问题:在Erlang中将布尔赋值给原子或变量,erlang,boolean,variable-assignment,Erlang,Boolean,Variable Assignment,我刚刚学会了编程,对Java感到很舒服。。。目前为止但现在我在学校有一个作业,我们在那里使用Erlang。我有一些问题 因此,我有3个简单(我认为)的问题: 我想像在Java中那样为变量(或atom?)分配一个布尔值。这可能吗 在我下面的代码中,checkTheExistance函数返回一个元组{State,boolean}。接下来我将把它分配给另一个元组:{NextState,DoExist}是否正确?我可以把布尔值放在DoExist中吗 然后,我想检查case语句中的布尔值。并根据布尔值做一
handle(State, {join, Pid, Channel}) ->
{NextState, DoExist} = checkTheExistance(Channel, State),
case {NextState, DoExist} of
{_,false} -> startChannel(Channel),
{_,true} -> genserver:request(Channel, {join, Pid})
end
{reply, ok, NextState};
- 您可以将布尔值指定给变量,但不能“指定”原子,因为原子已经是atom类型的值。顺便说一下,Erlang没有布尔类型,true和false是用于此目的的两个普通原子
- 将{State,Boolean}赋值给{NextState,DoExist}是合法的。这是模式匹配的一个很好的例子。这样做可以验证答案是一个2项元组,并分配变量NexState和DoExist
- 案例陈述也是合法的,但由于您忽略了案例中的NexState一词,您可以写:
case DoExist of false -> startChannel(Channel), true -> genserver:request(Channel, {join, Pid}) end
someFunctionName
的习惯变成了somefunction\u name
第二:状态更改
通常,我们不会在检查期间更改任何状态。支票是支票,状态变更是状态变更。两者不应混为一谈。这就是为什么我们将单赋值作为一种语言规则的部分原因——因此,当您看到范围内的变量名时,您看到的是一个标签,而不是指向存储位置的指针。在单个作用域内(一般来说,在函数定义、lambda或列表理解中,不能屏蔽外部作用域标签),标签的含义与您所说的完全相同,它在整个函数中的作用没有任何不同
如果要检查某些内容,请检查某些内容,并为检查功能提供其工作所需的内容(通常)仅此而已:
case check_existence(Channel, State) of
exists -> something(State);
does_not_exist -> something_else(State)
end,
或者,比较差异:
case check_existence(Channel, State) of
true -> something(State);
false -> something_else(State)
end,
刚才发生了什么事?我们返回了原子。这有点像返回一个字符串,但在类型规范方面效率更高而且完全明确。事实上,原子是它们自己的类型,它们的意思完全是它们所说的,在程序中没有更多的含义
所以Erlang中的布尔值是true
和false
——它们是原子。它们的意思正好是“真”和“假”,就像有模糊的鼻子一样
如果在程序中有意义的话,它的意思正好是“有模糊的鼻子”。有些函数接受原子的“真”和“假”,当然,布尔运算符也接受这些值,但没有什么使它们与语言中的任何其他原子不同。在Erlang中,您可以创建更多的复数逻辑布尔(有时这非常有用),例如可能
,有
,缺少
,不完整
,下一步
,结束
等等
第三:=
是赋值和断言
Erlang程序的每一行通常是一个赋值或一个值的断言(匹配)。这里的要点是要始终知道,您正在处理好的数据,如果您没有处理好,就会崩溃。这方面的一个很好的例子是包装的值,您将看到到处都是。典型的例子是具有副作用的任何函数,通常返回{ok,Value}
或{error,Reason}
在代码中处理此问题的典型方法是执行以下操作:
{ok, Data} = file:read_file(FileName),
这将强制对返回的元组的形状进行断言匹配,然后对atomok
,然后将读取文件的内容分配给变量名(标签)Data
——假设在当前执行范围内尚未分配数据。在这种情况下,如果file:read_file/1
返回了{error,Reason}
,进程就会立即崩溃
为什么?
因为在标准情况下,我们完全无法控制为什么像文件这样的外部资源可能不可用——而且需要数千行代码才能正确处理错误。因此,我们只是在那里崩溃,知道我们没有继续使用坏数据
那么关于这些作业…
我们刚刚看到了一个赋值,同时也看到了一个断言。完全有可能做这样更复杂的事情:
Value = file:read_file(FileName),
case Value of
{ok, Data} -> do_stuff(Data);
{error, Reason} -> report_error_and_die(Reason)
end.
MyList = [1,2,3,4],
Result = lists:member(2, MyList),
case Result of
true -> io:format("In the list.~n");
false -> io:format("Not in the list.~n")
end.
这将以更大的复杂性代价实现基本相同的效果。将此(无用的复杂)版本与以下版本(语义相同但更无用的复杂)进行比较:
现在,记住布尔值true
和false
仅仅是原子,完全可以将lists:member/2
的布尔返回值指定给变量名Result
,如下所示:
Value = file:read_file(FileName),
case Value of
{ok, Data} -> do_stuff(Data);
{error, Reason} -> report_error_and_die(Reason)
end.
MyList = [1,2,3,4],
Result = lists:member(2, MyList),
case Result of
true -> io:format("In the list.~n");
false -> io:format("Not in the list.~n")
end.
但更简洁的做法是:
MyList = [1,2,3,4],
case lists:member(2, MyList) of
true -> io:format("In the list.~n");
false -> io:format("Not in the list.~n")
end.
因为我们实际上不需要在任何地方记住这个名字
结束时…
希望这能解释更多,而不是混淆。您现在要做的最重要的事情可能是在vim和erl shell中闲逛,看看什么是有意义的,什么是没有意义的