返回介绍

2.4 转换

发布于 2024-10-13 11:25:28 字数 2024 浏览 0 评论 0 收藏 0

不支持隐式转换,可用 as 进行安全类型转换(safe casting)。

fn test(x: i64) {
  println!("{:?}", x);
}

fn main() {
  let x: i32 = 100;
  
  let _y = x as i64;
  let _z = x as i64 as i128;

  test(x as i64);
}

数字转换:

  • 相同大小(i32 -> u32)。
  • 大到小(u32 -> u8),截短(truncate)。
  • 小到大(u8 -> u32),扩展(zero-extend or sign-extend)。
  • 浮点数到整数,舍弃小数部分(round)。
  • 整数到浮点数。
  • 从 f32 到 f64,无损。
  • 从 f64 到 f32,近似值。
fn main() {
  let x = 1.66;
  let y = x as i32;

  assert_eq!(y, 1);
}

引用转换

可将引用转换为指针,或改为不可变引用。

  • &mut T -> &T : 安全转换。(反之不行,invalid cast)
  • &mut T or &T -> ptr : 原始指针操作需要 unsafe 保证。
fn main() {
  let mut x = 100;
  let mr = &mut x;   

  // let _r = &x;
  //      ^^ immutable borrow occurs here

  // ----------------------------------------
  
  // &mut T -> &T
  let r = mr as &i32;   // 转换,非借用。
  assert_eq!(100, *r);

  // &mut T -> *const T
  let p = mr as *const i32;     
  assert_eq!(100, unsafe{ *p });

  // &mut T -> *mut T
  let mp = mr as *mut i32;    
  unsafe {
    *mp += 1;
    assert_eq!(101, x);
  }
}

自动转换

Deref 特征(trait)实现的自动转换。

fn main() {
  let s = String::from("abc");
  let rs: &str = &s;      // &String to &str

  println!("{:?}", rs);
}
fn main() {
  let v = vec![1, 2, 3];
  let s: &[i32] = &v;      // &Vec<T> to &[T]

  println!("{:?}", s);
}
fn main() {
  let b = Box::<i32>::new(100);
  let r: &i32 = &b;        // &Box<T> to &T

  assert_eq!(*r, 100);
}
  • 非安全类型转换: std::mem::transmute
  • 自定义类型转换: std::convert::From

Casting Between Types

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文