rust 数据类型与变量

1、定义变量

1. 不可变绑定

1. 自动类型推导

fn main() {
  let a1 = 5; // 自动推导数据类型i32
  let a2:i32 = 5; // 指定数据类型i32
}

2. 不可对变量重新[赋值]

fn main() {
  let a1 = 5; // 自动推导数据类型i32
  a1 = 10; // error: cannot assign twice to immutable variable `a1`
}
error[E0384]: cannot assign twice to immutable variable `a1`
  --> main.rs:14:3
   |
11 |   let a1 = 5; // 自动推导数据类型i32
   |       -- first assignment to `a1`
...
14 |   a1 = 10;
   |   ^^^^^^^ cannot assign twice to immutable variable

2. 可变绑定

1. 可以对变量重新赋值

fn main() {
  // 在声明变量时,在变量前面加入 mut 关键字,变量就会成为可变绑定的变量
  let mut a: f64 = 1.0;
  println!("{:?}", a);

  //改变变量a的值
  a = 2.0;
  println!("{:?}", a);
}
➜  main make
rustc main.rs
./main
1.0
2.0
➜  main

2. 也可以对变量重新绑定

fn main() {
  // 在声明变量时,在变量前面加入 mut 关键字,变量就会成为可变绑定的变量
  let mut a: f64 = 1.0;
  println!("{:?}", a);

  // 重新绑定为不可变
  let a1 = a;
  println!("{:?}", a1);
    
  // 重新绑定为可变
  let mut a2 = a;
  println!("{:?}", a2);
}
➜  main make
rustc main.rs
warning: variable does not need to be mutable
 --> main.rs:3:7
  |
3 |   let mut a: f64 = 1.0;
  |       ---^^
  |       |
  |       help: remove this `mut`
  |
  = note: #[warn(unused_mut)] on by default

warning: variable does not need to be mutable
  --> main.rs:10:7
   |
10 |   let mut a2 = a;
   |       ---^^^
   |       |
   |       help: remove this `mut`

./main
1.0
1.0
1.0
➜  main

会报警高,但是正常运行。

3. 局部作用域

fn main() {
  let long_lived_binding = 1;

  // 局部作用域
  {
    let short_lived_binding = 2;
    println!("inner short: {}", short_lived_binding);

    let long_lived_binding = 5_f32;
    println!("inner long: {}", long_lived_binding);
  }

  // println!("outer short: {}", short_lived_binding); //error:short_lived_binding局部作用域内的变量
  // FIXME ^ Comment out this line

  println!("outer long: {}", long_lived_binding);
}
➜  main make
rustc main.rs
./main
inner short: 2
inner long: 5
outer long: 1
➜  main

4. 类型比较

Yes

fn main() {
  let a1 = 5; // 自动推导数据类型i32
  let a2:i32 = 5; // 指定数据类型i32
  assert_eq!(a1, a2); // 比较a1与a2的【数据类型】是否一致
}
➜  main make
rustc main.rs
./main
➜  main

fn main() {
  let a1:u32 = 5;
  let a2:i32 = 5;
  assert_eq!(a1, a2);
}
➜  main make
rustc main.rs
error[E0308]: mismatched types
 --> main.rs:4:3
  |
4 |   assert_eq!(a1, a2);
  |   ^^^^^^^^^^^^^^^^^^^ expected u32, found i32

2、基本数据类型

1. 基本使用

  • 有符号整数: i8, i16, i32, i64isize (指针大小)
  • 无符号整数: u8, u16, u32, u64usize (指针大小)
  • 浮点: f32, f64
  • char Unicode标值一样 'a', 'α''∞' (每4字节)
  • bool 以及 truefalse
fn main() {
  // boolean type
  let f1 = true;
  let f2: bool = false;
  println!("{:?}", f1);
  println!("{:?}", f2);

  // char type
  let c = 'c';
  println!("{:?}", c);

  // numeric types
  let x = 42;
  let y: u32 = 123_456;
  let z: f64 = 1.23e+2;
  let zero = (z - 123.4).abs();
  let bin = 0b1111_0000;
  let oct = 0o7320_1546;
  let hex : u32 = 0xf23a_b049;

  println!("{:?}", x);
  println!("{:?}", y);
  println!("{:?}", z);
  println!("{:?}", zero);
  println!("{:?}", bin);
  println!("{:?}", oct);
  println!("{:?}", hex);
}
➜  main make
rustc main.rs
./main
true
false
'c'
42
123456
123.0
0.4000000000000057
240
15532902
4063932489
➜  main

2. isize、usize

  • i8、i32 => int8、int32
  • u8、u32 => uint8、uint32
  • f32、f64 => float32、float64
  • 数值如果不指定iN、uN、fN,则编译器自动使用 i32 为整数, f64 作为浮点数
fn main() {
  let x1 = 1u8; // 告诉编译器使用 uint8 分配内存来存储 1
  let x2 : u8 = 1; // 同上
  let x3 = 1i8; // 告诉编译器使用 int8 分配内存来存储 1
  let x4 : i8 = 1; // 同上

  let y1 = 2u32; // 告诉编译器使用 uint32 分配内存来存储 2
  let y2 : u32 = 2; 
  let y3 = 2i32; // 告诉编译器使用 uint32 分配内存来存储 1
  let y4 : i32 = 2;

  let z1 = 3f32; // 告诉编译器使用 float32 分配内存来存储 3
  let z2 : f32 = 3f32;
  let z3 : f64 = 3f64; // 告诉编译器使用 float64 分配内存来存储 3
  let z4 = 9.9;
}

3. 类型转换

fn main() {
  // float
  let a = 65.4321_f32;
  println!("{:?}", a);

  // float => uint8
  let b = a as u8;
  println!("{:?}", b);

  // uint8 => char
  let c = b as char;
  println!("{:?}", c);
}
➜  main make
rustc main.rs
./main
65.4321
65
'A'
➜  main

3、字符串

1. &str => 不可变字符数组

1. 基本使用

fn main() {
  let str1 = "Hello, world!"; // 自动推导类型为 &str
  let str2 : &str = "Hello, world!"; 
  println!("str1 = {:?}", str1);
  println!("&str1 = {:?}", &str1);
  println!("str2 = {:?}", str2);
  println!("&str2 = {:?}", &str2);
}
➜  main make
rustc main.rs
./main
str1 = "Hello, world!"
&str1 = "Hello, world!"
str2 = "Hello, world!"
&str2 = "Hello, world!"
➜  main

2. &str内部的地址

fn main() {
  let mystr :&str = "abcd";
  println!("mystr  address:  {:p}", &mystr);
  println!("mystr  address:  {:p}", &mystr[0..]);
  println!("mystr  address:  {:p}", &mystr[1..]);
  println!("mystr  address:  {:p}", &mystr[2..]);
  println!("mystr  address:  {:p}", &mystr[3..]);
}
➜  main make
rustc main.rs
./main
mystr  address:  0x7fff52bd45e0
mystr  address:  0x10d071040
mystr  address:  0x10d071041
mystr  address:  0x10d071042
mystr  address:  0x10d071043
➜  main
  • mystr 与 mystr[i] 内存地址段明显不一样
  • mystr => 存储在局部栈帧
  • mystr[i] => 常量字符存储在符号表中

2. string => 可变字符数组

fn main() {
 let info1 = String::from("hello");
 println!("info1 = {:?}", info1);

 let info2 : String = String::from("hello");
 println!("info2 = {:?}", info2);
}
➜  main make
rustc main.rs
./main
info1 = "hello"
info2 = "hello"
➜  main

3. String 的内存结构

let s1 =String::from("hello");

[图片上传失败...(image-deab1b-1534067123291)]

&str的内存结构差不多,只是不可变的。

4. &str => string

fn main() {
  let str1 = "hello".to_string();
  println!("str1 = {:?}", str1);

  let str2 : &str = "hello";
  let str3 = str2.to_string();
  println!("str3 = {:?}", str3);
}
➜  main make
rustc main.rs
./main
str1 = "hello"
str3 = "hello"
➜  main

5. string => &str

fn main() {
  // String
  let info = String::from("hello");

  // &str 1
  let info_str1 = info.as_str();
  println!("info_str1 = {:?}", info_str1);

  // &str 2
  let info_str2 = &info;
  println!("info_str2 = {:?}", info_str2);
}
➜  main make
rustc main.rs
./main
info_str1 = "hello"
info_str2 = "hello"
➜  main

6. string = string + &str

fn main() {
  let info = String::from("hello");
  let new = info + "world";
  // println!("info = {:?}", info); //error: use of moved value: `info`
  println!("new = {:?}", new);
}
➜  main make
rustc main.rs
./main
new = "helloworld"
➜  main

7. string push_str()、pop_str()

1. push

fn main() {
  let mut info = String::from("hello");
  println!("info = {:?}", info);
    
  // 压入字符
  info.push('-');
  
  // 压入字符串
  info.push_str("world");
  println!("info = {:?}", info); 
}
➜  main make
rustc main.rs
./main
info = "hello"
info = "hello-world"
➜  main

2. pop

fn main() {
  let mut s = String::from("foo");
  assert_eq!(s.pop(), Some('o'));
  assert_eq!(s.pop(), Some('o'));
  assert_eq!(s.pop(), Some('f'));
  assert_eq!(s.pop(), None);
}
➜  main make
rustc main.rs
./main
➜  main

8. format

fn main() {
  let str1 : &str = "hello";
  let str2 : String = String::from("world");
  let str3 = format!("{0} - {1}", str1, str2);
  println!("str3 = {:?}", str3);
}
➜  main make
rustc main.rs
./main
str3 = "hello - world"
➜  main

9. &str、String 字符串切割

1. 只能对 &str、&String 进行切割

fn main() 
{
  // &str
  let mystr:&str = "abcd";
  println!("mystr :{:?}", &mystr[1..2]);   //"bc"
  println!("mystr :{:?}", &mystr[1..]);   //"bcd"
  println!("mystr :{:?}", &mystr[..]);    // "abcd"

  // &String
  let my_str:String = "ABCD".to_string();
  println!("my_str :{:?}", &my_str[1..2]); //"BC"
  println!("my_str :{:?}", &my_str[1..]); //"BCD"
  println!("my_str :{:?}", &my_str[..]);  //"ABCD"
}
➜  main make
rustc main.rs
./main
mystr :"b"
mystr :"bcd"
mystr :"abcd"
my_str :"B"
my_str :"BCD"
my_str :"ABCD"
➜  main

2. 不能对 str、String 直接切割

fn main() 
{
  // &str
  let mystr:&str = "abcd";
  println!("mystr :{:?}", mystr[1..]); //  =>error

  // &String
  let my_str:String = "ABCD".to_string();
  println!("my_str :{:?}", my_str[1..]); //  =>error 
}
➜  main make
rustc main.rs
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
 --> main.rs:5:3
  |
5 |   println!("mystr :{:?}", mystr[1..]); //  =>error
  |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `str` does not have a constant size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `str`
  = note: required by `std::fmt::ArgumentV1::new`
  = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
 --> main.rs:9:3
  |
9 |   println!("my_str :{:?}", my_str[1..]); //  =>error
  |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `str` does not have a constant size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `str`
  = note: required by `std::fmt::ArgumentV1::new`
  = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error: aborting due to 2 previous errors

make: *** [all] Error 101
➜  main

10. String.extend(&['a','b','c'])

fn main() {
  let mut message = String::from("==> ");
  message.extend(&['a', 'b', 'c']);
  println!("message = {:?}", message);
}
➜  main make
rustc main.rs
./main
message = "==> abc"
➜  main

4、数组

1. 不可变数组

fn main() {
  let arr1 = [0, 1, 2, 3, 4];
  println!("{:?}", arr1);

  let arr2 = &arr1[1..3];
  println!("{:?}", arr2);
}
➜  main make
rustc main.rs
./main
[0, 1, 2, 3, 4]
[1, 2]
➜  main

2. 可变数组

fn main() {
  // [i32; 3] => [数组元素类型 : 数组长度]
  // [0; 3] => 使用0填充3个位置
  let mut array : [i32; 3] = [0; 3];

  for x in &array {
    print!("{} ", x);
  }
  println!("");

  // 修改数组[i]
  array[1] = 1;
  array[2] = 2;

  // 
  for x in &array {
    print!("{} ", x);
  }
  println!("");
}
➜  main make
rustc main.rs
./main
0 0 0
0 1 2
➜  main

3. Vec

1. 不可变 Vec

fn main() {
  //创建空Vec
  let v: Vec = Vec::new();

  //使用宏创建空Vec
  let v: Vec = vec![];

  //创建包含5个元素的Vec
  let v = vec![1, 2, 3, 4, 5];

  //创建十个零
  let v = vec![0; 10];
}

2. 可变 Vec

fn main() {
  //创建可变的Vec,并压入元素3
  let mut v = vec![1, 2];
  v.push(3);

  //创建拥有两个元素的Vec,并弹出一个元素
  let mut v = vec![1, 2];
  let two = v.pop();
  
  //创建包含三个元素的可变Vec,并索引一个值和修改一个值
  let mut v = vec![1, 2, 3];
  let three = v[2];
  v[1] = v[1] + 5;
}

3. 珂理化初始化方式

fn main()
{
  let x: Vec = {
    let mut temp_vec = Vec::new();
    temp_vec.push(1);
    temp_vec.push(2);
    temp_vec.push(3);
    temp_vec
  };
  println!("{:?}", x)
}
➜  main make
rustc main.rs
./main
[1, 2, 3]
➜  main

5、元祖

1. 构建元祖

fn main() {
  // 不可变绑定形式的元祖1
  // arg1 => int 32 值
  // arg2 => &string 内存地址
  let tuple1: (i32, &str) = (50, "hello");
  println!("tuple1 = {:?}", tuple1);

  // 不可变绑定形式的元祖2
  let age = 99;
  let name : &str = "hello";
  let tuple2: (i32, &str) = (age, name);
  println!("tuple2 = {:?}", tuple2);
}
➜  main make
rustc main.rs
./main
tuple1 = (50, "hello")
tuple2 = (99, "hello")
➜  main

2. 元祖内元素的可选绑定与不可选绑定

fn main() {
  // 元祖
  // => a 不可变绑定
  // => b 可变绑定
  let (a, mut b): (bool,bool) = (true, false);
  println!("a = {:?}, b = {:?}", a, b);

  // a 不可变绑定
  // a = false; // error: cannot assign twice to immutable variable `a`

  // b 可变绑定
  b = true;

  // 数据类型比较
  assert_eq!(a, b);
}
➜  main make
rustc main.rs
./main
a = true, b = false
➜  main

3. 绑定其他元祖内的元素

fn main() {
  // 不可变绑定形式的元祖1
  // arg1 => int 32 值
  // arg2 => &string 内存地址
  let tuple: (i32, &str) = (50, "hello");
  println!("tuple = {:?}", tuple);

  // 绑定上面定义的元祖的arg1
  let (arg1_1, _) = tuple;
  let arg1_2 = tuple.0;
  println!("arg1_1 = {:?}", arg1_1);
  println!("arg1_2 = {:?}", arg1_2);

  // 绑定上面定义的元祖的arg2
  let arg2 = tuple.1;
  println!("arg2 = {:?}", arg2);
}
➜  main make
rustc main.rs
./main
tuple = (50, "hello")
arg1_1 = 50
arg1_2 = 50
arg2 = "hello"
➜  main

6、指针

1. [内存地址] as *const T

1. C语言中的 const T* const p;

指针变量的不能改变

fn main() {
  let x = 5;

  //【不可变绑定】对变量取地址
  let ptr = &x as *const i32;
  println!("ptr = {:p}", ptr);

  // unsafe{...} 对指针进行【解地址】读取内存空间的数据
  let val = unsafe { *ptr };
  println!("val = {:?}", val);
}
➜  main make
rustc main.rs
./main
ptr = 0x7fff5135971c
val = 5
➜  main

2. C语言中的 T* const p;

指针变量指向内存的值不能改变

fn main() {
  let x = 5;
  let y = 6;

  //【可变绑定】对变量取地址
  let mut ptr = &x as *const i32;
  println!("ptr = {:p}", ptr);

  // 解地址读取内存空间的数据
  let val = unsafe { *ptr };
  println!("*ptr = {:?}", val);

  // 重新指向其他变量标记的内存地址
  ptr = &y;
  println!("*ptr = {:?}", unsafe{*ptr});
}
➜  main make
rustc main.rs
./main
ptr = 0x7fff5ac9b6c8
*ptr = 5
*ptr = 6
➜  main

2. [内存地址] as *mut T

1. const指针转换为mut指针

fn main() {
  // 栈帧上局部变量
  let x = 5;

  // *const T 类型指针
  let ptr1 = &x as *const i32;
  // let ptr1 : *const i32 = &x as *const i32; // 同上
  println!("*ptr1 = {:?}", unsafe {*ptr1});

  // *const T => *mut T
  let ptr2 = ptr1 as *mut i32;

  // 修改 *mut T 类型指针变量指向的内存空间中的数据
  unsafe {*ptr2 = 6};
  println!("*ptr2 = {:?}", unsafe {*ptr2});
}
➜  main make
rustc main.rs
./main
*ptr1 = 5
*ptr2 = 6
➜  main

2. 直接定义 mut 类型变量与指针变量

fn main() {
  // 直接定义mut可变绑定类型变量
  let mut x = 2;

  // 获取可变绑定类型变量的内存地址
  let ptr = &mut x as *mut i32;

  // 读取地址空间中的数据
  println!("*ptr = {:?}", unsafe {*ptr});

  // 修改地址空间中的数据
  unsafe {*ptr = 3}; 
  println!("*ptr = {:?}", unsafe {*ptr});
}
➜  main make
rustc main.rs
./main
*ptr = 2
*ptr = 3
➜  main

7、结构体

1. 定义结构体与使用

struct Point {
  x: f64,
  y: f64,
}

fn main() {
  // 创建struct实例
  let point: Point = Point { x: 0.3, y: 0.4 };
  println!("point coordinates: ({}, {})", point.x, point.y);

  // 绑定获取struct实例成员的值
  let Point { x: my_x, y: my_y } = point;
  println!("my_x = {}, my_y = {}", my_x, my_y);
}
➜  main make
rustc main.rs
./main
point coordinates: (0.3, 0.4)
my_x = 0.3, my_y = 0.4
➜  main

2. 不能在struct内定义mut类型成员

struct Point {
  mut x: i32, // error
  y: i32,
}

3. 成员具有默认值

#[derive(Default)] // 成员初始化默认值
#[derive(Debug)]   // println!("{:?}", struct实例);
struct Point3d {
  x: i32,
  y: i32,
  z: i32,
}

fn main()
{
  // 创建struct实例,并给成员默认初始化
  let origin = Point3d::default();
  println!("{:?}", origin);

  // 赋值实例的成员y
  let point = Point3d { y: 1, ..origin };
  println!("{:?}", point);
    
  // 获取struct实例的成员x、成员y的值
  let Point3d { x: x0, y: y0, .. } = point;
  println!("{} - {}", x0, y0);
}
➜  main make
rustc main.rs
./main
Point3d { x: 0, y: 0, z: 0 }
Point3d { x: 0, y: 1, z: 0 }
0 - 1
➜  main

4. struct之间的包含

#[derive(Debug)]
struct Point {
  x: f64,
  y: f64,
}

#[allow(dead_code)] //包含其他的struct作为成员
#[derive(Debug)]
struct Rectangle {
  p1: Point,
  p2: Point,
}

fn main() {
  // 创建Point实例
  let point: Point = Point { x: 0.3, y: 0.4 };
  println!("point coordinates: ({}, {})", point.x, point.y);

  // 创建Rectangle实例
  let rectangle = Rectangle {
    p1: Point { x: point.x + 0.5, y: point.y + 0.5},
    p2: point,
  };
  println!("{:?}", rectangle);
}
➜  main make
rustc main.rs
./main
point coordinates: (0.3, 0.4)
Rectangle { p1: Point { x: 0.8, y: 0.9 }, p2: Point { x: 0.3, y: 0.4 } }
➜  main

5. 元祖类型的struct

struct Pair(i32, f64);

fn main() {
  // Instantiate a tuple struct
  let pair = Pair(1, 0.1);

  // Destructure a tuple struct
  let Pair(a, b) = pair;
  println!("a = {:?}, b = {:?}", a, b);
}
➜  main make
rustc main.rs
./main
a = 1, b = 0.1
➜  main

6. Nil struct

#[derive(Debug)]
struct Nil;

fn main() {
  let _nil = Nil;
  println!("{:?}", _nil);
}
➜  main make
rustc main.rs
./main
Nil
➜  main

7. 结构体成员可变

use std::cell::Cell;

#[derive(Debug)]
struct Point {
  x: i32,
  y: Cell,
}

fn main()
{
  let point = Point { x: 5, y: Cell::new(6) };
  println!("{:?}", point);

  point.y.set(7);
  println!("{:?}", point);
}
➜  main make
rustc main.rs
./main
Point { x: 5, y: Cell { value: 6 } }
Point { x: 5, y: Cell { value: 7 } }
➜  main

8. mod内定义struct

1. mod内定义struct必须使用pub修饰,才能被外部使用

mod graph {
  #[derive(Default)]
  #[derive(Debug)]
  struct Point {
    x: i32,
    y: i32,
  }

}

fn main()
{
  let point = graph::Point::default(); // error
}
➜  main make
rustc main.rs
error[E0603]: struct `Point` is private
  --> main.rs:13:15
   |
13 |   let point = graph::Point::default(); // error
   |               ^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

make: *** [all] Error 101
➜  main

2. mod内的struct成员也必须使用pub修饰

mod graph {
  #[derive(Default)]
  #[derive(Debug)]
  pub struct Point {
    pub x: i32,
    y: i32,
  }

}
fn main()
{
  let point = graph::Point::default();
  println!("{:?}", point);
  println!("{:?}", point.x);
  println!("{:?}", point.y); // error: field `y` of struct `graph::Point` is private
}
➜  main make
rustc main.rs
error[E0616]: field `y` of struct `graph::Point` is private
  --> main.rs:15:20
   |
15 |   println!("{:?}", point.y); // error: field `y` of struct `graph::Point` is private
   |                    ^^^^^^^

error: aborting due to previous error

make: *** [all] Error 101
➜  main

去掉访问point.y即可正常执行

➜  main make
rustc main.rs
./main
Point { x: 0, y: 0 }
0
➜  main

3. mod内定义操作struct实例的外部调用函数

mod graph {
  use std::cell::Cell;

  #[derive(Default)]
  #[derive(Debug)]
  pub struct Point {
    x: Cell, // mod 私有成员
    y: Cell, // mod 私有成员
  }

  pub fn init(p: Point, x: i32, y: i32) {
    p.x.set(x);
    p.y.set(y);
    println!("{:?}", p);
  }
}
fn main()
{
  let point = graph::Point::default();
  graph::init(point, 99, 100);
}
➜  main make
rustc main.rs
./main
Point { x: Cell { value: 99 }, y: Cell { value: 100 } }
➜  main

9. 枚举 => enum内定义struct

#[derive(Debug)]
enum Message {
  Quit,
  ChangeColor(i32, i32, i32), // 元祖类型结构体
  Move { x: i32, y: i32 }, // 字段类型结构体
  Write(String), // 元祖类型结构体
}

fn main()
{
  let a: Message = Message::Quit;
  let b: Message = Message::ChangeColor(1,2,3);
  let c: Message = Message::Move { x: 3, y: 4 };
  let d: Message = Message::Write(String::from("hello"));

  println!("{:?}", a);
  println!("{:?}", b);
  println!("{:?}", c);
  println!("{:?}", d);
}
➜  main make
rustc main.rs
./main
Quit
ChangeColor(1, 2, 3)
Move { x: 3, y: 4 }
Write("hello")
➜  main

9、type 类型别名

fn main() {
  type NanoSecond = u64;
  type Point = (u8, u8);

  let x : NanoSecond = 19999;
  let y : Point = (1,2);

  println!("x = {:?}", x);
  println!("y = {:?}", y);
}
➜  main make
rustc main.rs
./main
x = 19999
y = (1, 2)
➜  main

10、常量 与 静态量

1. 常量

const N: i32 = 5;

2. 静态全局变量

static N: i32 = 5; // 注意:必须标注一个静态的类型

3. 静态变量可变性

static mut N: i32 = 5;

4. 静态全局变量的多线程同步

static mut N: i32 = 5;

// 读写包裹在unsafe{}块中执行
unsafe {
  N += 1;
  println!("N: {}", N);
}

10、编译属性

1.【启用/关闭】编译属性

1. 启用

#[属性名(参数)]

2. 关闭

#![属性名(参数)] 

[前面加上一个!符号。

2. 开启 debug

#[derive(Debug)]

3. 开启 inline 内联

#[inline(always)]

4. 使用自定义编译属性

#[cfg(test)]

5. 使用系统预定义编译属性

#[cfg(target_os = "macos")]

你可能感兴趣的:(rust 数据类型与变量)