按值重载运算符会导致使用移动值 [英] Operator overloading by value results in use of moved value

查看:16
本文介绍了按值重载运算符会导致使用移动值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编译以下使用运算符重载的 Rust 代码

Compiling the following Rust code that uses operator overloading

use std::ops::{Add};

#[derive(Show)]
struct Point {
    x: int,
    y: int
}

impl Add for Point {
    type Output = Point;

    fn add(self, other: Point) -> Point {
        Point {x: self.x + other.x, y: self.y + other.y}
    }
}

fn main() {
    let p: Point = Point {x: 1, y: 0};
    let pp = p + p;
}

由于 p 的所有权导致编译器错误:

Results in compiler errors due to ownership of p:

<anon>:21:18: 21:19 error: use of moved value: `p`
<anon>:21     let pp = p + p;
                           ^
<anon>:21:14: 21:15 note: `p` moved here because it has type `Point`, which is non-copyable
<anon>:21     let pp = p + p;
                       ^

这里解释了其背后的原理和导致了一个不被接受的 RFC (部分原因是由于上述原因例子).但是,后来的 RFC 仍然为运算符引入了按值类型签名.

The rationale behind it is explained here and led to an RFC that was not accepted (part of due to reasons of the above example). However, later the following RFC still introduced the by-value type signatures for operators.

虽然我理解这个决定背后的理由.由于我缺乏生锈经验,我不确定允许上述代码工作的正确"方法是什么(a)如果我不想复制或(b)如何使结构可复制?

While I understand the rationale behind the decision. Due to my lack of experience in rust, I'm not sure what the "proper" way would be to allow the above code to work (a) if I do not want to copy or (b) how to make the struct copyable?

推荐答案

如果你不想复制那么,就我的新手理解而言,你需要在引用上实现 Add.

If you don't want to copy then, as far as my newbie understanding goes, you need to implement Add on references to Point.

这将得到 RFC 的支持:

This would be supported by the RFC:

幸运的是,表现力没有损失,因为您始终可以在引用类型上实现特征.但是,对于确实需要引用的类型,人机工程学会略有损失,因为您可能需要使用 & 显式借用操作数.好处是所有权语义变得更加清晰:它们更接近于正常的函数参数.

Fortunately, there is no loss in expressiveness, since you can always implement the trait on reference types. However, for types that do need to be taken by reference, there is a slight loss in ergonomics since you may need to explicitly borrow the operands with &. The upside is that the ownership semantics become clearer: they more closely resemble normal function arguments.

确实它似乎有效:

use std::ops::{Add};

#[derive(Show)]
struct Point {
    x: i32,
    y: i32
}

impl<'a> Add for &'a Point {
    type Output = Point;

    fn add(self, other: &'a Point) -> Point { //'
        Point {x: self.x + other.x, y: self.y + other.y}
    }
}

fn main() {
    let p: Point = Point {x: 1, y: 0};
    let pp = &p + &p;
    println!("{:?}", pp);
}

(游戏围栏)

要使 Point 可复制,只需将 #[derive(Show)] 替换为 #[derive(Show,Copy)].这些结构过去默认是可复制的,但它 改变了.

To make Point copyable instead, just replace #[derive(Show)] with #[derive(Show,Copy)]. Such structs used to be copyable by default, but it changed.

这篇关于按值重载运算符会导致使用移动值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆