[][src]Function tao_of_rust::ch13::raw_pointer::raw_pointer

pub fn raw_pointer()

原生指针

用途:

Basic usage: 解引用原生指针

fn main() {
    let mut s = "hello".to_string();
    let r1 = &s as *const String;
    let r2 = &mut s as *mut String;
    assert_eq!(r1, r2);
    let address = 0x7fff1d72307d;
    let r3 = address as *const String;
    unsafe {
        println!("r1 is: {}", *r1);
       println!("r2 is: {}", *r2);
       // Segmentation fault  
       // assert_eq!(*r1, *r3)
   }
}Run

Basic usage: 创建空指针

fn main() {
    let p: *const u8 = std::ptr::null();
    assert!(p.is_null());
    let s: &str = "hello";
    let ptr: *const u8 = s.as_ptr();
    assert!(!ptr.is_null());
    let mut s = [1, 2, 3];
    let ptr: *mut u32 = s.as_mut_ptr();
    assert!(!ptr.is_null());
}Run

Basic usage: 使用offset偏移量

offset方法不能保证传入的偏移量合法,故为unsafe

fn main() {
    let s: &str = "Rust";
    let ptr: *const u8 = s.as_ptr();
    unsafe {
        println!("{:?}", *ptr.offset(1) as char); // u
        println!("{:?}", *ptr.offset(3) as char); // t
        println!("{:?}", *ptr.offset(255) as char); // ÿ 有UB风险
    }
}Run

Basic usage: 使用read/write

read/write也是unsafe方法

fn main() {
    let x = "hello".to_string();
    let y: *const u8 = x.as_ptr();
    unsafe {
        assert_eq!(y.read() as char, 'h');
    }
    let x = [0, 1, 2, 3];
    let y = x[0..].as_ptr() as *const [u32; 4];
    unsafe {
       assert_eq!(y.read(), [0,1,2,3]);
   }
   let x = vec![0, 1, 2, 3];
   let y = &x as *const Vec<i32>;
   unsafe {
        assert_eq!(y.read(), [0,1,2,3]);
   }
   let mut x = "";
   let y = &mut x as *mut &str;
   let z = "hello";
   unsafe {
       y.write(z);
       assert_eq!(y.read(), "hello");
   }
}Run

Basic usage: 使用replace/swap

也是unsafe方法,使用它们要注意自引用问题

fn main() {
   let mut v: Vec<i32> = vec![1, 2];
   let v_ptr : *mut i32 = v.as_mut_ptr();
   unsafe{
       let old_v = v_ptr.replace(5);
       assert_eq!(1, old_v);
       assert_eq!([5, 2], &v[..]);    
   }
   let mut v: Vec<i32> = vec![1, 2];
  let v_ptr  = &mut v as *mut Vec<i32>;
  unsafe{
      let old_v = v_ptr.replace(vec![3,4,5]);
      assert_eq!([1, 2], &old_v[..]);
      assert_eq!([3, 4, 5], &v[..]);   
  }
  let mut array = [0, 1, 2, 3];
  let x = array[0..].as_mut_ptr() as *mut [u32; 2];
  let y = array[1..].as_mut_ptr() as *mut [u32; 2];
  unsafe {
      assert_eq!([0, 1], x.read());
      assert_eq!([1, 2], y.read());
      x.swap(y);
      assert_eq!([1, 0, 1, 3], array);
  }
}Run