Rust中字符串與格式化操作方法
Rust 提供了多種字符串類型和強大的格式化工具。
字符串
Rust 中主要有兩種字符串類型:&str(字符串切片)和String(動態(tài)字符串),二者均基于UTF-8 編碼。
String-動態(tài)字符串
String是標準庫提供的擁有所有權的動態(tài)字符串類型,存儲在堆上:
- 可變:可通過方法修改內(nèi)容(如添加、刪除字符)。
- 動態(tài)分配:內(nèi)存會根據(jù)內(nèi)容自動擴容。
- 所有權:
String擁有其數(shù)據(jù),賦值或傳遞時會觸發(fā)所有權轉移。
創(chuàng)建:
let mut s = String::new(); // 空字符串
let s = "initial".to_string(); // 從字面量轉換
let s = String::from("initial"); // 同上
let s = format!("Hello {}", "world"); // 通過格式化宏創(chuàng)建&str-字符串切片
&str是對一段 UTF-8 編碼字符串的不可變引用,它不擁有數(shù)據(jù)所有權,僅作為 “視圖” 存在:
- 不可變:無法直接修改
&str指向的內(nèi)容。 - 輕量:由兩部分組成(指針 + 長度),不分配堆內(nèi)存,傳遞時無需復制數(shù)據(jù)。
- 字面量默認類型:代碼中的字符串字面量(如
"hello")本質(zhì)上是&'static str,生命周期為整個程序運行期。
let s: &str = "hello world"; // 字符串字面量,類型為&'static str let slice: &str = &s[0..5]; // 從s中截取切片,結果為"hello"
&str與String間轉換
String→&str:通過as_str()方法或直接引用(&s),因為String實現(xiàn)了Deref<Target=str>,會自動解引用為&str。
let s = String::from("test");
let s_slice: &str = s.as_str(); // 顯式轉換
let s_slice2: &str = &s; // 自動解引用,更常用
&str→String:通過String::from或to_string()。
let slice = "hello"; let s = String::from(slice); // 轉換為String let s2 = slice.to_string(); // 等價方式
常用操作
| 分類 | 方法 / 操作 | 適用類型 | 說明 |
|---|---|---|---|
| 創(chuàng)建 | String::new() | String | 創(chuàng)建空字符串 |
String::from("abc") | String | 從字面量創(chuàng)建 | |
"abc".to_string() | String | 從 &str創(chuàng)建 String | |
String::with_capacity(n) | String | 預分配容量,減少重分配 | |
| 轉換 | s.as_str() | String | 轉換為 &str |
s.into_bytes() | String | 轉換為 Vec<u8> | |
String::from_utf8(v) | Vec<u8> | 從字節(jié)向量還原字符串 | |
s.to_string() | &str | 創(chuàng)建新 String | |
| 長度 | s.len() | String/ &str | 返回字節(jié)長度(不是字符數(shù)) |
s.chars().count() | String/ &str | 返回字符數(shù)(Unicode scalar) | |
| 判斷 | s.is_empty() | String/ &str | 是否為空字符串 |
s.contains("ab") | String/ &str | 是否包含子串 | |
s.starts_with("ab") | String/ &str | 是否以指定子串開頭 | |
s.ends_with("ab") | String/ &str | 是否以指定子串結尾 | |
| 拼接 | s.push('a') | String | 追加單個字符 |
s.push_str("abc") | String | 追加字符串切片 | |
s1 + &s2 | String+ &str | 拼接(移動左側) | |
format!("{}{}", a, b) | 任意 | 格式化拼接,不移動 | |
| 截取/分割 | &s[a..b] | &str | 按字節(jié)切片(需在字符邊界) |
s.split(',') | String/ &str | 按分隔符分割為迭代器 | |
s.split_whitespace() | String/ &str | 按空白分割 | |
s.lines() | String/ &str | 按行分割 | |
| 修剪 | s.trim() | String/ &str | 去除首尾空白 |
s.trim_start() /trim_end() | String/ &str | 去除首或尾空白 | |
| 替換 | s.replace("a","b") | String/ &str | 全部替換 |
s.replacen("a","b",n) | String/ &str | 替換前 n 次 | |
| 大小寫 | s.to_lowercase() | String/ &str | 轉小寫 |
s.to_uppercase() | String/ &str | 轉大寫 | |
| 查找 | s.find("ab") | String/ &str | 返回首個匹配位置(Option) |
s.rfind("ab") | String/ &str | 從后往前找 | |
| 迭代 | s.chars() | String/ &str | 按字符迭代 |
s.bytes() | String/ &str | 按字節(jié)迭代 | |
| 比較 | s1 == s2 | String/ &str | 內(nèi)容比較(UTF-8 安全) |
| 拷貝 / 克隆 | s.clone() | String | 深拷貝(堆上內(nèi)容復制) |
| 清空 / 容量 | s.clear() | String | 清空內(nèi)容 |
s.capacity() | String | 當前容量 | |
s.reserve(n) | String | 預留額外容量 | |
| 字節(jié)訪問 | s.as_bytes() | String/ &str | 獲取字節(jié)切片 |
| 連接 Vec | vec.join(",") | Vec<&str> | 用分隔符連接 |
| 格式化輸出 | format!() | 任意 | 返回格式化字符串 |
格式化
Rust 提供了一套強大的格式化宏,用于字符串拼接、輸出等場景,核心是format!(返回String),以及衍生的print!(打印到標準輸出)、println!(帶換行的打?。?code>eprint!(打印到標準錯誤)等。
格式化語法說明:
{[argument][:[fill][align][width][.precision][type]]}
// 動態(tài)寬度+精度(后面需要$)
println!("{value:>width$.prec$}",
value=3.14159,
width=10,
prec=3); // " 3.142"
// 帶前綴的十六進制
println!("{:#08x}", 42); // "0x00002a"
// 命名參數(shù)+格式化
println!("{name:*^10}", name="ALICE"); // "**ALICE***"參數(shù)指定
{argument}用于指定要格式化的參數(shù),默認省略(按順序)
| 形式 | 說明 | 示例 | 輸出結果 |
|---|---|---|---|
| 省略 | 按參數(shù)順序匹配(默認) | println!("{}, {}", "a", "b") | a, b |
位置索引{n} | 按索引n(從 0 開始)匹配 | println!("{1}, {0}", "a", "b") | b, a |
命名{name} | 按參數(shù)名匹配 | println!("{x}, {y}", x=1, y=2) | 1, 2 |
填充與對齊
語法片段:[fill][align][width]
fill:任意單字符(默認空格);使用fill時需要同時指定align+width。align:<(左對齊)、>(右對齊,默認)、^(居中)。width:最小字段寬度(整數(shù)),不足時使用fill填充。
| 形式 | 說明 | 示例 | 輸出結果 |
|---|---|---|---|
固定寬度{:w} | 指定最小寬度 | println!("width: [{:*^5}]", 123); | [*123*] |
動態(tài)寬度{:width$} | 寬度由參數(shù)指定($是必須的) | println!("[{:w$}]", 123, w=5); | [ 123] |
format!("{:>8}", "hi") // 右對齊 -> " hi"
format!("{:<8}", "hi") // 左對齊 -> "hi "
format!("{:^8}", "hi") // 居中 -> " hi "
format!("{:0>5}", 42) // 填充字符 '0', 右對齊 -> "00042"
精度
語法片段:.precision(寫作 .N 或 動態(tài) .*)
| 適用類型 | 含義 | 示例 | 輸出結果 |
|---|---|---|---|
| 字符串 | 最大長度(超過則截斷) | println!("{:.3}", "hello") | hel |
| 浮點數(shù) | 小數(shù)位數(shù)(四舍五入) | println!("{:.2}", 3.1415) | 3.14 |
| 整數(shù) | 最小位數(shù)(不足補 0,超過則原樣輸出) | println!("{:.4}", 12) | 0012 |
動態(tài)精度{:.*} | 精度由參數(shù)指定(前一個參數(shù)為精度值) | println!("{}-{:.*}","ab", 2, 3.1415) | ab-3.14 |
類型格式
指定數(shù)據(jù)的格式化類型,將數(shù)據(jù)轉換為特定格式的字符串。
整數(shù)類型
整數(shù)類型(i8/i16/i32/i64/u8/u16/…/usize/isize):
| 說明符 | 作用 | 示例 | 輸出結果 |
|---|---|---|---|
b | 二進制 | println!("{:b}", 10) | 1010 |
o | 八進制 | println!("{:o}", 10) | 12 |
d | 十進制(默認) | println!("{:d}", 10) | 10 |
x | 小寫十六進制 | println!("{:x}", 255) | ff |
X | 大寫十六進制 | println!("{:X}", 255) | FF |
浮點數(shù)類型
浮點數(shù)類型(f32/f64):
| 說明符 | 作用 | 示例 | 輸出結果 |
|---|---|---|---|
f | 小數(shù)形式(默認) | println!("{:f}", 123.456) | 123.456000(默認 6 位小數(shù)) |
e | 科學計數(shù)法(小寫 e) | println!("{:e}", 123.456) | 1.234560e+02 |
E | 科學計數(shù)法(大寫 E) | println!("{:E}", 123.456) | 1.234560E+02 |
g | 自動選擇f或e(取較短形式) | println!("{:g}", 123456789.0) | 1.23457e+08 |
G | 自動選擇f或E | println!("{:G}", 123456789.0) | 1.23457E+08 |
通用與特殊類型
| 說明符 | 作用 | 適用場景 | 示例 | 輸出結果 |
|---|---|---|---|---|
? | 按Debug trait 格式化(調(diào)試用) | 所有實現(xiàn)Debug的類型 | println!("{:?}", vec![1,2]) | [1, 2] |
#? | 美化的Debug格式(換行 + 縮進) | 復雜結構(如結構體、嵌套集合) | println!("{:#?}", vec![1,2]) | [\n 1,\n 2\n] |
p | 指針地址 | 僅用于引用類型 | println!("{:p}", &10) | 0x7ff72194e7b8 |
標志(Flags)
特殊修飾符,用于調(diào)整輸出格式,可與其他說明符組合使用。
| 標志 | 作用 | 示例 | 輸出結果 |
|---|---|---|---|
# | 為數(shù)值添加前綴(二進制0b、八進制0o、十六進制0x) | println!("{:#x}", 255) | 0xff |
+ | 強制顯示正負號(正數(shù)顯+,負數(shù)顯-) | println!("{:+}", 10); println!("{:+}", -10) | +10-10 |
0 | 用0填充(代替空格) | println!("{:05}", 123) | 00123 |
_ | 為大數(shù)值添加千位分隔符(僅整數(shù)和浮點數(shù)) | println!("{:_}", 1000000) | 1_000_000 |
特殊格式
| 語法 | 示例 | 說明 |
|---|---|---|
{{ | {{ | 輸出左花括號 { |
}} | }} | 輸出右花括號 } |
自定義Display獲取參數(shù)
當在類型上實現(xiàn) fmt::Display 時,可以在 fmt(&self, f: &mut fmt::Formatter<'_>) 中讀取用戶給的 width、precision、alternate 等:
use std::fmt;
struct Point { x: f64, y: f64 }
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// 獲取 width / precision(Option<usize>)
if let Some(prec) = f.precision() {
write!(f, "({:.prec$}, {:.prec$})", self.x, self.y)
} else if f.alternate() {
// 如果用戶寫了 "{:#}",可切換格式
write!(f, "Point {{ x: {}, y: {} }}", self.x, self.y)
} else {
write!(f, "({}, {})", self.x, self.y)
}
}
}到此這篇關于Rust中字符串與格式化操作方法的文章就介紹到這了,更多相關Rust字符串格式化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
rust使用Atomic創(chuàng)建全局變量和使用操作方法
從 Rust1.34 版本后,就正式支持原子類型,原子指的是一系列不可被 CPU 上下文交換的機器指令,這些指令組合在一起就形成了原子操作,這篇文章主要介紹了rust使用Atomic創(chuàng)建全局變量和使用,需要的朋友可以參考下2024-05-05
Rust調(diào)用Windows API 如何獲取正在運行的全部進程信息
本文介紹了如何使用Rust調(diào)用WindowsAPI獲取正在運行的全部進程信息,通過引入winapi依賴并添加相應的features,可以實現(xiàn)對不同API集的調(diào)用,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-11-11

