在Elixir中,引脚运算符用于防止变量重新绑定.但是,对于像Ecto这样的查询
from u in User, where: u.username == ^username
Run Code Online (Sandbox Code Playgroud)
的作者编程凤凰状态(第7章),其
请记住,^运算符(称为pin运算符)意味着我们希望保持^ username相同.
但这听起来不对,因为显然,查询中的比较不会导致任何重新绑定变量.
这本书的作者(JoséValim与谁合着)是错误的吗?Ecto中的引脚运算符只是查询Ecto DSL的构造而不是通常的Elixir引脚运算符吗?或者username,在宏扩展后,查询是否真的有机会重新绑定?
Mla*_*vić 27
Ecto的查询依赖于宏来提供我们使用的强大的DSL.这意味着,无论发生什么from,都不是"常规"Elixir代码,而是最终将转换为SQL查询的DSL.因此,插入符号本身没有插入操作符,与模式匹配无关(尽管显然它仍然可以称为"引脚操作符",因为人们总是会忘记诸如插入符号和符号和星号之类的单词).这只是一个方便的操作员,Ecto的作者选择成为"插值算子".如果没有它,username你的示例将从字面上直接插入,并直接插入到生成的SQL中(尽管Ecto足够聪明,可以看到那不是你想要的,所以它会溢出错误).
很棒的问题BTW,激励我阅读更多关于宏(FP中的新手).
Nim*_*mir 22
根据Ecto文档,ecto中的pin运算符用于查询插值:
可以使用^将外部值和Elixir表达式注入查询表达式
Run Code Online (Sandbox Code Playgroud)def with_minimum(age, height_ft) do from u in "users", where: u.age > ^age and u.height > ^(height_ft * 3.28), select: u.name end
试图跳过引脚会给你一个错误,因为Ecto无法找出一个名为的数据库函数或查询表达式age:
(Ecto.Query.CompileError)变量
age不是有效的查询表达式.需要使用^在查询中显式插值变量