[英]How do I return an owned array from a function?
我是一個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();
}
這當然無法使用此錯誤進行編譯:
pointers.rs:11:8: 11:21 error: cannot move out of dereference of & pointer
pointers.rs:11 self.thingies
如果這個代碼示例看起來不合適,我所要做的就是從已實現的結構中拉出一個數組。 借用的指針並不重要,它只是我試圖存儲數據的方式。
有關如何正確提取數組的任何提示?
順便說一下,我正在使用Rust 0.8
您的代碼無法編譯的原因是唯一指針~
只能有一個所有者。 編譯器阻止您編寫容易出錯的代碼。 你可以決定返回一個東西的副本,一個對東西的引用,或一片東西(它是對矢量數據或它的一部分的引用)。
復制解決方案
struct Widget {
thingies: ~[int]
}
impl Widget {
fn new() -> Widget {
Widget { thingies: ~[4, 8, 15, 16, 23, 42] }
}
fn somethings(&self) -> ~[int] {
self.thingies.clone()
}
}
參考方案
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
}
}
切片解決方案
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()
}
}
要了解參考和切片解決方案,您需要了解什么是'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
}
}
注意我相信在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的所有權模式對語言來說非常重要,因此有關更多信息,我建議查看有關所有權和借用的優秀官方文檔
=== 結束編輯 ===
在魯斯特, .
在self
之后,自動解除引用self
,所以這是錯誤提到dereference of & pointer
的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
您可以借用對thingies的引用:
fn somethings<'a>(&'a self) -> &'a~[int] {
&self.thingies
}
或明確返回一些東西
fn somethings(&self) -> ~[int] {
self.thingies.clone()
}
你無法擺脫借來的指針,正如其他答案中所解釋的那樣。 但是您可以通過值或擁有指針傳遞self
,然后您將能夠返回擁有的向量:
struct Widget {
thingies: ~[int]
}
impl Widget {
fn somethings(self) -> ~[int] {
self.thingies
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.