为什么我不能链接 String.replace?

Why can't I chain String.replace?

我正在研究一个价格格式函数,它接受一个浮点数,并正确地表示它。

例如。 190.5,应该是190,50

这是我想出来的

  def format_price(price) do
    price
    |> to_string
    |> String.replace ".", ","
    |> String.replace ~r/,(\d)$/, ",\1 0"
    |> String.replace " ", ""
  end

如果我运行以下.

format_price(299.0)
# -> 299,0

第一次替换似乎只 运行 了。现在,如果我将其更改为以下内容。

  def format_price(price) do
    formatted = price
    |> to_string
    |> String.replace ".", ","

    formatted = formatted
    |> String.replace ~r/,(\d)$/, ",\1 0"

    formatted = formatted
    |> String.replace " ", ""
  end

然后似乎一切正常。

format_price(299.0)
# -> 299,00

这是为什么?

EDIT 在 Elixir 的 master 分支上,如果函数在没有括号的情况下通过管道传输,如果有参数,编译器将发出警告。


这是一个可以用显式括号解决的优先级问题:

price
|> to_string
|> String.replace(".", ",")
|> String.replace(~r/,(\d)$/, ",\1 0")
|> String.replace(" ", "")

因为函数调用的优先级高于 |> 运算符,所以您的代码与以下代码相同:

price
|> to_string
|> String.replace(".",
  ("," |> String.replace ~r/,(\d)$/,
    (",\1 0" |> String.replace " ", "")))

如果我们替换最后一个子句:

price
|> to_string
|> String.replace(".",
  ("," |> String.replace ~r/,(\d)$/, ".\10"))

再一次:

price
|> to_string
|> String.replace(".", ",")

应该解释为什么会得到这个结果。