Elixir中等号的确切含义是什么? [英] What is the exact meaning of the equal sign in Elixir?

查看:62
本文介绍了Elixir中等号的确切含义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白Elixir中的等号.尚不清楚的是,它看起来像是分配和模式匹配操作之间的混合体.

I don't get what exactly means the equal sign in Elixir. What is unclear is that it looks like a mix between assignment and a pattern matching operation.

iex(1)> x=4
4
iex(2)> y=5
5
iex(3)> 3=y
** (MatchError) no match of right hand side value: 5

iex(3)> y=3
3
iex(4)> y=x
4

我了解在Elixir中,等于运算符的意思是将=符号的左侧与右侧匹配.前两行对我来说很有意义.x和y是未绑定的变量,因此它们可以匹配任何内容.它们在匹配时受到约束.因此,我了解第三行.您无法将3与5相匹配.

I understand that in Elixir, the equals operator means to match the left side of the = sign to the the right side. First two lines make sense to me. x and y are unbound variables, hence they could match anything. They are bound as they match. Consequently, I understand the third line. You can't match 3 with 5.

我开始放松的地方是为什么在最后两行执行时都没有给出相同的错误.看起来等号又回到了仅作为赋值运算符的地步.

Where I start to loose my head is why the hell the two last lines are executed without giving the same error. It looks like the equal sign is back to being an assignment operator only.

在没有充分理解的情况下,我尝试将这种行为视为事实,并尝试进一步学习该语言.但是,由于模式匹配是Elixir的核心机制之一,因此我不断锁定并感到应该回到最初的问题.在我完全理解"="符号的确切含义以及逻辑之后,我将不做任何进一步的介绍.

I've try to accept this behaviour as a fact without full understanding and tried to go further in the learning of the language. But as pattern matching is one of the core mechanism of Elixir, I'm constantly lock and feel I should go back to this original question. I will not go any further before I fully understand what exactly happens with the "=" sign and what is the logic.

推荐答案

等号表示:尝试将表达式的拟合为形状在左侧并相应地分配值".因此左侧和右侧是不同的,您无法切换它们.在右侧,所有变量都必须绑定,因为它是一个表达式.在左侧,即使您使用已绑定的变量也将被重新分配.

The equals sign means: "try to fit the value of expression on the right to the shape on the left and assigning values accordingly". So left and right side are different and you cannot switch them. On the right side all variables have to be bound, because it is an expression. On the left side even if you use variables that are already bound they will be reassigned.

所以第一件事是,在右边您可以拥有任何想要的表达式:

So first thing is that on the right you can have any expression your want:

{:error, :enoent} = File.open("foo")

但是您不能在左侧使用表达式:

but you can't have an expression on the left side:

iex(1)> File.open("foo") = {:error, :enoent}
** (CompileError) iex:1: cannot invoke remote function File.open/1 inside match

如果是

y=3
5=y # y gets evaluated to 3 and then you pattern match 3=5

,并且失败.但是你可以做

and it fails. But you can do

y=3
y=5 # y gets reassigned.

在左侧,您只能拥有形状",该形状可以是任意嵌套的数据结构:

On the left hand side you can only have "shape" which may be arbitrarly nested datastructure:

[a, b, %{"a" => {1, c}}] = [1, 2, %{"a" => {1, 2}]
# c is now assigned value of 2

因此模式匹配用于分解数据或声明某些条件,例如

So pattern matching is used to either destructure data or to assert some condition like

case File.open("foo") do
  {:ok, contents} -> enjoy_the_file(contents)
  {:error, reason} -> print_error(reason)
end

或者如果您想断言数据库中只有一个实体,而不是先断言它存在然后才可以模式匹配:

or if you want to assert that there is only one entity in the database instead of firstly asserting it exists and then that there is only one you can pattern match:

[entity] = Repo.all(query)

如果要断言列表中的第一个值为1,则可以模式匹配:

If you want to assert that the first value in a list is one, you can pattern match:

[1 | rest] = [1, 2, 3]

模式匹配时有一些陷阱.例如:

There are some gotchas when pattern matching. For example this:

%{} = %{a: "a"}

将匹配,因为左侧的形状是地图,并且您不需要任何其他内容,因此任何地图都将匹配.但这不匹配:

will match, because shape on the left side is a map and you don't require anything more so any map will match. However this won't match:

%{a: "a"} = %{}

因为左侧的形状是给我一张原子键为:a 的地图.

because shape on the left says "give me a map with a key of atom :a.

如果要匹配变量,则可以编写如下内容:

If you would like to match on a variable you may write something like this:

a = 1
{a, b} = {2, 3}

,但这将为 a 分配值2.相反,您需要使用pin运算符:

but this will assign a the value 2. Instead you need to use pin operator:

a = 1
{^a, b} = {2, 3} #match fails

我在此答案中写了更多有关引脚运算符的信息:

I wrote more about pin operator in this answer: What is the "pin" operator for, and are Elixir variables mutable?

这篇关于Elixir中等号的确切含义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆