【Rust练习】8.字符串

32 篇文章 0 订阅
8 篇文章 0 订阅

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

1.正常情况下我们无法使用 str 类型,但是可以使用 &str 来替代

// 修复错误,不要新增代码行
fn main() {
    let s: str = "hello, world";
}

s的类型应该是&str

fn main() {
    let s: &str = "hello, world";
}

2 如果要使用 str 类型,只能配合 Box。 & 可以用来将 Box 转换为 &str 类型

// 使用至少两种方法来修复错误
fn main() {
    let s: Box<str> = "hello, world".into();
    greetings(s)
}

fn greetings(s: &str) {
    println!("{}",s)
}

Box是一种对数据进行装箱的设计。类似于C++中的智能指针(我感觉是智能指针和Java的包装数据的结合)。Box在栈上保留指针,然后在堆上分配内存保存数据。这道题最简答的两种改法就是,或者将形参类型修改,或者将实参类型修改。

//修改实参
fn main() {
    let s: Box<str> = "hello, world".into();
    greetings(&s)
}

fn greetings(s: &str) {
    println!("{}",s)
}
fn main() {
    let s: Box<str> = "hello, world".into();
    greetings(s)
}
//修改形参
fn greetings(s: Box<str>) {
    println!("{}",s)
}

3

// 填空
fn main() {
    let mut s = __;
    s.push_str("hello, world");
    s.push('!');

    assert_eq!(s, "hello, world!");
}

构造一个空的字符串即可。

fn main() {
    let mut s = String::from("");
    s.push_str("hello, world");
    s.push('!');

    assert_eq!(s, "hello, world!");
}

4

// 修复所有错误,并且不要新增代码行
fn main() {
    let  s = String::from("hello");
    s.push(',');
    s.push(" world");
    s += "!".to_string();

    println!("{}", s)
}

修改如下:

fn main() {
    //s必须可变
    let mut s = String::from("hello");
    s.push(',');
    //追加string必须用push_str
    s.push_str(" world");
    //重载的加法运算必须是&str类型,toString是多此一举
    s += "!";

    println!("{}", s)
}

5 我们可以用 replace 方法来替换指定的子字符串

// 填空
fn main() {
    let s = String::from("I like dogs");
    // 以下方法会重新分配一块内存空间,然后将修改后的字符串存在这里
    let s1 = s.__("dogs", "cats");

    assert_eq!(s1, "I like cats")
}
fn main() {
    let s = String::from("I like dogs");
    // 以下方法会重新分配一块内存空间,然后将修改后的字符串存在这里
    let s1 = s.replace("dogs", "cats");

    assert_eq!(s1, "I like cats")
}

6 你只能将 String 跟 &str 类型进行拼接,并且 String 的所有权在此过程中会被 move

// 修复所有错误,不要删除任何一行代码
fn main() {
    let s1 = String::from("hello,");
    let s2 = String::from("world!");
    let s3 = s1 + s2; 
    assert_eq!(s3,"hello,world!");
    println!("{}",s1);
}

s2的类型必须是&str,且s1作为拼接的String的base,拼接完成后所有权会被释放掉。

fn main() {
    let s1 = String::from("hello,");
    let s2 = String::from("world!");
    let s3 = s1 + &s2; 
    assert_eq!(s3,"hello,world!");
    println!("{}",s3);
}

7 我们可以使用两种方法将 &str 转换成 String 类型

// 使用至少两种方法来修复错误
fn main() {
    let s = "hello, world";
    greetings(s)
}

fn greetings(s: String) {
    println!("{}",s)
}

对于&str类型的val,可以使用to_string()转为String(不会丢失所有权)

fn main() {
    let s = "hello, world";
    greetings(s.to_string());
}

fn greetings(s: String) {
    println!("{}",s)
}

或者,把函数的形参改了也行:

fn main() {
    let s = "hello, world";
    greetings(s);
}

fn greetings(s: &str) {
    println!("{}",s)
}

8 我们可以使用 String::from 或 to_string 将 &str 转换成 String 类型

// 使用两种方法来解决错误,不要新增代码行
fn main() {
    let s = "hello, world".to_string();
    let s1: &str = s;
}

同上,不解释了。

fn main() {
    let s = "hello, world".to_string();
    let s1: &str = &s;
}
fn main() {
    let s = "hello, world";
    let s1: &str = s;
}

9

fn main() {
    // 你可以使用转义的方式来输出想要的字符,这里我们使用十六进制的值,例如 \x73 会被转义成小写字母 's'
    // 填空以输出 "I'm writing Rust"
    let byte_escape = "I'm writing Ru\x73__!";
    println!("What are you doing\x3F (\\x3F means ?) {}", byte_escape);

ASCII码我基本一个也不记得,不过t就在s的后面,这我还是记得的。

fn main() {
    let byte_escape = "I'm writing Ru\x73\x74!";
    println!("What are you doing\x3F (\\x3F means ?) {}", byte_escape);

10

/* 填空并修复所有错误 */
fn main() {
    let raw_str = r"Escapes don't work here: \x3F \u{211D}";
    // 修改上面的行让代码工作
    assert_eq!(raw_str, "Escapes don't work here: ? ℝ");

    // 如果你希望在字符串中使用双引号,可以使用以下形式
    let quotes = r#"And then I said: "There is no escape!""#;
    println!("{}", quotes);

    // 如果希望在字符串中使用 # 号,可以如下使用:
    let  delimiter = r###"A string with "# in it. And even "##!"###;
    println!("{}", delimiter);

    // 填空
    let long_delimiter = __;
    assert_eq!(long_delimiter, "Hello, \"##\"")
}

raw字符串的作用是,让所有的转义字符全部失效。

fn main() {
    let raw_str = r"Escapes don't work here: \x3F \u{211D}";
    // 修改上面的行让代码工作
    assert_eq!(raw_str, r"Escapes don't work here: \x3F \u{211D}");

    // 如果你希望在字符串中使用双引号,可以使用以下形式
    let quotes = r#"And then I said: "There is no escape!""#;
    println!("{}", quotes);

    // 如果希望在字符串中使用 # 号,可以如下使用:
    let  delimiter = r###"A string with "# in it. And even "##!"###;
    println!("{}", delimiter);

    // 填空
    let long_delimiter = "Hello, \"##\"";
    assert_eq!(long_delimiter, "Hello, \"##\"")
}

11 你无法通过索引的方式去访问字符串中的某个字符,但是可以使用切片的方式 &s1[start…end] ,但是start 和 end 必须准确落在字符的边界处.

fn main() {
    let s1 = String::from("hi,中国");
    let h = s1[0]; // 修改当前行来修复错误,提示: `h` 字符在 UTF-8 格式中只需要 1 个字节来表示
    assert_eq!(h, "h");

    let h1 = &s1[3..5];// 修改当前行来修复错误,提示: `中` 字符在 UTF-8 格式中需要 3 个字节来表示
    assert_eq!(h1, "中");
}

h位于0个,所以对应的切片为[0..1];中位于3-5个字符,对应的切片为[3..6]

fn main() {
    let s1 = String::from("hi,中国");
    let h = &s1[..1]; // 修改当前行来修复错误,提示: `h` 字符在 UTF-8 格式中只需要 1 个字节来表示
    assert_eq!(h, "h");

    let h1 = &s1[3..6];// 修改当前行来修复错误,提示: `中` 字符在 UTF-8 格式中需要 3 个字节来表示
    assert_eq!(h1, "中");
}

12

fn main() {
    // 填空,打印出 "你好,世界" 中的每一个字符
    for c in "你好,世界".__ {
        println!("{}", c)
    }
}

使用chars()即可。

fn main() {
    // 填空,打印出 "你好,世界" 中的每一个字符
    for c in "你好,世界".chars() {
        println!("{}", c)
    }
}
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值