Rust中字符串与格式化

Rust 提供了多种字符串类型和强大的格式化工具。

字符串

Rust 中主要有两种字符串类型:&str(字符串切片)和String(动态字符串),二者均基于UTF-8 编码

String-动态字符串

String是标准库提供的拥有所有权的动态字符串类型,存储在堆上:

  • 可变:可通过方法修改内容(如添加、删除字符)。
  • 动态分配:内存会根据内容自动扩容。
  • 所有权:String拥有其数据,赋值或传递时会触发所有权转移。

创建:

rust 复制代码
let mut s = String::new();                   // 空字符串
let s = "initial".to_string();               // 从字面量转换
let s = String::from("initial");             // 同上
let s = format!("Hello {}", "world");        // 通过格式化宏创建

&str-字符串切片

&str是对一段 UTF-8 编码字符串的不可变引用,它不拥有数据所有权,仅作为 "视图" 存在:

  • 不可变:无法直接修改&str指向的内容。
  • 轻量:由两部分组成(指针 + 长度),不分配堆内存,传递时无需复制数据。
  • 字面量默认类型:代码中的字符串字面量(如"hello")本质上是&'static str,生命周期为整个程序运行期。
rust 复制代码
let s: &str = "hello world";  // 字符串字面量,类型为&'static str
let slice: &str = &s[0..5];   // 从s中截取切片,结果为"hello"

&str与String间转换

  • String&str:通过as_str()方法或直接引用(&s),因为String实现了Deref<Target=str>,会自动解引用为&str
rust 复制代码
let s = String::from("test");
let s_slice: &str = s.as_str();  // 显式转换
let s_slice2: &str = &s;         // 自动解引用,更常用
  • &strString:通过String::fromto_string()
rust 复制代码
let slice = "hello";
let s = String::from(slice);  // 转换为String
let s2 = slice.to_string();   // 等价方式

常用操作

分类 方法 / 操作 适用类型 说明
创建 String::new() String 创建空字符串
String::from("abc") String 从字面量创建
"abc".to_string() String &str 创建 String
String::with_capacity(n) String 预分配容量,减少重分配
转换 s.as_str() String 转换为 &str
s.into_bytes() String 转换为 Vec<u8>
String::from_utf8(v) Vec<u8> 从字节向量还原字符串
s.to_string() &str 创建新 String
长度 s.len() String /&str 返回字节长度(不是字符数)
s.chars().count() String /&str 返回字符数(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 按字节切片(需在字符边界)
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 按字节迭代
比较 s1 == s2 String /&str 内容比较(UTF-8 安全)
拷贝 / 克隆 s.clone() String 深拷贝(堆上内容复制)
清空 / 容量 s.clear() String 清空内容
s.capacity() String 当前容量
s.reserve(n) String 预留额外容量
字节访问 s.as_bytes() String /&str 获取字节切片
连接 Vec vec.join(",") Vec<&str> 用分隔符连接
格式化输出 format!() 任意 返回格式化字符串

格式化

Rust 提供了一套强大的格式化宏,用于字符串拼接、输出等场景,核心是format!(返回String),以及衍生的print!(打印到标准输出)、println!(带换行的打印)、eprint!(打印到标准错误)等。

格式化语法说明

{[argument][:[fill][align][width][.precision][type]]}

rust 复制代码
// 动态宽度+精度(后面需要$)
println!("{value:>width$.prec$}", 
         value=3.14159, 
         width=10, 
         prec=3); // "     3.142"

// 带前缀的十六进制
println!("{:#08x}", 42); // "0x00002a"

// 命名参数+格式化
println!("{name:*^10}", name="ALICE"); // "**ALICE***"

参数指定

{argument}用于指定要格式化的参数,默认省略(按顺序)

形式 说明 示例 输出结果
省略 按参数顺序匹配(默认) println!("{}, {}", "a", "b") a, b
位置索引{n} 按索引n(从 0 开始)匹配 println!("{1}, {0}", "a", "b") b, a
命名{name} 按参数名匹配 println!("{x}, {y}", x=1, y=2) 1, 2

填充与对齐

语法片段:[fill][align][width]

  • fill:任意单字符(默认空格);使用fill时需要同时指定align+width
  • align<(左对齐)、>(右对齐,默认)、^(居中)。
  • width:最小字段宽度(整数),不足时使用 fill 填充。
形式 说明 示例 输出结果
固定宽度{:w} 指定最小宽度 println!("width: [{:*^5}]", 123); [*123*]
动态宽度{:width$} 宽度由参数指定($是必须的) println!("[{:w$}]", 123, w=5); [ 123]
rust 复制代码
format!("{:>8}", "hi")       // 右对齐 -> "      hi"
format!("{:<8}", "hi")       // 左对齐 -> "hi      "
format!("{:^8}", "hi")       // 居中 -> "   hi   "
format!("{:0>5}", 42)        // 填充字符 '0', 右对齐 -> "00042"

精度

语法片段:.precision(写作 .N 或 动态 .*

适用类型 含义 示例 输出结果
字符串 最大长度(超过则截断) println!("{:.3}", "hello") hel
浮点数 小数位数(四舍五入) println!("{:.2}", 3.1415) 3.14
整数 最小位数(不足补 0,超过则原样输出) println!("{:.4}", 12) 0012
动态精度{:.*} 精度由参数指定(前一个参数为精度值) println!("{}-{:.*}","ab", 2, 3.1415) ab-3.14

类型格式

指定数据的格式化类型,将数据转换为特定格式的字符串。

整数类型

整数类型(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

浮点数类型

浮点数类型(f32/f64):

说明符 作用 示例 输出结果
f 小数形式(默认) println!("{:f}", 123.456) 123.456000 (默认 6 位小数)
e 科学计数法(小写 e) println!("{:e}", 123.456) 1.234560e+02
E 科学计数法(大写 E) println!("{:E}", 123.456) 1.234560E+02
g 自动选择fe(取较短形式) println!("{:g}", 123456789.0) 1.23457e+08
G 自动选择fE println!("{:G}", 123456789.0) 1.23457E+08

通用与特殊类型

说明符 作用 适用场景 示例 输出结果
? Debug trait 格式化(调试用) 所有实现Debug 的类型 println!("{:?}", vec![1,2]) [1, 2]
#? 美化的Debug格式(换行 + 缩进) 复杂结构(如结构体、嵌套集合) println!("{:#?}", vec![1,2]) [\n 1,\n 2\n]
p 指针地址 仅用于引用类型 println!("{:p}", &10) 0x7ff72194e7b8

标志(Flags)

特殊修饰符,用于调整输出格式,可与其他说明符组合使用。

标志 作用 示例 输出结果
# 为数值添加前缀(二进制0b、八进制0o、十六进制0x println!("{:#x}", 255) 0xff
+ 强制显示正负号(正数显+,负数显- println!("{:+}", 10); println!("{:+}", -10) +10 -10
0 0填充(代替空格) println!("{:05}", 123) 00123
_ 为大数值添加千位分隔符(仅整数和浮点数) println!("{:_}", 1000000) 1_000_000

特殊格式

语法 示例 说明
{``{ {``{ 输出左花括号 {
}} }} 输出右花括号 }

自定义 Display获取参数

当在类型上实现 fmt::Display 时,可以在 fmt(&self, f: &mut fmt::Formatter<'_>) 中读取用户给的 widthprecisionalternate 等:

rust 复制代码
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)
        }
    }
}
相关推荐
魔镜前的帅比3 小时前
(开源项目)XSUN_DESKTOP_PET 2 (桌面宠物)
rust·宠物·tauri2
0110_10243 小时前
tauri + rust的环境搭建---初始化以及构建
开发语言·后端·rust
像风一样自由20204 小时前
Rust Tokio vs Go net/http:云原生与嵌入式生态选型指南
开发语言·golang·rust
大鱼七成饱1 天前
Rust Web 初学者必看:用一个宏搞定错误处理和统一返回
rust
Vallelonga1 天前
Rust 设计模式 Marker Trait + Blanket Implementation
开发语言·设计模式·rust
ftpeak1 天前
《Cargo 参考手册》第二十一章:Cargo 包命令
开发语言·rust
Source.Liu1 天前
【BuildFlow & 筑流】品牌命名与项目定位说明
c++·qt·rust·markdown·librecad
ftpeak1 天前
《Cargo 参考手册》第二十二章:发布命令
开发语言·rust
JoannaJuanCV3 天前
error: can‘t find Rust compiler
开发语言·后端·rust