String.to_integer/1的奇怪行为

d34*_*4n5 8 elixir

Elixir里有一些奇怪的东西String.to_integer.没什么大不了的,但我想知道是否有办法用管道操作员链接我的所有功能.

这是问题所在.这行代码(你可以试试"iex"):

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join "", &(Integer.to_string(&1))
Run Code Online (Sandbox Code Playgroud)

返回字符串 "3765"

我想要的是一个整数.所以我只需要|> String.to_integer在前一个语句的末尾添加这段代码,我应该有一个整数.我们试试吧.这段代码:

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join "", &(Integer.to_string(&1)) 
|> String.to_integer
Run Code Online (Sandbox Code Playgroud)

给我这个:"3765".不是整数,一个字符串!

如果我这样做:

a = [5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join "", &(Integer.to_string(&1)) 
String.to_integer(a)
Run Code Online (Sandbox Code Playgroud)

它返回一个整数:3765.

这就是我现在正在做的事情,但它让我很生气,因为我很乐意将所有这些功能与惊人的管道操作员联系起来.

感谢您的帮助或灯光.Elixir非常有趣!

Pat*_*ity 9

您需要在参数周围添加括号map_join.目前,您的代码被解释为

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join("", &(Integer.to_string(&1) |> String.to_integer))
Run Code Online (Sandbox Code Playgroud)

你想要的是什么

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join("", &(Integer.to_string(&1)))
|> String.to_integer
Run Code Online (Sandbox Code Playgroud)

通常,在管道内使用捕获时,始终需要使用括号以避免歧义.捕获还可以简化为&Integer.to_string/1:

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.map_join("", &Integer.to_string/1)
|> String.to_integer
Run Code Online (Sandbox Code Playgroud)

但平原Enum.join会做同样的事情.如果你看的实施,将整数转换为字符串反正使用String.Chars协议.

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.join
|> String.to_integer
Run Code Online (Sandbox Code Playgroud)

顺便说一下,你可以在不使用字符串的情况下实现同样的目的:

[5, 6, 7, 3] 
|> Enum.reverse 
|> Enum.reduce(0, &(&2 * 10 + &1))
Run Code Online (Sandbox Code Playgroud)

哦,然后还有Integer.digitsInteger.undigits,其可用于整数转换和数字列表.它在当前版本中不存在,虽然它在1.1.0-dev分支中,所以我怀疑它会进来1.1.0.你可以在这里观察进展.

[5, 6, 7, 3] 
|> Enum.reverse 
|> Integer.undigits
Run Code Online (Sandbox Code Playgroud)

  • 这就是为什么我一般反对任选的parens.在少数情况下,它很高兴,但我认为通常最好养成一种习惯,即在需要的地方放置parens. (2认同)