我刚刚阅读了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,
}
}
}
答案 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,
}
}
}