可能重复:
What does ||= (or equals) mean in Ruby?回报率:解释 “用户|| = User.new”
Out on the internet我看到下面的语法的Ruby/Rails:
user ||= User.new
我是新手,我无法解析这个。有人可以向我解释“|| =”运算符的用途吗?
可能重复:
What does ||= (or equals) mean in Ruby?回报率:解释 “用户|| = User.new”
Out on the internet我看到下面的语法的Ruby/Rails:
user ||= User.new
我是新手,我无法解析这个。有人可以向我解释“|| =”运算符的用途吗?
如果已经设置了user
,那什么都不做,否则它会分配一个新的User
对象(使用User.new
创建)。
According to David A. Black “的良好的接地Rubyist” 的作者:
X || = y表示:X || x = y
所不同的是,如果x未定义,x || = y不会抱怨, 而如果您键入x || y, x = y,范围内没有x,它会。
对于一些添加的细节,这里的parse.y相关部分:
| var_lhs tOP_ASGN command_call
{
/*%%%*/
value_expr($3);
if ($1) {
ID vid = $1->nd_vid;
if ($2 == tOROP) {
$1->nd_value = $3;
$$ = NEW_OP_ASGN_OR(gettable(vid), $1);
if (is_asgn_or_id(vid)) {
$$->nd_aid = vid;
}
}
else if ($2 == tANDOP) {
$1->nd_value = $3;
$$ = NEW_OP_ASGN_AND(gettable(vid), $1);
}
else {
$$ = $1;
$$->nd_value = NEW_CALL(gettable(vid), $2, NEW_LIST($3));
}
}
NEW_OP_ASGN_OR
在node.h
定义:
#define NEW_OP_ASGN_OR(i,val) NEW_NODE(NODE_OP_ASGN_OR,i,val,0)
NEW_NODE
看起来是这样的:
#define NEW_NODE(t,a0,a1,a2) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))
寻找NODE_OP_ASGN_OR
导致compile.c
,其中最有趣的部分是这样的:
case NODE_OP_ASGN_OR:{
LABEL *lfin = NEW_LABEL(nd_line(node));
LABEL *lassign;
if (nd_type(node) == NODE_OP_ASGN_OR) {
LABEL *lfinish[2];
lfinish[0] = lfin;
lfinish[1] = 0;
defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
lassign = lfinish[1];
if (!lassign) {
lassign = NEW_LABEL(nd_line(node));
}
ADD_INSNL(ret, nd_line(node), branchunless, lassign);
}
else {
lassign = NEW_LABEL(nd_line(node));
}
COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head);
ADD_INSN(ret, nd_line(node), dup);
if (nd_type(node) == NODE_OP_ASGN_AND) {
ADD_INSNL(ret, nd_line(node), branchunless, lfin);
}
else {
ADD_INSNL(ret, nd_line(node), branchif, lfin);
}
ADD_INSN(ret, nd_line(node), pop);
ADD_LABEL(ret, lassign);
COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_value", node->nd_value);
ADD_LABEL(ret, lfin);
if (poped) {
/* we can apply more optimize */
ADD_INSN(ret, nd_line(node), pop);
}
break;
}
我觉得这是比我更想了解的关于Ruby的任务,但它是相当有趣的看这件事。
x || = y表示:x = x || y – 2013-03-27 16:24:26
该语句将自己设置为user
(如果它已经是一个现有对象)或User.new
(如果用户为空,它将创建一个新用户)。这是一个合乎逻辑的或将避免有一个分配的空用户对象。
的代码用于
user = user || User.new
的速记如果用户为空,则用户将被设置为User.new
。
这基本上是一个快捷方式:
user = user || User.new
或为了更好的理解:
if user.nil?
user = User.new
end
我敢打赌,你以前见过类似的符号与像 '+'
i += 1
运营商
这也可以写成:
i = i + 1
不仅'nil',也'false'。 – 2012-08-14 18:48:39
这种说法是相当于
user = user || User.new
这相当于
user = user ? user : User.new
它将当且仅当user
是零的User.new
值赋给变量user
。如果不是,则user
的内容将保持不变。
在这里,'nil'或'false',不只是'nil'。 – 2012-08-14 18:50:36
我可能是错的,但是如果他们不熟悉'|| =',我不会期望他们熟悉'?:' – Retsam 2012-08-14 18:55:27
为什么?许多语言都有三元运算符,并不是所有的都有'|| ='。 – 2012-08-14 18:56:22
这相当于user = user || User.new
。
这依赖于||
运营商的短路行为。如果表达式的左边是真的,那么右边将是什么并不重要,整体表达式将是真实的,因此操作员“短路”并停止评估。而不是返回布尔值“真”,||
运算符返回它所评估的最后一个值。
所以,||=
是分配的默认值是有用的。如果user
具有值,则user || User.new
评估为user
,否则评估为User.new
,这是默认值。
的等效块是:
if user
user = user
else
user = User.new
end
啊,很抱歉。我尝试在此处的搜索框中输入'|| =',但没有出现。也许我的查询被解释为几个布尔运算符而不是字符串?我正在寻找错误的方式吗? – 2012-08-14 18:54:08
我不知道SO如何处理像|| =这样的字符。我用英文单词或等号搜索。 – 2012-08-14 18:57:38
我会在下次尝试。谢谢。 – 2012-08-14 18:58:13