在Erlang(或Elixir)中将记录模式匹配作为元组是不是很糟糕?
示例代码:假设我们已经定义了这个模块:
defmodule Ween do
defrecord TimeSpot, at: nil, tag: nil
def proper?({ _, _, "home"} = v), do: { true, "succeeded with: #{inspect v}" }
def proper?(other), do: { false, "failed with: #{inspect other}" }
def sample, do: TimeSpot.new(tag: "home")
end
如果我们定义测试如下:
defmodule WeenTest do
use ExUnit.Case
require Ween
test "records are tuples" do
case Ween.proper?(Ween.sample) do
{ true, v } -> IO.puts v
assert(true)
{ false, v } -> IO.puts v
assert(false)
end
end
end
它会成功。
编辑1:@parroty 这里针对元组测试的模式匹配的原因是模拟记录中的某种“类型”鸭子类型;我希望的最终结果应该是这样的:
defmodule Ween do
defrecord TimeSpot, at: nil, tag: nil
def proper?([tag: "home"] = v), do: { true, "succeeded with: #{inspect v}" }
def proper?([tag: "1234"] = v), do: { true, "succeeded with: #{inspect v}" }
def proper?(other), do: { false, "failed with: #{inspect other}" }
def sample, do: TimeSpot.new(tag: "home")
end
因此,每个带有“标记”字段的记录都会显示“home”值,这与第一个子句匹配。当然,那里似乎会有一些性能损失。
答案 0 :(得分:4)
Cesarini和Thompson在他们的书 Erlang Programming 中说,从不依赖于记录被实现为元组的事实,因为该实现可能会改变。请参阅this question的接受答案。
答案 1 :(得分:4)
我认为记录可以直接用于模式匹配(这比使用元组结构更好)。
defmodule Ween do
defrecord TimeSpot, at: nil, tag: nil
def proper?(TimeSpot[tag: "home"] = v), do: { true, "succeeded with: #{inspect v}" }
def proper?(other), do: { false, "failed with: #{inspect other}" }
def sample, do: TimeSpot.new(tag: "home")
end
答案 2 :(得分:1)
只是为了完整性(因为这个问题在Elixir标记问题列表中仍然非常高):从Elixir 0.13开始,不推荐使用记录(除了与Erlang代码交互之外),现在使用Structs最好地实现了这个问题。这些也方便地为您提供了您想要的多态性(Structs是Map的一种形式)
http://elixir-lang.org/getting_started/15.html