此子句无法匹配,因为前一个子句始终匹配

the*_*ing 2 elixir

不知道为什么我收到此编译器警告.我在这做错了什么?

defmodule T do
    def get_length do
        with {:ok, file} <- File.read("<file>"),
             content <- String.downcase(file) do
                IO.puts content
             end
    end
end
Run Code Online (Sandbox Code Playgroud)

警告:此子句无法匹配,因为第4行的前一个子句始终匹配

fny*_*fny 6

TLDR:with这里有点矫枉过正.

defmodule T do
  def get_length do
    {:ok, file} = File.read("<file>") 
    IO.puts String.downcase(file)
  end
end
Run Code Online (Sandbox Code Playgroud)

此外,您将获得编译器警告,因为content它将有效地匹配由提供的任何内容String.downcase/1.

详细模式:

我不认为你理解的意图with.with通过描述你关心的快乐路径上的模式匹配,可以将许多粗糙的案例链接在一起.

所以不要像这样写一些令人发指的东西......

defp serve(socket) do
  msg =
    case read_line(socket) do
      {:ok, data} ->
        case KVServer.Command.parse(data) do
          {:ok, command} ->
            KVServer.Command.run(command)
          {:error, _} = err ->
            err
        end
      {:error, _} = err ->
        err
    end

  write_line(socket, msg)
  serve(socket)
end
Run Code Online (Sandbox Code Playgroud)

......你可以写出这个可爱的魔法:

defp serve(socket) do
  msg =
    with {:ok, data} <- read_line(socket),
         {:ok, command} <- KVServer.Command.parse(data),
         do: KVServer.Command.run(command)

  write_line(socket, msg)
  serve(socket)
end
Run Code Online (Sandbox Code Playgroud)

所以为了好玩,让我们构建一个我们可以利用with给定文件示例的情况.

想象一下,这里定义的函数具有相当复杂的失败案例

defmodule X do
  def extract_header(file) do
    # returns {:ok, file} or {:err, file} or whatever
  end

  def starts_with_emoji?(file) do
    # returns true or false
  end
end
Run Code Online (Sandbox Code Playgroud)

你可以看到如何with派上用场:

defmodule T do
  def header_emoji_alert do
    with {:ok, file} <- File.read("<file>"),
         {:ok, header} <- X.extract_header(file),
         true  <- X.starts_with_emoji?(header), do: IO.puts("EMOJI!!!!")
  end
end
Run Code Online (Sandbox Code Playgroud)