RUST速成-变量, 引用,结构体, 函数

说明

rust 的变量,结构体,函数等概念和其他语言基本类似。

区别在于,变量有 不可变变量(immutable)和可变变量(mutable);

变量

rust是强类型语言,所有变量在使用之前需要先用 let 关键字定义;

fn main() {
    let h: i32 = 10; // 定义一个32位有符号整型变量h,为不可变变量,初始值为10
    println!("h={}", h);

    // 修改不可变变量 h 会导致编译出错
    // h = 20;
}
fn main() {
    let mut m: u64 = 99; // 定义一个64位无符号整型变量 m ,mut代表可变变量,初始值为99
    println!("before changing, m={}", m);
    m = 100; // 修改 m 的值
    println!("after changing, m={}", m);
}
fn main() {
    let h: i32 = 10; // 定义一个32位有符号整型不可变变量 h ,值为10
    println!("first h={}", h);
    let h: i64 = 20; // 重新定义变量 h
    println!("second h={}", h);
}

引用

 rust 的引用和C++的引用类似,可以理解是变量的别名。

引用的规则:

  • rust的引用分 “可变应用” 和 “不可变引用”
  • 可变变量:可以有且只有1个“可变引用” 或者 多个“不可变引用”
  • 不可变变量:可以有多个“不可变引用”,不能有可变引用
  • 一个变量不能同时存在“可变引用”和“不可变引用”
  • 一个变量如果存在可变引用,在可变引用的作用范围内,不可以使用原变量

从内存安全角度来看这些规则很好理解。

  • 如果存在多个“可变引用”,就可能同时存在写操作的冲突
  • 如果存在“可变引用” 和 “不可变引用”,写操作和读操作会有冲突
  • 如果存在 多个 “不可变引用”,都是读操作,没有冲突
fn main() {
    let v: i32 = 10;
    let r1: &i32 = &v;  // 不可变引用
    let r2 = &v;  // r1 和 r2都是 v 的不可变引用
    println!("immutable v {}, r1 {}, r2 {}", v, r1, r2);
    // r1
    
    let mut v: i32 = 10;  // 可变变量才能可变引用
    let r1 = &mut v;  // r1 是 v 的可变引用

    // let r2 = &mut v; // 已经有一个可变引用r1,再创建一个可变引用 r2 会编译出错
    // println!("mutable v {}", v); // 已经有一个可变引用 r1,不能再访问原变量 v

    *r1 = 100; // 写操作,修改可变引用的变量值
    println!("mutable reference r1 {}", r1); // 访问可变引用 r1 
    
    // rust会自动判断可变引用 r1 已经不再被使用
    // 所以这里可以继续访问原变量
    println!("mutable v {}", v); 
}

函数

函数用 fn 关键字声明。

// 没有参数的函数
fn test0() {
    println!("test0() without args");
}

// 有 1 个参数的函数
fn test1(h: i32) {
    println!("test1() with one arg {}", h);
}

// 有多个参数的函数
fn test2(h1: i32, h2: i32, h3: i32) {
    println!("test2() with args, h1 {}, h2 {}, h3 {}", h1, h2, h3);
}

// 有 1 个返回值的函数
fn test3() -> i32 {
    let h: i32 = 33;
    return h;
}

// 有多个返回值的函数
fn test4() -> (i32, i32, i32) {
    return (41, 42, 43);
}

// 最后一条语句如果是 return 语句,可以省掉 return 关键字且行尾没有分号
fn test5() -> i32 {
    let h: i32 = 33;
    h
}

// 参数是引用的函数
fn test6(n: &i32) -> i32 {
    *n // 解引用并返回
}


fn main() {
    test0();    // 调用函数,无参数
    test1(11);  // 调用函数,1个参数
    test2(21, 22, 34); // 调用函数,多个参数
    
    let h = test3();
    println!("test3() return {}", h);
    
    let (h1, h2, h3) = test4();
    println!("test4() return ({}, {}, {})", h1, h2, h3);

    let h = test5();
    println!("test5() return {}", h);


    let n = 111;
    let h = test6(&n);
    println!("test6() return {}", h);
}

 结构体

结构体用 struct 关键字声明,是用户自定义的数据类型。

// 声明结构体 Point
struct Point{
    x: i32,
    y: i32, 
}

fn main() {
    let point: Point = Point{x: 1, y: 2}; // 定义 Point 变量
    println!("Point: x={}, y={}", point.x, point.y);
    
    let point = Point{x: 3, y: 4}; // 可以省略变量类型,编译会自动推断出类型
    println!("Point: x={}, y={}", point.x, point.y);
}

类型成员函数

// 声明结构体 Point
struct Point{
    x: i32,
    y: i32, 
}

impl Point {
    fn new(x0: i32, y0: i32) -> Self { // Self 是指当前类型 Point
        Self{ x: x0, y: y0,} // 新建 Point 对象并返回
    }
    
    // self 类似 C++ 或 Java 的 this
    fn get(&self) -> (i32, i32) {
        return (self.x, self.y);
    }
}

fn main() {
    let point: Point = Point::new(1, 2); 
    println!("Point: x={}, y={}", point.x, point.y);
    
    let (x, y) = point.get();
    println!("point.get(): x={}, y={}", x, y);
    
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值