不确定我为什么会收到此编译器警告。我在这里做错了什么?
defmodule T do
def get_length do
with {:ok, file} <- File.read("<file>"),
content <- String.downcase(file) do
IO.puts content
end
end
end
警告:此子句无法匹配,因为第4行的前一个子句始终匹配
答案 0 :(得分:6)
TLDR:with
这里有点矫枉过正。
defmodule T do
def get_length do
{:ok, file} = File.read("<file>")
IO.puts String.downcase(file)
end
end
此外,您收到了编译器警告,因为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
......你可以写下这个可爱的魔法:
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
因此,为了好玩,让我们根据您的文件示例构建一个可以使用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
您可以看到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
答案 1 :(得分:3)
你真的有意这样做吗?
defmodule T do
def get_length do
with {:ok, file} <- File.read("<file>") do
content = String.downcase(file) #Assigning result of String.downcase will _always_ work.
IO.puts content
end
end
end
老实说,有点难以推断代码的意图。我的意思是这也会做同样的事情(据我所知)
defmodule T do
def get_length do
{:ok, file} = File.read("<file>")
content = String.downcase(file)
IO.puts content
end
end
我的意思是说我不确定使用with
在哪里获得任何东西。
在Erlang和Elixir中,如果你从File.read获得除{:ok, file}
元组以外的任何东西,那么你将得到错误。如果您无法读取该文件,那么还没有真正的恢复选项吗?