【Rust练习】8.字符串

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

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

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

s的类型应该是&str

rust 复制代码
fn main() {
    let s: &str = "hello, world";
}

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

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

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

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

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

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

3

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

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

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

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

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

4

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

    println!("{}", s)
}

修改如下:

rust 复制代码
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 方法来替换指定的子字符串

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

    assert_eq!(s1, "I like cats")
}
rust 复制代码
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

rust 复制代码
// 修复所有错误,不要删除任何一行代码
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,拼接完成后所有权会被释放掉。

rust 复制代码
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 类型

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

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

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

rust 复制代码
fn main() {
    let s = "hello, world";
    greetings(s.to_string());
}

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

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

rust 复制代码
fn main() {
    let s = "hello, world";
    greetings(s);
}

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

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

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

同上,不解释了。

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

9

rust 复制代码
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的后面,这我还是记得的。

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

10

rust 复制代码
/* 填空并修复所有错误 */
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字符串的作用是,让所有的转义字符全部失效。

rust 复制代码
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 必须准确落在字符的边界处.

rust 复制代码
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]

rust 复制代码
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

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

使用chars()即可。

rust 复制代码
fn main() {
    // 填空,打印出 "你好,世界" 中的每一个字符
    for c in "你好,世界".chars() {
        println!("{}", c)
    }
}
相关推荐
黄雪超4 分钟前
JVM——JVM 是如何执行方法调用的?
java·开发语言·jvm
风暴之零13 分钟前
文本中地理位置提取方法—正则和NLP模型
开发语言·python
Dxy123931021624 分钟前
python合并word中的run
开发语言·python·word
光影少年29 分钟前
新手学编程前端好还是后端
前端·后端
why15132 分钟前
百度网盘golang实习面经
开发语言·后端·golang
楠奕1 小时前
neo4j vs python
开发语言·python·neo4j
layman05281 小时前
javaScript——正则表达式(四)
开发语言·javascript·正则表达式
UestcXiye1 小时前
Rust 学习笔记:枚举与模式匹配
rust
jiunian_cn2 小时前
【c++】【STL】queue详解
开发语言·c++·visualstudio
achene_ql2 小时前
C++ 与 Lua 联合编程
开发语言·c++·lua