VishnuK
VishnuK

Reputation: 1

Implement mem::swap in rust without std lib

I am trying to write a mem::swap function without using any std lib functions. i am totally new to rust and still trying to make sense of how to use rust language.

below is my code

fn swap<T: std::fmt::Display>(x: &mut T, y: &mut T) {
unsafe {
    // Give ourselves some scratch space to work with
    let mut t: &mut T = y;
    y = x;
    x = t;
    }
}
fn main() {
println!("Hello, world!");
let mut x = Box::new(5);
let mut y = Box::new(42);
let mut t = Box::new(0);
swap(&mut x, &mut y);
}

and i am facing below error

error: lifetime may not live long enough
 --> src/main.rs:4:29
  |
1 | fn swap<T: std::fmt::Display>(x: &mut T, y: &mut T) {
  |                                  -          - let's call the lifetime of this reference `'2`
  |                                  |
  |                                  let's call the lifetime of this reference `'1`
...
4 |         let mut t: &mut T = y;
  |                             ^ assignment requires that `'2` must outlive `'1`
  |
help: consider introducing a named lifetime parameter
  |
1 | fn swap<'a, T: std::fmt::Display>(x: &'a mut T, y: &'a mut T) {
  |         +++                           ++            ++

what does 'lifetime may not live long enough' mean ? is there a simple way to write mem::swap code in rust ?

Upvotes: 0

Views: 244

Answers (2)

xc wang
xc wang

Reputation: 372

How about using core::ptr::swap to swap raw pointers *mut T.

use core::ptr::swap;

fn custom_swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        (x as *mut T).swap(y as *mut T);
    }
}
fn main() {
    println!("Hello, world!");

    let mut x = Box::new(5);
    let mut y = Box::new(42);

    println!("x={}, y={}", x, y);

    custom_swap(&mut x, &mut y);

    println!("x={}, y={}", x, y);
}

output

Hello, world!
x=5, y=42
x=42, y=5

Upvotes: 0

tadman
tadman

Reputation: 211560

You need to Copy the data. The reference you're using is useless for this purpose. You need to actually alter what both x and y reference.

For example:

fn swap<T>(a: &mut T, b: &mut T) where T : Copy {
    (*a,*b) = (*b, *a)
}

fn main() {
    let mut a = 1;
    let mut b = 2;
    
    swap(&mut a,&mut b);
    
    println!("a={}, b={}", a, b);
}

If you set up the conditions here, it's really a one-liner, Rust will figure out the "temporary" stuff for you. In fact, having a function to do this is actually kind of overkill, since you can just do that single line anywhere in your code as you would normally.

Maybe you want to optimize this around boxed values, taking Box<T> as an argument instead, in which case you could swap references within the box instead of copying, but that's a specialization.

Upvotes: 2

Related Questions