在Erlang中将布尔赋值给原子或变量

在Erlang中将布尔赋值给原子或变量,erlang,boolean,variable-assignment,Erlang,Boolean,Variable Assignment,我刚刚学会了编程,对Java感到很舒服。。。目前为止但现在我在学校有一个作业,我们在那里使用Erlang。我有一些问题 因此,我有3个简单(我认为)的问题: 我想像在Java中那样为变量(或atom?)分配一个布尔值。这可能吗 在我下面的代码中,checkTheExistance函数返回一个元组{State,boolean}。接下来我将把它分配给另一个元组:{NextState,DoExist}是否正确?我可以把布尔值放在DoExist中吗 然后,我想检查case语句中的布尔值。并根据布尔值做一

我刚刚学会了编程,对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
      

    您的问题和片段同时涉及几个方面。下面的解释是曲折的,最终会得到答案,到时候你可能已经知道答案了

    第一:风格

    我们不在Erlang中使用camelCaseNames,因为大写和小写名称之间有具体的语义区别。因此,Java将函数命名为
    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),
    
    这将强制对返回的元组的形状进行断言匹配,然后对atom
    ok
    ,然后将读取文件的内容分配给变量名(标签)
    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中闲逛,看看什么是有意义的,什么是没有意义的