问题描述
在Elixir中,pin运算符用于防止变量重新绑定。但是,对于来自User中u的
In Elixir, the pin operator is used to prevent variable rebinding. However, with regard to an Ecto query like
from u in User, where: u.username == ^username
Programming Phoenix 州的作者(在第7章中)
the authors of Programming Phoenix state (in chapter 7) that
但这听起来不对,因为显然,查询中的比较不会引起任何变量的重新绑定。
But this doesn't sound right, because apparently, the comparison in the query shall not cause any rebinding of variables.
这本书的作者(何塞·瓦利姆(JoséValim)合写)误会了吗? Ecto中的pin运算符是否只是Ecto DSL的构造,而不是通常的Elixir pin运算符?还是在扩展宏之后查询真正有机会重新绑定用户名
?
Are the authors of the book (which José Valim co-authored) mistaken? Is the pin operator in Ecto queries merely a construct of the Ecto DSL instead of a usual Elixir pin operator? Or will the query really get a chance to rebind username
after the macros are expanded?
推荐答案
Ecto的查询依赖于宏来提供我们使用的强大DSL。这意味着,在之后
之后的任何内容,都不是常规的Elixir代码,而是最终将转换为SQL查询的DSL。因此,插入符号本身没有pin运算符,并且与模式匹配无关(尽管显然它仍可以称为 pin运算符,因为人们总是忘记诸如 caret 和& 和星号)。 Ecto的作者选择作为插值运算符只是一种方便的运算符。没有它,您的示例中的用户名
将会被原样地获取,并直接插入到生成的SQL中(尽管Ecto足够聪明,可以看到那不是您想要的,所以它会溢出)一个错误)。
Ecto's queries rely on macros to provide the powerful DSL that we use. That means that, whatever comes after from
, is not "regular" Elixir code, but a DSL which will eventually get transformed to SQL query. So, a caret there is not pin operator per se, and has nothing to do with pattern matching (although obviously it still can be called "pin operator" because people always forget words such as caret and ampersand and asterisk). It's just a convenient operator that Ecto's authors choose to be an "interpolation operator". Without it, the username
from your example would be taken literally, and inserted directly to the generated SQL (though Ecto is smart enough to see that that's not what you want so it spills an error).
很好的问题BTW,启发了我阅读有关宏的更多信息(此处是FP中的新手)。
Great question BTW, inspired me to read more about macros (newbie in FP here).
这篇关于为什么在Ecto查询中必须使用pin运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!