You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elixir元组模式匹配语法疑问:=与->的区别

Understanding = vs -> in Elixir's Pattern Matching

Great question! Let's break this down clearly so you can see exactly what's going on with these two syntaxes, and why your proposed alternative doesn't work.

First: What's the difference between = and ->?

  • The = operator is Elixir's pattern match operator: It's used to check if the right-hand side value matches the left-hand side pattern, and bind variables if the match succeeds. For example:

    # This works: binds filename to "report.pdf"
    {:result, filename} = {:result, "report.pdf"}
    
    # This would fail: the right side doesn't match the left side's tuple structure
    {:result, filename} = "report.pdf"
    

    It's a single, standalone operation that either succeeds (binds variables) or raises a MatchError.

  • The -> is a clause separator: It's used in multi-branch structures like receive, case, and anonymous functions to split a "match pattern" from the "code to run when that pattern matches". It's not a match operator itself—it's part of the syntax that organizes multiple pattern-matching cases.

Why receive uses ->

When you write a receive block, Elixir expects a list of pattern-action pairs. Each pair follows the format pattern -> code_to_execute.

In your example:

receive do
  {:result, filename} -> filename
end

This means:

  1. Wait for an incoming message.
  2. If the message matches the pattern {:result, filename} (i.e., it's a 2-element tuple where the first element is :result), bind the second element to filename.
  3. Then return the value of filename as the result of the receive block.

Why your proposed {:result, filename} = filename is invalid

Your suggested line has two big issues:

  1. It doesn't fit receive's syntax: The receive do block expects clauses in pattern -> action form. Writing a standalone = match expression here isn't valid syntax—the compiler will throw an error because it doesn't recognize this as a valid receive clause.
  2. The match itself is logically flawed: Even if you tried to use this line elsewhere, {:result, filename} = filename would only succeed if the variable filename is already a tuple of the form {:result, some_value}. In the context of receive, we're trying to match against the incoming message—not against a variable we haven't even bound yet! That's backwards from how pattern matching works in this scenario.

Sort of! Anonymous functions use -> for the same reason receive does: to separate match patterns from their corresponding code blocks. For example:

process_message = fn
  {:result, filename} -> "Got result for #{filename}"
  {:error, reason} -> "Error: #{reason}"
end

process_message.({:result, "data.csv"}) # Returns "Got result for data.csv"

This is the same multi-branch pattern-matching syntax as receive—-> is just how Elixir lets you define "when X matches, do Y" across multiple cases.


内容的提问来源于stack exchange,提问作者Ayrton Senna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 19:32:53