根据the documentation,我们有左值和左值上下文。如何知道表达式是否在左值上下文中?它只是在作业中的表达方面确定了吗?
更具体一点,我需要了解何时使用Deref
取消引用以及何时使用Index
?与IndexMut
和mobno:{
type:String,
unique:true,
validate: {
validator: function(v) {
return /^([0-9]{10}$)/.test(v);
}},
required: true
}
相同。
答案 0 :(得分:5)
你在这里问两个不同的问题。
更具体一点,我需要了解,当
DerefMut
用于取消引用时以及何时使用Deref
时?与Index
和IndexMut
相同。
这仅取决于结果值是否可变使用。使用属于这些特征([]
和*
)的运算符的表达式始终是左值表达式。
现在你的问题更加复杂:
如果表达式位于左值上下文中,我怎么知道?它只是在作业中的表达方面确定了吗?
回顾:什么是右值/左值表达式?
哪些表达式是左值,哪些是右值表达式?只有少数 l 值表达式:
foo[3]
)*foo
)foo.bar
) rvalue / lvalue contexts 怎么样?这些上下文是表达式中的“槽”。例如,表达式“modulo”(%
)有两个插槽,第一个和第二个操作数:⟨first⟩ % ⟨second⟩
。现在这些背景有两种不同的风格:
那么哪个槽是右值,哪个是左值上下文?幸运的是,数字 l 值的上下文非常有限,所以这里有一个完整的列表:
⟨lvalue context⟩ = ...;
或⟨lvalue context⟩ += ...;
)&⟨lvalue context⟩
和&mut ⟨lvalue context⟩
)ref
的模式时(例如let ref x = &⟨lvalue context⟩;
)让我们看看我们可以在上下文中使用哪些表达式:
3
)
在 l [L in L] l 值表达式 > 值上下文:没问题,表达式用作内存位置(例如,赋值左侧的变量名)
在 r [L in R] l 值表达式 > 值上下文:由于上下文需要一个值而表达式表示“内存位置中的值”,我们只需使用表达式的值即可。所以:一切都很好(例如,作业右侧的变量名称)。所以我们可以看到:左值表达式比 rvalue表达式更有价值。
在 l [R in L] r 值表达式 > 价值观背景:这就是问题所在。上下文需要内存地址,但表达式仅表示值。有时候,Rust会做一个“rvalue promotion”来制作像这样的工作。这意味着Rust会自动将表达式的值放入新的内存位置(临时变量)并在上下文中使用该位置。例如,&mut 3
因为所述促销而起作用。此促销目前不适用于seems to be a bug in either the documentation or the compiler。的作业
答案 1 :(得分:1)
DerefMut
/ Deref
/ Index
/ IndexMut
由可变性决定,这与 lvalue / rvalue不同上下文即可。可变性对于右值上下文没有意义。
事实上,所有四个特征都要求操作数self
位于左值上下文中,因为它们都以&Self
或&mut Self
作为参数。
DerefMut
/ IndexMut
,例如
*here = ...;
here[i] = ...;
&mut here
&mut here[i]
here.call_some_mut_method(...)
here[i].call_some_mut_method(...)
左值上下文是您想要知道表达式的地址(内存位置/引用/ ...)而不是其值的位置。你需要一个左值的地方。
赋值或复合赋值表达式的左操作数是左值上下文,...
here = ...;
here += ...;
......这是一元借款的单一操作数。
&here
&mut here
let ref ... = here;
// Note: equivalent to `let ... = &here;`
let ref mut ... = here;
// Note: equivalent to `let ... = &mut here;`
注意:这显示了一个不可变的左值上下文
匹配表达式的判别式或主语可以是左值上下文,如果是ref绑定,则是rvalue上下文。
match here {
Ok(ref ...) => ...,
Err(ref mut ...) => ...,
}