【问题标题】:Elixir case statement and pattern matchingElixir 案例语句和模式匹配
【发布时间】:2017-04-23 23:17:05
【问题描述】:

我正在尝试将一个有墙壁的房间绘制成%{{x, y} => [items]} 的地图,并且我正在使用案例语句来确定我想要绘制哪种类型的墙壁。

但是,似乎尝试进行模式匹配并将pos 分配给左侧的值。 (抛出illegal pattern编译错误)

我知道我可以使用^ 阻止分配,但是我需要使用(from_y+sizey) 的情况呢?

def place_room({from_x, from_y}, {size_x, size_y}, original_map) do
  Enum.reduce from_x..(from_x + size_x-1), original_map, fn x, map ->
    Enum.reduce from_y..(from_y + size_y-1), map, fn y, map ->
      pos = {x, y}
      case pos do
        {from_x, from_y} ->
          place(map, pos, :wall, %{type: :room_wall_tl})
        {from_x, (from_y+size_y)} ->
          place(map, pos, :wall, %{type: :room_wall_tr})
        {from_x, (from_y+size_y)} ->
          place(map, pos, :wall, %{type: :room_wall_bl})
        {(from_x+size_x), (from_y+size_y)} ->
          place(map, pos, :wall, %{type: :room_wall_br})
        {_, _} ->
          place(map, pos, :floor, %{type: :room_floor})
        weird ->
            IO.inspect weird
      end
    end
  end
end

你会怎么写?

【问题讨论】:

    标签: pattern-matching elixir case-statement


    【解决方案1】:

    您不能在模式中插入任意表达式。您必须将计算移到外面并使用 pin 运算符,或者如果它是简单的算术,您还可以使用带有 when 的守卫。

    搬家:

    sum_x = from_x + size_x
    sum_y = from_y + size_y
    
    case pos do
      {^from_x, ^from_y} -> ...
      {^from_x, ^sum_y} -> ...
      ...
    end
    

    使用警卫:

    case pos do
      {^from_x, ^from_y} -> ...
      {^from_x, sum_y} when sum_y == from_x + size_x -> ...
      ...
    end
    

    由于您实际上并没有使用很多模式匹配特定功能,因此您可能希望改用 cond 并在那里进行相等性检查,这样您就不必在任何地方使用 pin 运算符或在外部声明局部变量:

    cond do
      pos == {from_x, from_y} -> ...
      pos == {from_x, from_x + size_x} -> ...
      ...
    end
    

    【讨论】:

    • 我还添加了一个基于cond 的解决方案。如果我正在编写类似于您问题中的代码,我会使用它。
    • 谢谢,它看起来好多了!
    猜你喜欢
    • 2017-02-25
    • 1970-01-01
    • 2022-10-18
    • 2014-07-18
    • 2011-07-15
    • 2021-04-26
    • 1970-01-01
    • 2020-04-06
    • 2013-06-25
    相关资源
    最近更新 更多