卫兵!卫兵

Lobsters Hottest 新闻

摘要

探讨 Elixir 中一个令人惊讶的行为:`is_map_key/2` 守卫可能导致守卫失败而非返回 false,从而破坏了布尔运算符的可交换性。

<p><a href="https://lobste.rs/s/b2emi7/guards_guards">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/06/27 17:55

# Hauleth 的博客 - 守卫!守卫! 来源:https://hauleth.dev/post/guards-guards/ 我们先从一个简单的小测开始。 --- 给定如下模块定义: ```elixir defmodule Foo do def a(x) when is_integer(x) or is_map_key(x, :foo), do: true def a(x), do: false def b(x) when is_map_key(x, :foo) or is_integer(x), do: true def b(x), do: false end ``` 试着回答以下问题。 **问:** `Foo.a(%{foo: 21})` 的结果是什么? `true` `false` 错误 正确 这个问题很直白。 我们检查守卫,它有一个条件 `is_integer(x) or is_map_key(x, :foo)`。第一个返回 `false`,第二个返回 `true`,布尔运算的或运算结果为 `true`,因此匹配第一个子句。 **问:** `Foo.a(37)` 的结果是什么? `true` `false` 错误 正确 这个问题同样直白。 我们检查守卫,它有一个条件 `is_integer(x) or is_map_key(x, :foo)`。第一个返回 `true`,第二个根本不会触发,因为 `or` 运算符是短路的。 **问:** `Foo.b(%{foo: 21})` 的结果是什么? `true` `false` 错误 正确 同样,和前几个问题类似。 我们检查守卫,它有一个条件 `is_map_key(x, :foo) or is_integer(x)`。第一个返回 `true`,剩余部分被短路。 **问:** `Foo.b(37)` 的结果是什么? `true` `false` 错误 正确 哦,出现了变化…… 我们再次检查守卫,一个条件 `is_map_key(x, :foo) or is_integer(x)`。我们首先遇到第一个子句 `is_map_key(x, :foo)`,而这个子句 **没有** 返回 `false`,相反它失败了。守卫函数中的任何一个失败都不会转换为 `false`,而是导致整个守卫表达式失败。这意味着 `is_integer(x)` 部分将 **永远不会** 被调用。 --- 这种行为常常让许多 Elixir 开发者感到惊讶,因为它似乎破坏了布尔运算符的交换律。然而,说实话,由于短路求值的缘故,它们从来就不是可交换的。 似乎在撰写本文时(Elixir 1.20.1,OTP 29),Elixir 并未对此问题发出警告。 ∎

相似文章

整数无故发生神秘变化,而本应无代码生成影响

The Old New Thing (Raymond Chen)

一位开发者发现,交换两个等效宏竟导致无关函数中出现意外的整数变化,这篇博客文章深入探究了这一谜团,并对某个大语言模型(LLM)关于控制流保护的解释提出了质疑。

更多Molly Guards

Hacker News Top

一篇后续文章,展示了各种‘molly guards’的例子——这些是防止意外按键或操作的物理和软件设计元素——从IBM打字机到Chrome的退出对话框。

PrefixGuard: From LLM-Agent Traces to Online Failure-Warning Monitors

Hugging Face Daily Papers

# Paper page - PrefixGuard: From LLM-Agent Traces to Online Failure-Warning Monitors Source: [https://huggingface.co/papers/2605.06455](https://huggingface.co/papers/2605.06455) ## Abstract PrefixGuard enables effective online monitoring of LLM agents through trace analysis and prefix\-based risk scoring, demonstrating strong performance across multiple benchmark tasks while providing diagnostic insights for alert reliability\. Large language model \(LLM\) agents now execute long, tool\-using ta