rust的切片

切片

  • rust的另外一种不持有所有权的数据类型:切片(slice)
  • 一道题,编写一个函数:
  1. 它接收字符串作为参数
  2. 返回它在这个字符串里找到的第一个单词
  3. 如果函数找不到任何空格,那么整个字符串就被返回
fn main(){
    let mut s = String::from("hello world");
    let wordIndex = first_world(&s);
    // 删除String s 使其失效
    // 获取的wordIndex 不能在通过该支取获取后面的字符串
    s.clear();
    println!("wordIndex:{}", wordIndex);
}

fn first_world(s: &String)-> usize{
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate(){
        if item == b' '{
            return i;
        }
    }
    s.len()
}
fn main(){
    let mut s = String::from("hello world");    // 可变引用
    let str = first_world(&s);                  // s 作为不可变引用传入方法中
    // 编译报错,不能同时拥有可变引用和不可变引用
    // s.clear();
    println!("str:{}", str);
}
fn first_world(s: &String)-> &str{
    let bytes = s.as_bytes();
    for(i, &item) in bytes.iter().enumerate(){
        if item == b' '{
            return &s[..i];
        }
    }
    &s[..]
}

字符串切片

  • 字符串切片是指向字符串一部分内容的引用
  • 形式:[开始索引…结束索引]
  1. 开始索引就是切片起始位置的索引值
  2. 结束索引是切片终止位置的下一个索引值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iUmhF91T-1664259671687)(./qiepian.png)]
在这里插入图片描述

fn main(){
    let s = String::from("hello world");
    // 写法1
    // let hello = &s[0..5];
    // let world = &s[6..11];
    // 写法2
    let hello = &s[..5];
    let world = &s[6..s.len()];
    let whole = &s[..];
    println!("hello:{}, world:{}, whole:{}", hello, world, whole);
}

注意

  • 字符串切片的范围索引必须发生在有效的UTF-8字符边界内。
  • 如果尝试从一个多字节的字符中创建字符串切片,程序会报错并退出

字符串字面值是切片

  • 字符串字面值被直接存储在二进制程序中
// 类型是 &str 切片
let s = "hello world";
  • 变量s的类型是&str,它是一个执行二进制程序特定位置的切片
  1. &str是不可变引用,所以字符串字面值也是不可变得

将字符串切片作为参数传递

  • fn first_world(s: &String)-> &str{}
    有经验的rust开发者会采用&str作为参数类型,因为这样就可以同时接收String和&str类型的参数了
  • fn first_world(s: &str)-> &str{}
  1. 使用字符串切片,直接调用该函数
  2. 使用String,可以创建一个完整的String切片来调用改函数
  • 定义函数时使用字符串切片来代替字符串引用会使我们的API更加通用,且不会损失任何功能
fn main(){
    let str_1 = String::from("hello world");
    let res_1 = first_world(&str_1);
    
    let str_2 = "hello world";
    let res_2 = first_world(str_2);
    println!("rest_1:{}", res_1);
    println!("rest_2:{}", res_2);
}
fn first_world(s: &str)-> &str{
    let bytes = s.as_bytes();
    for(i, &item)in bytes.iter().enumerate(){
        if item == b' '{
            return &s[..i];
        }
    }
    &s[..]
}

其他类型的切片

fn main(){
    // 类型[i32; 4]
    let a = [3, 4, 5, 6];
    // 类型 &[i32]
    let slice = &a[1..=3];
    println!("slice:{:?}", slice);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值