原文
概述
添加语言内部__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);
}