返回介绍

2.3 类型

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

静态类型(statically type),编译时必须确定所有变量和常量类型(显式声明或值推断)。内置类型分为 标量类型 (scalar type)和 复合类型 (compound type)。

标量类型

固定长度(fixed width),存储单值。

  • 整数: i8 / u8 , i16 / u16 , i32 / u32 , i64 / u64 , i128 / u128 ,
    isize / usize
  • 浮点: f32 , f64
  • 布尔: bool (1 byte, true / false
  • 字符: char (4 bytes,Unicode, 'A'

与机器架构相关(machine-dependent)的 isize/usize 长度与平台指针类型相同。

use std::mem::size_of_val;

fn main() {
  let c: char = '我';
  println!("{}, {}", size_of_val(&c), c);   // 4, 我
}
use std::mem::size_of_val;

fn main() {
  let x = b'A';   // u8, byte
  let y = 'A';  // char, unicode

  println!("{:?} {:?}", x, size_of_val(&x));  // 65  1
  println!("{:?} {:?}", y, size_of_val(&y));  // A   4
}

默认i32f64

进制0xff , 0o34 , 0b1111_0000

操作+、-、*、/、%&、|、^、<<、>>&&、||、!

后缀100i64100isize0x64u32

分隔12_345100_i64

复合类型

相同或不同类型的多值集合。

  • 元组(tuple): 长度固定,元素类型可不同。
  • 数组(array): 长度固定,元素类型相同。

元组

序号(.index)访问,不支持迭代。解构(destructure)时,左右数量相等,或以 .. 忽略。

  • 可用于函数多返回值。
  • 解构表达式中, .. 只能出现一次。
  • 编译器对元素内存对齐处理。
fn main() {
  let t: (i32, f32, char) = (10, 1.23, 'a');   // 以初始化值推断成员类型。
  assert_eq!(t.1, 1.23);             // 以序号访问成员。
  assert_eq!(t.2, 'a');

  let (x, y, _z) = t;              // 解构
  assert_eq!(y, 1.23);
}
fn main() {
  let (_x, _y) = (1, 2, 3);
     ^
     expected a tuple with 3 elements, found one with 2 elements
}
fn main() {
  let (_x, .., _y) = (1, 2, 3, 4, 5, 6);
  let (_x, _y, ..) = (1, 2, 3, 4, 5, 6);
  let (.., _x, _y) = (1, 2, 3, 4, 5, 6);
}

不含元素的元组,称做 unit

  • () 表示该类型或其唯一值。
  • 如无声明,则表达式(如函数)隐式返回 ()
  • 被忽略的值,如 Result<(), Error>
use std::mem::size_of_val;

fn main() {
  let x = (0);  // 被括号包含的零。
  let y = ();   // unit
  let z = (0,);   // 只有单个元素的元组。

  assert_eq!(type_of(&x), "i32"); 
  assert_eq!(size_of_val(&x), 4);

  assert_eq!(type_of(&y), "()");
  assert_eq!(size_of_val(&y), 0);

  assert_eq!(type_of(&z), "(i32,)");
  assert_eq!(size_of_val(&z), 4);
}

数组

数组类型 [type; length] 。长度是类型组成部分,以下标索引访问。

  • 初始化 [elem1, elem2 ...][value; length]
  • 以向量 Vec<T> 实现可变长度。
  • 以切片 &[T] 完成排序、搜索等操作。

即便 “很大” 的数组,默认也分配在栈上,仅受 ulimit -s 限制。

fn main() {
  let a = [1, 2, 3];       // 推断数组元素类型。
  assert_eq!(a.len(), 3);    // 长度
  assert_eq!(a[1], 2);       // 以序号访问。

  let b: [i64; 10] = [7; 10];  // = [元素初始化值; 长度]。
  assert_eq!(b[1], 7);
  assert_eq!(b[9], 7);
}
fn main() {
  let data = [1, 2, 3, 4];

  for d in data {         // 2021 Edition
    println!("{:?}", d);
  }
}
fn main() {
  let _b = [0; 8192 << 10];  // stack overflow
}                // ulimit -s: 8192 kbytes

长度必须是编译期常量(表达式)。

fn main() {
  let n = 100;
  let _x: [i32; n];   // 类型声明
          ^ non-constant value
}
fn main() {
  let n = 100;
  let _x = [0i64; n]; // 初始化语句
          ^ non-constant value
}

索引是 usize 类型。

fn main() {
  let a = [1, 2, 3];
  let i: i32 = 1;

  println!("{:?}", a[i]);
             ^ slice indices are of type `usize`
}

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

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

发布评论

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