functional-programming - "pin"运算符的用途是什么?Elixir 变量是否可变?

标签 functional-programming erlang variable-assignment immutability elixir

目前正在尝试理解 Elixir 中的“^”运算符。 来自网站:

The pin operator ^ can be used when there is no interest in rebinding a variable but rather in matching against its value prior to the match:

来源 - http://elixir-lang.org/getting_started/4.html

考虑到这一点,您可以为符号附加一个新值,如下所示:

iex> x = 1  # Outputs "1"
iex> x = 2  # Outputs "2"

我还可以:

iex> x = x + 1  # Outputs "3"!

所以我的第一个问题是; Elixir 变量是可变的吗? 如果是这样的话,看起来确实如此......这在函数式编程语言中不应该是可能的吗?

现在我们来看看“^”运算符...

iex> x = 1  # Outputs "1"
iex> x = 2  # Outputs "2"
iex> x = 1  # Outputs "1"
iex> ^x = 2 # "MatchError"
iex> ^x = 1  # Outputs "1"

我认为“^”的作用是将“x”锁定到与其绑定(bind)的最后一个值。这就是全部内容了吗? 为什么不像 Erlang 本身一样确保所有“匹配”/赋值都是不可变的呢?

我刚刚习惯了......

最佳答案

Elixir 中的数据仍然是不可变的,但有一些简写,可以让您减少输入次数,或者不用担心找到新名称。在 Erlang 中,你经常会看到这样的代码:

SortedList = sort(List),
FilteredList = filter(SortedList),
List3 = do_something_with(FilteredList),
List4 = another_thing_with(List3)

在 Elixir 中,你可以这样写:

list = sort(list)
list = filter(list)
list = do_something_with(list)
list = another_thing_with(list)

这完全一样,但看起来更好一点。当然最好的解决方案是这样写:

list |> sort |> filter |> do_something |> another_thing_with

每次,您将新事物分配给 list 变量时,您都会获得新实例:

iex(1)> a = 1
1
iex(2)> b = [a, 2]
[1, 2]
iex(3)> a = 2
2
iex(4)> b
[1, 2] # first a did not change, it is immutable, currently a just points to something else

你只是说,你不再对旧的a感兴趣并让它指向其他东西。如果您有 Erlang 背景,您可能知道 shell 中的 f 函数。

A = 1.
f(A).
A = 2.

在 Elixir 中,您不必编写 f。它会自动为您完成。这意味着,每次模式匹配左侧有变量时,都会为其分配新值。

如果没有 ^ 运算符,您将无法在模式匹配的左侧拥有变量,因为它将从右侧获取新值。 ^ 表示不要为该变量分配新内容 - 将其视为文字值

这就是 Elixir 的原因

x = 1
[1, x, 3] = [1, 2, 3]

在 Erlang 中相当于:

X = 1,
[1, CompletelyNewVariableName, 3] = [1, 2, 3]

和:

x = 1
[1, ^x, 3] = [1, 2, 3]

相当于:

x = 1
[1, 1, 3] = [1, 2, 3]

在 Erlang 中是:

X = 1,
[1, X, 3] = [1, 2, 3]

关于functional-programming - "pin"运算符的用途是什么?Elixir 变量是否可变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27971357/

相关文章:

scala - 在具有开始和结束时间的元组列表中查找空区间的功能方法

c++ 隐式复制构造函数是否复制数组成员变量?

for循环内的计数器没有给出预期的输出

c - 当我想在 C 中设置指向 NULL 的指针时,如何修复不兼容类型错误?

erlang - 为什么 Dialyzer 无法捕获这个简单的错误?

scala - 如何使有状态 API 变得纯粹

javascript - 在 JavaScript 中将函数映射到生成器

recursion - 标准 ML 斐波那契溢出

java - 在 Java/Scala 中重现 CouchDB 1.2.0 密码哈希函数

erlang - 使用 Erlang 管理程序时,我可以执行代码来响应子进程的退出吗?