Hi, Ollie, The working piece of code code: http://is.gd/dX7hzB
First of all, try to go through the official Rust guide [1]. It is mostly finished and it is *really* good. In particular, it explains what ownership is and how it should be managed. I’ve took your `example_box.rs` as a base and modified it as follows: 1. I’ve removed `Box`es everywhere. You shouldn’t use them unless you really know why you need them. You can read more on boxes and other kinds of pointers here [2]. You will need to do it anyway if you go through the guide [1] anyway. 2. I’ve made your functions to accept &mut Vec<Section> and &mut Section. This is exactly what ownership is about: these functions should not take ownership of their arguments, but they need to modify them, so &mut is the solution. Apart from that your code is mostly fine. Hope that helps! [1]: http://doc.rust-lang.org/guide.html [2]: http://doc.rust-lang.org/guide-pointers.html On 10 сент. 2014 г., at 18:05, Oldřich Vetešník <oldrich.vetes...@gmail.com> wrote: > Hello, > > I have a problem with creating a mutable nested data structure when combined > with functions. > I’m lost in all those &muts, boxes and lifetimes. :-) > > I would like to crawl a directory looking for subdirectories and in those > subdirectories find all images. > So I started with a vector for holding those subdirectories. > Then I created a struct to hold a directory path and a vector of images. > Also a struct for the image itself. > > It all works in one function body but not when refactored into functions. > I understand that when a variable is sent as an argument, the ownership is > moved so it cannot be used after the function call. > So I sent &-references instead but then it would yell at me that borrowed > things are not mutable. > So I &mut-ed it all and it would yell that lifetimes are not defined. > So I tried to define lifetimes but then it would say that things do not live > long enough. This is where I stopped. > I also tried the box-way but that yells about immutable dereference. I’m not > even sure I have those boxes right. > > This is the code: > (Also available here https://gist.github.com/ollie/9c81d2a368bf7bf0831a, > there is also a Ruby version not listed here.) > > > With references and lifetimes: > > #[deriving(Show)] > struct Image { > filename: String, > } > > #[deriving(Show)] > struct Section<'a> { > path: String, > images: &'a mut Vec<Image>, > } > > impl Image { > fn new(filename: &str) -> Image { > Image { > filename: String::from_str(filename), > } > } > } > > impl<'a> Section<'a> { > fn new(path: &str) -> Section { > Section { > path: String::from_str(path), > images: &mut Vec::new(), > } > } > > fn add_image(&mut self, image: Image) { > self.images.push(image); > } > } > > fn read_directories(sections: &mut Vec<&mut Section>) { > let dirs = ["./dir-a", "./dir-b"]; > > for dir in dirs.iter() { > let mut section = &mut Section::new(*dir); > read_images(section); > sections.push(section); > } > } > > fn read_images(section: &mut Section) { > let files = ["./image-1.png", "./image-2.png"]; > > for file in files.iter() { > section.add_image(Image::new(*file)); > } > } > > fn main() { > let mut sections = Vec::new(); > read_directories(&mut sections); > println!("{}", sections); > } > > > With boxes: > > #[deriving(Show)] > struct Image { > filename: String, > } > > #[deriving(Show)] > struct Section { > path: String, > images: Box<Vec<Image>>, > } > > impl Image { > fn new(filename: &str) -> Image { > Image { > filename: String::from_str(filename), > } > } > } > > impl Section { > fn new(path: &str) -> Section { > Section { > path: String::from_str(path), > images: box Vec::new(), > } > } > > fn add_image(&mut self, image: Image) { > self.images.push(image); > } > } > > fn read_directories(sections: Box<Vec<Box<Section>>>) { > let dirs = ["./dir-a", "./dir-b"]; > > for dir in dirs.iter() { > let mut section = box Section::new(*dir); > read_images(section); > sections.push(section); > } > } > > fn read_images(section: Box<Section>) { > let files = ["./image-1.png", "./image-2.png"]; > > for file in files.iter() { > section.add_image(Image::new(*file)); > } > } > > fn main() { > let mut sections = box Vec::new(); > read_directories(sections); > println!("{}", sections); > } > > > All in one, no referenes and lifetimes: > > #[deriving(Show)] > struct Image { > filename: String, > } > > #[deriving(Show)] > struct Section { > path: String, > images: Vec<Image>, > } > > impl Image { > fn new(filename: &str) -> Image { > Image { > filename: String::from_str(filename), > } > } > } > > impl Section { > fn new(path: &str) -> Section { > Section { > path: String::from_str(path), > images: Vec::new(), > } > } > > fn add_image(&mut self, image: Image) { > self.images.push(image); > } > } > > fn main() { > let mut sections = Vec::new(); > let dirs = ["./dir-a", "./dir-b"]; > > for dir in dirs.iter() { > let mut section = Section::new(*dir); > let files = ["./image-1.png", "./image-2.png"]; > > for file in files.iter() { > section.add_image(Image::new(*file)); > } > > sections.push(section); > } > > println!("{}", sections); > > // [ > // Section { > // path: ./dir-a, > // images: [Image { filename: ./image-1.png }, Image { filename: > ./image-2.png }] > // }, > // Section { > // path: ./dir-b, > // images: [Image { filename: ./image-1.png }, Image { filename: > ./image-2.png }] > // } > // ] > } > > I’ve read the tutorial, the rust-by-example site but it still feels alien to > me. :-/ > > Thank you, > Ollie > _______________________________________________ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev