Map.fetch/2与Map.fetch!/2的区别及适用场景咨询
When to use Map.fetch/2 vs Map.fetch!/2 in Elixir?
Great question! Let’s break down their core differences and walk through when to pick one over the other based on your use case.
Core Behavioral Differences
First, let’s recap the basics to fill in the doc gaps:
Map.fetch/2: Returns{:ok, value}if the key exists, or:errorif it doesn’t. This is Elixir’s idiomatic "safe" approach—no exceptions thrown, just clear, predictable return values to handle. And as the docs mention, it’s inlined by the compiler, so it’s plenty performant.Map.fetch!/2: Returns the value directly if the key exists, but throws aKeyErrorexception immediately if the key is missing. This is an "assertive" approach—you’re stating that the key must be there, and its absence is a critical error that shouldn’t be ignored.
When to Use Map.fetch/2
- Uncertain or external data sources: If you’re dealing with user input, API responses, or any data outside your program’s direct control,
fetch/2is the way to go. It lets you gracefully handle both the presence and absence of a key without crashing:case Map.fetch(form_submission, :username) do {:ok, username} -> create_profile(username) :error -> render_error("Username is required") end - Pipeline-friendly error handling: It plays nicely with Elixir’s
withstatement or pipe operators, keeping your code flow clean when chaining multiple operations that might fail:with {:ok, username} <- Map.fetch(form_submission, :username), {:ok, email} <- Map.fetch(form_submission, :email), {:ok, user} <- Accounts.create_user(username, email) do {:ok, user} else :error -> {:error, :missing_fields} {:error, reason} -> {:error, reason} end
When to Use Map.fetch!/2
- Controlled, internal data: If you’re working with data your program generates or strictly controls (like a struct loaded from your database, or a config map you defined),
fetch!/2makes sense. Missing a key here is a bug in your code, not a user error, so an exception will help you catch it early:# We know current_user is loaded from the DB and always has an :id user_id = Map.fetch!(current_user, :id) Logger.info("User #{user_id} updated their settings") - Rapid development/debugging: When prototyping or debugging,
fetch!/2saves time by immediately highlighting missing keys instead of letting the program continue with silent failures. It’s a quick way to catch mistakes early. - Scripting or one-off tasks: In short scripts where code brevity matters more than fault tolerance,
fetch!/2keeps your code concise—you don’t need extra error handling for a task that’s only run once.
A Quick Note on Performance
While Map.fetch/2 is inlined by the compiler, the performance difference between the two is negligible for most use cases. Don’t pick one over the other for performance reasons—focus on whether you need to handle missing keys gracefully or want to assert their presence.
内容的提问来源于stack exchange,提问作者pkbyron
相关产品推荐
相关产品推荐

