【Rust练习】9.切片

34 篇文章 0 订阅
10 篇文章 0 订阅

练习题来自:https://practice-zh.course.rs/compound-types/slice.html

1 这里, [i32] 和 str 都是切片类型,但是直接使用它们会造成编译错误,如下代码所示。为了解决,你需要使用切片的引用: &[i32],&str。

// 修复代码中的错误,不要新增代码行!
fn main() {
    let arr = [1, 2, 3];
    let s1: [i32] = arr[0..2];

    let s2: str = "hello, world" as str;
}

切片( 引用 )可以用来借用数组的某个连续的部分,对应的签名是 &[T]。

fn main() {
    let arr = [1, 2, 3];
    let s1: &[i32] = &arr[0..2];

    let s2: &str = "hello, world";
}

2

fn main() {
    let arr: [char; 3] = ['中', '国', '人'];

    let slice = &arr[..2];
    
    // 修改数字 `8` 让代码工作
    // 小提示: 切片和数组不一样,它是引用。如果是数组的话,那下面的 `assert!` 将会通过: '中'和'国'是char类型,char类型是Unicode编码,大小固定为4字节,两个字符为8字节。
    assert!(std::mem::size_of_val(&slice) == 8);
}

一个切片引用占用了2个字大小的内存空间( 从现在开始,为了简洁性考虑,如无特殊原因,我们统一使用切片来特指切片引用 )。 该切片的第一个字是指向数据的指针,第二个字是切片的长度。字的大小取决于处理器架构,例如在 x86-64 上,字的大小是 64 位也就是 8 个字节,那么一个切片引用就是 16 个字节大小。

fn main() {
    let arr: [char; 3] = ['中', '国', '人'];

    let slice = &arr[..2];
    
    assert!(std::mem::size_of_val(&slice) == 16);
}

3

fn main() {
   let arr: [i32; 5] = [1, 2, 3, 4, 5];
  // 填空让代码工作起来
  let slice: __ = __;
  assert_eq!(slice, &[2, 3, 4]);
}

填写正确的切片类型和切片语法即可。

fn main() {
    let arr: [i32; 5] = [1, 2, 3, 4, 5];
   // 填空让代码工作起来
   let slice: &[i32] = &arr[1..4];
   assert_eq!(slice, &[2, 3, 4]);
 }

4

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

    let slice1 = &s[0..2];
    // 填空,不要再使用 0..2
    let slice2 = &s[__];

    assert_eq!(slice1, slice2);
}
fn main() {
    let s = String::from("hello");

    let slice1 = &s[0..2];
    let slice2 = &s[..2];

    assert_eq!(slice1, slice2);
}

5

fn main() {
    let s = "你好,世界";
    // 修改以下代码行,让代码工作起来
    let slice = &s[0..2];

    assert!(slice == "你");
}

中文字符占用两个字节,因此需要用[0..3]来索引

fn main() {
    let s = "你好,世界";
    // 修改以下代码行,让代码工作起来
    let slice = &s[0..3];

    assert!(slice == "你");
}

6 &String 可以被隐式地转换成 &str 类型.

// 修复所有错误
fn main() {
    let mut s = String::from("hello world");

    // 这里, &s 是 `&String` 类型,但是 `first_character` 函数需要的是 `&str` 类型。
    // 尽管两个类型不一样,但是代码仍然可以工作,原因是 `&String` 会被隐式地转换成 `&str` 类型,如果大家想要知道更多,可以看看 Deref 章节: https://course.rs/advance/smart-pointer/deref.html
    let ch = first_character(&s);

    s.clear(); // error!

    println!("the first character is: {}", ch);
}
fn first_character(s: &str) -> &str {
    &s[..1]
}

不可变引用的作用域覆盖了可变的。

fn main() {
    let mut s = String::from("hello world");

    let ch = first_character(&s);
    println!("the first character is: {}", ch);
    s.clear(); // error!
}
fn first_character(s: &str) -> &str {
    &s[..1]
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值