文章目录
- 1. 目的
- 2. 数据类型
- 2.1 str 类型
- 2.2 标准库 `String` 类型
- 3. 常用 API
- 3.1 `len()` 方法
- 3.2 `is_empty()` 方法
- 3.3 `starts_with()` 方法
- 3.4 `find()` 方法
- 4. References
1. 目的
学习 Rust 语言中的字符串, 包括数据类型, 常用 API。
2. 数据类型
Rust 语言提供了两种字符串:
-
str
类型. 通常用它的 borrow 类型&str
. -
标准库的
String
类型.
2.1 str 类型
也叫做 string slice
. 通常是使用它的 borrow 类型,也就是 &str
. 1
字符串字面量 (string literals) 的类型, 也是 str
类型(也就是 &'static str
).
字符串字面量 &str
是在编译时确定其值的字符串类型。
fn main() {
let a:&str = "hello";
println!("a {}", a);
let b = "world";
println!("b {}", b);
}
编译运行
zz@Legion-R7000P% ./u1
a hello
b world
2.2 标准库 String
类型
Rust 语言的 String
位于标准库2:
String
是一个 struct3:
pub struct String {
vec: Vec<u8>,
}
其中 Vec<u8>
指的是 UTF-8 字符作为元素的容器。这里暂时不了解容器,简单理解为:和 C++ 的 vector 类似的东西。
尝试使用 String
创建字符串变量:
fn main() {
let s1 = String::new(); // 创建空字符串
println!("s1: |{}|", s1);
let s2 = String::from("hello world"); // 从字符串字面量创建 String
println!("s2: {}", s2);
}
3. 常用 API
3.1 len()
方法
无论是 &str
还是 String
类型的对象, 都支持 len()
方法:
u3.rs:
fn main() {
let s1 = String::new();
println!("s1: |{}|, s1.len(): {}", s1, s1.len());
let s2 = String::from("hello world");
println!("s2: {}, s2.len(): {}", s2, s2.len());
let t1 = "";
println!("t1: |{}|, t1.len(): {}", t1, t1.len());
let t2 = "hello world";
println!("t2: {}, t2.len(): {}", t2, t2.len());
}
编译运行结果:
zz@Legion-R7000P% rustc u3.rs
zz@Legion-R7000P% ./u3
s1: ||, s1.len(): 0
s2: hello world, s2.len(): 11
t1: ||, t1.len(): 0
t2: hello world, t2.len(): 11
3.2 is_empty()
方法
无论是 &str
还是 String
类型的对象, 都支持 is_empty()
方法:
u4.rs:
fn main() {
let s1 = String::new();
println!("s1: |{}|, s1.is_empty(): {}", s1, s1.is_empty());
let s2 = String::from("hello world");
println!("s2: {}, s2.is_empty(): {}", s2, s2.is_empty());
let t1 = "";
println!("t1: |{}|, t1.is_empty(): {}", t1, t1.is_empty());
let t2 = "hello world";
println!("t2: {}, t2.is_empty: {}", t2, t2.is_empty());
}
编译运行结果:
zz@Legion-R7000P% rustc u4.rs
zz@Legion-R7000P% ./u4
s1: ||, s1.is_empty(): true
s2: hello world, s2.is_empty(): false
t1: ||, t1.is_empty(): true
t2: hello world, t2.is_empty: false
3.3 starts_with()
方法
无论是 &str
还是 String
类型的对象, 都支持 starts_with()
方法, 也都支持 ends_with()
方法。这里以及 starts_with()
方法为例:
u5.rs:
fn main() {
let s1 = String::from("Hello World");
println!("s1: {}, s1.starts_with(\"Hello\"): {}", s1, s1.starts_with("Hello"));
println!("s1: {}, s1.starts_with(\"hello\"): {}", s1, s1.starts_with("hello"));
let t1 = "Hello World";
println!("t1: {}, t1.starts_with(\"Hello\"): {}", t1, t1.starts_with("Hello"));
println!("t1: {}, t1.starts_with(\"hello\"): {}", t1, t1.starts_with("hello"));
}
编译运行结果:
zz@Legion-R7000P% rustc u5.rs
zz@Legion-R7000P% ./u5
s1: Hello World, s1.starts_with("Hello"): true
s1: Hello World, s1.starts_with("hello"): false
t1: Hello World, t1.starts_with("Hello"): true
t1: Hello World, t1.starts_with("hello"): false
3.4 find()
方法
无论是 &str
还是 String
类型的对象, 都支持 find()
方法, 返回的是匹配到给定模式时当前 &str
/string
的第一个字符的索引. 举例如下:
这里本来想写一个简单的例子, 不过编译报错了, 看起来 rust 的 println!
宏罢工了, 不能直接处理字符串的 find() 方法返回的结果:
对应的代码是 u6.rs(这是一个错误的示范, 了解的大佬欢迎在评论区赐教)
fn main() {
let s1 = String::from("Hello World");
let idx1 = s1.find("ello");
let idx2 = s1.find("world");
println!("s1: {}, s1.find(\"ello\"): {}", s1, idx1);
println!("s1: {}, s1.find(\"world\"): {}", s1, idx2);
let t1 = "Hello World";
let idx1 = t1.find("ello");
let idx2 = t1.find("world");
println!("t1: {}, t1.find(\"ello\"): {}", t1, idx1);
println!("s1: {}, s1.find(\"world\"): {}", s1, idx2);
}
zz@Legion-R7000P% rustc u6.rs
error[E0277]: `Option<usize>` doesn't implement `std::fmt::Display`
--> u6.rs:5:51
|
5 | println!("s1: {}, s1.find(\"ello\"): {}", s1, idx1);
| ^^^^ `Option<usize>` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Option<usize>`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `Option<usize>` doesn't implement `std::fmt::Display`
--> u6.rs:6:52
|
6 | println!("s1: {}, s1.find(\"world\"): {}", s1, idx2);
| ^^^^ `Option<usize>` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Option<usize>`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `Option<usize>` doesn't implement `std::fmt::Display`
--> u6.rs:11:51
|
11 | println!("t1: {}, t1.find(\"ello\"): {}", t1, idx1);
| ^^^^ `Option<usize>` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Option<usize>`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `Option<usize>` doesn't implement `std::fmt::Display`
--> u6.rs:12:52
|
12 | println!("s1: {}, s1.find(\"world\"): {}", s1, idx2);
| ^^^^ `Option<usize>` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Option<usize>`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.
4. References
https://doc.rust-lang.org/std/primitive.str.html ↩︎
https://doc.rust-lang.org/std/string/struct.String.html# ↩︎
https://doc.rust-lang.org/src/alloc/string.rs.html#365 ↩︎