为什么我的 Elixir 函数返回一个列表列表?
Why is my Elixir function returning a list of lists?
我有一个由函数 make_struct
编辑的结构 return 完全像这样:
%Example.Struct{example: 1, example_again: 2}
(即不带括号,如:[ %Example... ]
),至少我认为它像上面那样 return,但是函数在 GenServer 模块中,有时我注意到我的函数 return出于某种我不理解的原因在列表中输入一个值?
我想要return这些结构的列表:
def foo(data_as_a_list) do
my_list = []
for entry <- data_as_a_list do
my_list = [ make_struct(entry) | my_list ]
end
end
这是return结构列表,每个结构都在列表中:
[
[
%Example.Struct{example: 1, example_again: 2}
],
[
%Example.Struct{example: 1, example_again: 2}
]
]
我只想:
[
%Example.Struct{example: 1, example_again: 2},
%Example.Struct{example: 1, example_again: 2}
]
Elixir 的 for
不像大多数语言的 for
循环那样工作 - 它们是理解,而不是循环。我建议阅读 the Elixir guide's page on it.
理解已经return一个列表(默认情况下;当指定:into
时可能是另一个Collectable
),其中包含return的每次执行12=] 的 do
块。它在简单情况下就像 Enum.map
一样。所以你可以使用其中任何一个来获得你想要的结果:
def foo(data_as_a_list) do
for entry <- data_as_a_list do
make_struct(entry)
end
end
def foo(data_as_a_list) do
Enum.map(data_as_a_list, &make_struct/1)
end
我认为第二个更加地道,因为 map
ping 函数非常常见。理解主要用于当您有更复杂的需求时。
您的代码中有几点需要指出。
- 您正在做的是分配
my_list = []
然后使用 for
更新 my_list
的想法是错误的。
这在语法上并没有错,这就解释了为什么您没有收到错误消息,而是把事情搞混了。
Elixir 中的东西是不可变的。这意味着在您的 for
中,您并不是真正地更新 my_list
,而是在每个“迭代”上定义新的 my_list
,这些迭代的范围是 for
构造并且什么都没有处理它之外的事情。
当你运行像a = 2
在iex
你得到回来2
,因为“赋值”returns赋值。或者因为结果是最后计算的结果,即 2
.
考虑到这一点,您的代码相当于:
def foo(data_as_a_list) do
my_list = []
for entry <- data_as_a_list do
[ make_struct(entry) | my_list ]
end
end
Notice, however, that because things are immutable, every time [ make_struct(entry) | my_list ]
is read, my_list
equals []
. Both in the updated and in your original code.
在 Elixir 中,for
不只是循环遍历事物,而是生成一个列表,其中包含对事物的操作结果。最简单的示例是:for i <- 1..5, do: i
生成 [1, 2, 3, 4, 5]
,尽管事先没有正式的列表或在 for
构造中更新列表。
考虑到这两点,如果您想要的是在 data_as_a_list
的每个项目上获得一个调用 make_struct
的列表,您可以使用 for
实现它与:
def foo(data_as_a_list) do
for entry <- data_as_a_list do
make_struct(entry)
end
end
我有一个由函数 make_struct
编辑的结构 return 完全像这样:
%Example.Struct{example: 1, example_again: 2}
(即不带括号,如:[ %Example... ]
),至少我认为它像上面那样 return,但是函数在 GenServer 模块中,有时我注意到我的函数 return出于某种我不理解的原因在列表中输入一个值?
我想要return这些结构的列表:
def foo(data_as_a_list) do
my_list = []
for entry <- data_as_a_list do
my_list = [ make_struct(entry) | my_list ]
end
end
这是return结构列表,每个结构都在列表中:
[
[
%Example.Struct{example: 1, example_again: 2}
],
[
%Example.Struct{example: 1, example_again: 2}
]
]
我只想:
[
%Example.Struct{example: 1, example_again: 2},
%Example.Struct{example: 1, example_again: 2}
]
Elixir 的 for
不像大多数语言的 for
循环那样工作 - 它们是理解,而不是循环。我建议阅读 the Elixir guide's page on it.
理解已经return一个列表(默认情况下;当指定:into
时可能是另一个Collectable
),其中包含return的每次执行12=] 的 do
块。它在简单情况下就像 Enum.map
一样。所以你可以使用其中任何一个来获得你想要的结果:
def foo(data_as_a_list) do
for entry <- data_as_a_list do
make_struct(entry)
end
end
def foo(data_as_a_list) do
Enum.map(data_as_a_list, &make_struct/1)
end
我认为第二个更加地道,因为 map
ping 函数非常常见。理解主要用于当您有更复杂的需求时。
您的代码中有几点需要指出。
- 您正在做的是分配
my_list = []
然后使用for
更新my_list
的想法是错误的。
这在语法上并没有错,这就解释了为什么您没有收到错误消息,而是把事情搞混了。
Elixir 中的东西是不可变的。这意味着在您的 for
中,您并不是真正地更新 my_list
,而是在每个“迭代”上定义新的 my_list
,这些迭代的范围是 for
构造并且什么都没有处理它之外的事情。
当你运行像a = 2
在iex
你得到回来2
,因为“赋值”returns赋值。或者因为结果是最后计算的结果,即 2
.
考虑到这一点,您的代码相当于:
def foo(data_as_a_list) do
my_list = []
for entry <- data_as_a_list do
[ make_struct(entry) | my_list ]
end
end
Notice, however, that because things are immutable, every time
[ make_struct(entry) | my_list ]
is read,my_list
equals[]
. Both in the updated and in your original code.
在 Elixir 中,for
不只是循环遍历事物,而是生成一个列表,其中包含对事物的操作结果。最简单的示例是:for i <- 1..5, do: i
生成 [1, 2, 3, 4, 5]
,尽管事先没有正式的列表或在 for
构造中更新列表。
考虑到这两点,如果您想要的是在 data_as_a_list
的每个项目上获得一个调用 make_struct
的列表,您可以使用 for
实现它与:
def foo(data_as_a_list) do
for entry <- data_as_a_list do
make_struct(entry)
end
end