Gre*_*olm 10 arrays rust rust-0.8
我是一个Rust新手试图通过玩它来弄清楚语言.尝试从函数返回数组时遇到了一些问题:
struct Widget {
thingies: ~[int]
}
impl Widget {
fn new() -> Widget {
Widget { thingies: ~[4, 8, 15, 16, 23, 42] }
}
fn somethings(&self) -> ~[int] {
self.thingies
}
}
fn main() {
let widget = Widget::new();
let wotsits = widget.somethings();
}
Run Code Online (Sandbox Code Playgroud)
这当然无法使用此错误进行编译:
pointers.rs:11:8: 11:21 error: cannot move out of dereference of & pointer
pointers.rs:11 self.thingies
Run Code Online (Sandbox Code Playgroud)
如果这个代码示例看起来不合适,我所要做的就是从已实现的结构中拉出一个数组.借用的指针并不重要,它只是我试图存储数据的方式.
有关如何正确提取数组的任何提示?
顺便说一下,我正在使用Rust 0.8
A.B*_*.B. 13
您的代码无法编译的原因是唯一指针~只能有一个所有者.编译器阻止您编写容易出错的代码.你可以决定返回一个东西的副本,一个对东西的引用,或一片东西(它是对矢量数据或它的一部分的引用).
复制解决方案
struct Widget {
thingies: ~[int]
}
impl Widget {
fn new() -> Widget {
Widget { thingies: ~[4, 8, 15, 16, 23, 42] }
}
fn somethings(&self) -> ~[int] {
self.thingies.clone()
}
}
Run Code Online (Sandbox Code Playgroud)
参考方案
struct Widget {
thingies: ~[int]
}
impl Widget {
fn new() -> Widget {
Widget { thingies: ~[4, 8, 15, 16, 23, 42] }
}
fn somethings<'a>(&'a self) -> &'a~[int] {
&self.thingies
}
}
Run Code Online (Sandbox Code Playgroud)
切片解决方案
struct Widget {
thingies: ~[int]
}
impl Widget {
fn new() -> Widget {
Widget { thingies: ~[4, 8, 15, 16, 23, 42] }
}
fn somethings<'a>(&'a self) -> &'a[int] {
self.thingies.as_slice()
}
}
Run Code Online (Sandbox Code Playgroud)
要理解引用和切片解决方案,您需要了解其'a含义:它表示生命周期,并且&'a是一种告诉编译器引用必须永远不会超过它引用的对象的方法,在这种情况下,它是一个Widget.
这些解决方案也有一些限制:您无法修改当前引用的对象,因为这样做会打开引用变为无效的可能性.
如果你返回一个可变引用,你当然可以修改thingies.将编写具有生命周期的可变引用&'a mut T
struct Widget {
thingies: ~[int]
}
impl Widget {
fn new() -> Widget {
Widget { thingies: ~[4, 8, 15, 16, 23, 42] }
}
fn somethings<'a>(&'a mut self) -> &'a mut ~[int] {
&mut self.thingies
}
}
Run Code Online (Sandbox Code Playgroud)
注意我相信在Rust 0.8中,您需要编写&'self而不是&'a因为不支持使用自定义名称的生命周期.我也在0.9写了这个.
编辑:删除冗余生命周期声明.
=== 编辑 ===
在Rust 1稳定,~[T]成为Vec<T>,但(语法旁边)同样的问题适用,因为Vec仍然有一个独特的所有者.简而言之,somethings只有对自我的引用和(通过引用)它不能成为所有者thingies.游乐场链接到Rust 1版本:https://play.rust-lang.org/?gist = 50ec1acdc684e53fd5f9&version =stable.
Rust的所有权模式对语言来说非常重要,因此有关更多信息,我建议查看有关所有权和借用的优秀官方文档
=== 结束编辑 ===
在Rust中,.后self,自动解除引用self,所以这就是dereference of & pointer错误提到的.
现在,物品的所有权是您cannot move out of解除引用的部分:
let widget = Widget::new(); // widget owns the unique pointer to self
let wotsits = widget.somethings(); // if this worked, ownership of
// unique pointer to thingies would be
// moved to wotsits
Run Code Online (Sandbox Code Playgroud)
您可以借用对thingies的引用:
fn somethings<'a>(&'a self) -> &'a~[int] {
&self.thingies
}
Run Code Online (Sandbox Code Playgroud)
或明确返回一些东西
fn somethings(&self) -> ~[int] {
self.thingies.clone()
}
Run Code Online (Sandbox Code Playgroud)