Rust 学习笔记:关于切片的两个练习题

Rust 学习笔记:关于切片的两个练习题

参考视频:

  1. https://www.bilibili.com/video/BV1GrDQYeEzS

引用和切片引用的大小

考虑以下程序的 s2 和 s3 变量,它们的大小如何?

fn main() {
    let s = String::from("hello");
    let s2 = &s;
    let s3 = &s[..];
    
    println!("{}", size_of::<&String>());
    println!("{}", size_of::<&str>());
}

运行结果:

在这里插入图片描述

对于变量 s2,类型是 &String,它是一个引用。变量 s2 本身在内存中存储的是一个指针,在 64 位系统上,普通指针的大小是 8 字节,所以这个变量的大小是 size_of::<&String>(),即 8 字节。

而 s3 是切片,是 &str 类型,这是一个胖指针,包含指向数据的指针和长度,所以每个 &str 的大小是 16 字节。

以下程序能否通过编译?

fn main() {
    let mut s = String::from("hello");
    for &item in s.as_bytes().iter() {
        if item == b'l' {
            s.push_str(" world");
        }
    }
    println!("{s}");
}

不能通过编译。

s.as_bytes() 是对 s 的不可变借用,s.push_str() 是对 s 的可变借用,由于这里是在 for 循环中,会导致可变借用和不可变借用的作用于多次相互交叠,借用检查器为了安全起见,不允许这种做法。

改法一:从程序逻辑分析去修正,绕过借用问题

fn main() {
    let mut s = String::from("hello");
    let mut count = 0;
    for x in s.as_bytes().iter() {
        if *x == b'l' {
            count += 1;
        }
    }
    let to_push = " world".repeat(count);
    s.push_str(to_push.as_str());
    println!("{s}");
}

改法二:使用.to_owned()方法切断和源头的藕断丝连,使其自成一家

fn main() {
    let mut s = String::from("hello");
    for &item in s.as_bytes().to_owned().iter() {
        if item == b'l' {
            s.push_str(" world");
        }
    }
    println!("{s}");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值