2411d,右值与移动
原文
概述
添加语言内部__rvalue(Expression)
函数,指示对匹配函数参数,按右值对待式
.这在用非引用
语义调用函数
时启用移动
语义.
移动语义
对运行时和资源效率
是可取
的,因为可移动资源
到新对象
,而不是复制然后析构
.其他语言(如C++
)有流行
的移动语义
.
先前的工作
C++
移动语义这里
Rust
与C++
移动语义对比这里
C++
语义有害(Rust
更好)这里
描述
语法
RvalueExpression
是个附加
的PrimaryExpression
:
RvalueExpression:
__rvalue ( AssignExpression )
重载
如果同时有引用
和非引用
参数重载
,则偏爱匹配右值
与非引用
参数,而偏爱左值
与引用
参数匹配
.RvalueExpression
最好与非引用
参数匹配.
右值参数匹配参数语义
按调用函数
拥有对待右值参数
.因此,如果左值与右值参数
匹配,则会给函数
传递左值副本
.然后,在函数结束时该函数
对(如果有)参数调用析构器
.
不会复制右值参数
,因为按唯一
假设它,且在函数结束
时也会析构它.编译器会自动
给函数体
附加析构
.
函数
无法知道其参数源
是右值
还是左值的副本
.
即在函数返回
时,__rvalue
(左值式
)参数
会析构式
.不能继续使用左值式
.在传递给函数
后,编译器并不总是可检测到使用
,即对象的析构器
必须按其初值或至少是良性值
,重置对象的内容
.
struct S
{
ubyte* p;
~this()
{
free(p);
//在此添加:`'p=null;'`
}
}
void aggh(S s)
{
}
void oops()
{
S s;
s.p = cast(ubyte*)malloc(10);
aggh(__rvalue(s));
free(s.p); //错误,两次释放`s.p`
}
用__rvalue
移动赋值
struct S
{
ubyte* p;
~this()
{
free(p);
p = null;
}
void opAssign(S s)
{
this.p = s.p;
s.p = null;
}
}
void oops()
{
S s;
s.p = cast(ubyte*)malloc(10);
S t;
t = __rvalue(s);
}
用__rvalue
移动构造
struct S
{
ubyte* p;
~this()
{
free(p);
p = null;
}
this(S s)
{
this.p = s.p;
s.p = null;
}
}
void oops()
{
S s;
S t = __rvalue(s);
}