Rust 中的字符是 Unicode 類(lèi)型,因此每個(gè)字符占據(jù) 4 個(gè)字節(jié)內(nèi)存空間,但字符串不一樣,字符串是 UTF-8 編碼,也就是字符串中的字符所占的字節(jié)數(shù)是變化的(1 - 4)。
常見(jiàn)的字符串有兩種:
- str,通常是引用類(lèi)型,
&str
,即字符串字面常量,字符串切片。 - std::string::String
類(lèi)型&str
的變量是被硬編碼的,快速而高效,但不可變;類(lèi)型String
,是可設(shè)可變的,它是在堆上的變量,如何管理內(nèi)存,有的語(yǔ)言用垃圾回收機(jī)制(Garbage Collection),標(biāo)記使用情況并自動(dòng)清理;而Rust不愿意用GC,既要高性能,又要高安全性,提出變量離開(kāi)作用域即自動(dòng)釋放其占用的內(nèi)存,比GC思路更妙。
C語(yǔ)言中清理內(nèi)存的函數(shù)free,要被手動(dòng)調(diào)用;Rust中則是drop(),Rust自動(dòng)調(diào)用。
C++中的Resoure Acquisition Is Initialization,RAII模型。
兩種字符串類(lèi)型互轉(zhuǎn)
&str
轉(zhuǎn)String
:
let a = String::from("hello, world");
"hello, world".to_string();
String
轉(zhuǎn)&str
,引用即可
fn main() {
let s = String::from("hello,world!");
say_hello(&s);
say_hello(&s[..]);
say_hello(s.as_str());
}
fn say_hello(s: &str) {
println!("{}",s);
}
除上述兩種類(lèi)型,Rust標(biāo)準(zhǔn)庫(kù)還有其他類(lèi)型的字符串。
字符串不能被直接索引
Rust字符串不允許索引操作。由于不同字符占用字節(jié)數(shù)不等,考慮操作時(shí)間復(fù)雜度不能實(shí)現(xiàn)O(1)。
//三個(gè)字節(jié)
let a = "中國(guó)人";
//一個(gè)字節(jié)
let b = "Chinese";
Rust字符串雖然不能索引但可以切片(slice),類(lèi)似Python等語(yǔ)言中的切片概念。
fn main() {
let my_name = "kirk zhang";
let first_name = &my_name[0..4];
let last_name = &my_name[5..10];
println!("{}",first_name);
println!("{}",last_name);
greet(String::from(my_name));
// 嘗試my_name[0]報(bào)錯(cuò),不過(guò)可以用.chars().nth或.bytes()來(lái)實(shí)現(xiàn)
println!("can str be indexed {:?}",my_name.chars().nth(0));
}
fn greet(name: String){
println!("hello {}", name);
}
小心字符串切片
注意字符串切片是按字節(jié)來(lái)的哦,而Rust字符串是UTF-8協(xié)議格式,一般1個(gè)字符1個(gè)字節(jié),但1個(gè)中文字符占3個(gè)字節(jié);如果切片起止不在字符邊界,則有異常。
fn main(){
let f = "中國(guó)人";
let f1 = &f[0..5];
println!("watch out, what you got {}",f1);
}
提示:thread ‘main’ panicked at ‘byte index 5 is not a char boundary; it is inside ‘國(guó)’ (bytes 3…6) of 中國(guó)人
’, src/main.rs:10:15
note: run with RUST_BACKTRACE=1
environment variable to display a backtrace
字符串的操作
替換
replace(要被替換的子串,新字符串),返回結(jié)果字符串。
let word = String::from("rust");
let new_word = word.replace("r","R");
println!("{}", new_word);
插入
insert(位置索引,字符)、insert_str(位置索引,字符串):變量本身變化,聲明時(shí)要mut。
let word = String::from("rust");
let mut new_word = word.replace("r","R");
new_word.insert_str(0, "I love ");
println!("{}", new_word);
追加
push(字符)
push_str(字符串)
let word = String::from("rust");
let mut new_word = word.replace("r","R");
new_word.insert_str(0, "I love ");
new_word.push('!');
println!("{}", new_word);
連接
+
或+=
調(diào)用了String的add(self,&str)
方法,其定義要求+后面的參數(shù)為字符串字面常量,返回String類(lèi)型。
或用format! ,適用于 String 和 &str 。format! 的用法與 println! 的用法類(lèi)似。
let a1 = String::from("tic");
let a2 = String::from("tac");
let a3 = String::from("toe");
// 經(jīng)過(guò)下面一行后,a1被釋放了,不能再使用!a2、a3依然存在。
let s = s1 + "-" + &s2 + "-" + &s3;
刪除
有4個(gè)方法,pop()、remove(索引位置)、truncate(起始位置)、clear()
注意刪除字符串的索引必須是字符串中字符的邊界,否則錯(cuò)誤。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-829519.html
fn main() {
let mut string_remove = String::from("測(cè)試remove方法");
println!(
"string_remove 占 {} 個(gè)字節(jié)",
std::mem::size_of_val(string_remove.as_str())
);
// 刪除第一個(gè)漢字
string_remove.remove(0);
// 下面代碼會(huì)發(fā)生錯(cuò)誤
// string_remove.remove(1);
// 直接刪除第二個(gè)漢字
// string_remove.remove(3);
dbg!(string_remove);
}
字符串的字符與字節(jié)
例,文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-829519.html
for c in "中國(guó)人".chars() {
println!("{}", c);
}
for b in "中國(guó)人".bytes() {
println!("{}", b);
}
到了這里,關(guān)于【編程】Rust語(yǔ)言入門(mén)第4篇 字符串的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!