Rust从入门到实战系列二百九十五:UTF-8 & 索引

由于 String 都是 UTF-8 编码的,这会带来几个影响:
如果你需要的是非 UTF-8 字符串,可以考虑 OsString
无法通过索引的方式访问一个 String
具体请看字符串索引。
4. 🌟🌟🌟 我们无法通过索引的方式访问字符串中的某个字符,但是可以通过切片的方式来获取字符串
的某一部分 &s1[start…end]
// 填 空 并 修 复 错 误
fn main() {
let s = String::from(“hello, 世 界”);
let slice1 = s[0]; //提 示: h 在 UTF-8 编 码 中 只 占 用 1 个 字 节
assert_eq!(slice1, “h”);
let slice2 = &s[3…5];// 提 示: 在 UTF-8 编 码 中 占 用 3 个 字 节
assert_eq!(slice2, “世”);
// 迭 代 s 中 的 所 有 字 符
for (i, c) in s.__ {
if i == 7 {
assert_eq!(c, ‘世’)
}
}
println!(“Success!”)
}
utf8_slice
我们可以使用 utf8_slice 来按照字符的自然索引方式对 UTF-8 字符串进行切片访问,与之前的切片方式相
比,它索引的是字符,而之前的方式索引的是字节.
示例
use utf8_slice;
fn main() {
let s = “The 🚀 goes to the 🌑!”;
let rocket = utf8_slice::slice(s, 4, 5);
// Will equal “🚀”
}
5. 🌟🌟🌟
提示: 也许你需要使用 from_utf8 方法
// 填 空
fn main() {
let mut s = String::new();
;
let v = vec![104, 101, 108, 108, 111];
// 将 字 节 数 组 转 换 成 String
let s1 = ;
assert_eq!(s, s1);
println!(“Success!”)
}
内部表示
事实上 String 是一个智能指针,它作为一个结构体存储在栈上,然后指向存储在堆上的字符串底层数
据。
存储在栈上的智能指针结构体由三部分组成:一个指针只指向堆上的字节数组,已使用的长度以及已分配
的容量 capacity (已使用的长度小于等于已分配的容量,当容量不够时,会重新分配内存空间)。
6. 🌟🌟 如果 String 的当前容量足够,那么添加字符将不会导致新的内存分配
// 修 改 下 面 的 代 码 以 打 印 如 下 内 容:
// 25
// 25
// 25
// 循 环 中 不 会 发 生 任 何 内 存 分 配
fn main() {
let mut s = String::new();
println!(“{}”, s.capacity());
for _ in 0…2 {
s.push_str(“hello”);
println!(“{}”, s.capacity());
}
println!(“Success!”)
}
7. 🌟🌟🌟
// 填 空
use std::mem;
fn main() {
let story = String::from(“Rust By Practice”);
// 阻 止 String 的 数 据 被 自 动 drop
let mut story = mem::ManuallyDrop::new(story);
let ptr = story.
();
let len = story.
();
let capacity = story.__();
assert_eq!(16, len);
// 我 们 可 以 基 于 ptr 指 针 、 长 度 和 容 量 来 重 新 构 建 String.
// 这 种 操 作 必 须 标 记 为 unsafe, 因 为 我 们 需 要 自 己 来 确 保 这 里 的 操 作 是 安 全 的
let s = unsafe { String::from_raw_parts(ptr, len, capacity) };
assert_eq!(*story, s);
println!(“Success!”)
}

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值