rust

Rust ownership when returning struct


I'm fairly new to rust and I thought one way to learn it is to make a game in it. To make the game I'm using sdl2 (doesn't matter), but the code started to get messy. So I decided to split it up into different files. In of those files, I have created a struct, which has a public new function. Which will create a new instance of the struct.

pub struct Screen {
    sdl_context: Sdl,
    video_subsystem: VideoSubsystem,
    window: Window,
    event_pump: EventPump,
    canvas: Option<WindowCanvas>,
    pub width: u32,
    pub height: u32
}

impl Screen {
    pub fn new(width: u32, height: u32, title: &str) -> Self {
        let sdl_context = sdl2::init().unwrap();
        let video_subsystem = sdl_context.video().unwrap();
        let window = WindowBuilder::new(&video_subsystem, title, width, height).position_centered().build().unwrap();
        let canvas = window.into_canvas().accelerated().build().unwrap();
        let event_pump = sdl_context.event_pump().unwrap();

        Screen {sdl_context, canvas, event_pump, height, video_subsystem, width, window}
    }
}

My error:

error[E0382]: use of moved value: `window` --> src/screen.rs:23:82
let window = WindowBuilder::new(&video_subsystem, title, width, height).position_centered().build().unwrap();
                 ------ move occurs because `window` has type `sdl2::video::Window`, which does not implement the `Copy` trait
let canvas = window.into_canvas().accelerated().build().unwrap();
          ------------- `window` moved due to this method call
Screen {sdl_context, canvas, event_pump, height, video_subsystem, width, window}                                                                                  ^^^^^^ value used here after move

The problem I'm facing here is that most of the variables don't implement the Copy trait which results in an error about ownership when I try to make the struct with those variables. I have tried using references but the variable will not live long enough.

What's the best way to do this?


Solution

  • You're calling .into_canvas() on the window which takes ownership of it. It takes self (not &self) as the self parameter. Therefore you don't have it anymore to store in your struct; it has been moved elsewhere.

    The WindowCanvas you end up with will have ownership of the Window. There are methods like .window()/window_mut()/into_window() that you can use to access the window from the canvas if you need to.