如何在不解除引用指针的情况下修复错误“无法移出取消引用”?

时间:2014-12-23 18:38:36

标签: pointers rust

我刚刚阅读了rust-lang.org上的生命周期指南并尝试实现该示例(但使用通用枚举来增加一点复杂性)。

enum PositionInfo<T> {
    Position(T, T),
}

enum ShapeInfo<T> {
    RectInfo(T, T),
    CircleInfo(T),
}

enum GeometricObject<T>{
    Circle(PositionInfo<T>, ShapeInfo<T>),
    Rectangle(PositionInfo<T>, ShapeInfo<T>),
}

impl<T:Num> GeometricObject<T>{
    fn get_area(&self) -> Option<T> {
        match *self {
            Circle(_, CircleInfo(r))     => Some(r * r), 
            Rectangle(_, RectInfo(w, h)) => Some(w * h),
            _                            => None,
        }
    }
}

当我尝试编译代码时,出现以下错误

enum_tut.rs:28:9: 28:14 error: cannot move out of dereference of `&`-pointer
enum_tut.rs:28      match *self {
                          ^~~~~
enum_tut.rs:29:29: 29:30 note: attempting to move value to here (to prevent the move, use `ref r` or `ref mut r` to capture value by reference)
enum_tut.rs:29                 Circle(_, CircleInfo(r))     => Some(r * r), 
                                                    ^
enum_tut.rs:30:30: 30:31 note: and here (use `ref w` or `ref mut w`)
enum_tut.rs:30                 Rectangle(_, RectInfo(w, h)) => Some(w * h),
                                                     ^
enum_tut.rs:30:33: 30:34 note: and here (use `ref h` or `ref mut h`)
enum_tut.rs:30                 Rectangle(_, RectInfo(w, h)) => Some(w * h),
                                                        ^
error: aborting due to previous error

查看错误消息,我将实现重写为以下内容并且编译时没有任何错误。

这段代码看起来很混乱;在我明确要求它引用之后,我必须取消引用4个指针。

有没有办法更干净地编写代码?

impl<T:Num> GeometricObject<T>{
    fn get_area(&self) -> Option<T> {
        match *self {
            Circle(_, CircleInfo(ref r))         => Some(*r * *r), 
            Rectangle(_, RectInfo(ref w, ref h)) => Some(*w * *h),
            _                                    => None,
        }
    }
}

1 个答案:

答案 0 :(得分:1)

问题是你的代码不知道制作T的副本是安全的,因为你没有告诉它。唯一安全的事情是引用对象并取消引用它们。否则,您可能会导致资源泄漏或破坏安全保障。

试试这个(游戏围栏现在不能正常工作,所以我无法验证它......):

Rust 1.0

impl<T> GeometricObject<T>
    where T: Copy + std::ops::Mul<Output=T>
{
    fn get_area(&self) -> Option<T> {
        use GeometricObject::*;
        use ShapeInfo::*;

        match *self {
            Circle(_, CircleInfo(r))     => Some(r * r), 
            Rectangle(_, RectInfo(w, h)) => Some(w * h),
            _                            => None,
        }
    }
}

<强>原始

impl<T:Num+Copy> GeometricObject<T>{
    fn get_area(&self) -> Option<T> {
        match *self {
            Circle(_, CircleInfo(r))     => Some(r * r), 
            Rectangle(_, RectInfo(w, h)) => Some(w * h),
            _                            => None,
        }
    }
}