update intro.md

pull/535/head
sunface 3 years ago
parent 332b106756
commit 9d670b4c6a

@ -59,7 +59,6 @@
- [注释和文档](basic/comment.md) - [注释和文档](basic/comment.md)
- [格式化输出](basic/formatted-output.md) - [格式化输出](basic/formatted-output.md)
- [Rust 高级进阶](advance/intro.md) - [Rust 高级进阶](advance/intro.md)
- [生命周期](advance/lifetime/intro.md) - [生命周期](advance/lifetime/intro.md)
- [认识生命周期](advance/lifetime/basic.md) - [认识生命周期](advance/lifetime/basic.md)
- [深入生命周期](advance/lifetime/advance.md) - [深入生命周期](advance/lifetime/advance.md)
@ -102,7 +101,6 @@
## 专题内容,每个专题都配套一个小型项目进行实践 ## 专题内容,每个专题都配套一个小型项目进行实践
- [自动化测试](test/intro.md) - [自动化测试](test/intro.md)
- [编写测试及控制执行](test/write-tests.md) - [编写测试及控制执行](test/write-tests.md)
- [单元测试和集成测试](test/unit-integration-test.md) - [单元测试和集成测试](test/unit-integration-test.md)
- [断言 assertion](test/assertion.md) - [断言 assertion](test/assertion.md)
@ -160,15 +158,14 @@
- [手把手带你实现链表 doing](linked-list/intro.md) - [手把手带你实现链表 doing](linked-list/intro.md)
- [易混淆概念解析](confonding/intro.md) - [易混淆概念解析](confonding/intro.md)
- [切片和切片引用](confonding/slice.md) - [切片和切片引用](confonding/slice.md)
- [String、&str 和 str](confonding/string.md) - [Eq 和 PartialEq](confonding/eq.md)
- [String、&str 和 str todo](confonding/string.md)
- [原生指针、引用和智能指针 todo](confonding/pointer.md) - [原生指针、引用和智能指针 todo](confonding/pointer.md)
- [作用域、生命周期和 NLL todo](confonding/lifetime.md) - [作用域、生命周期和 NLL todo](confonding/lifetime.md)
- [move、Copy 和 Clone todo](confonding/move-copy.md) - [move、Copy 和 Clone todo](confonding/move-copy.md)
- [对抗编译检查 doing](fight-with-compiler/intro.md) - [对抗编译检查 doing](fight-with-compiler/intro.md)
- [幽灵数据(todo)](fight-with-compiler/phantom-data.md) - [幽灵数据(todo)](fight-with-compiler/phantom-data.md)
- [生命周期](fight-with-compiler/lifetime/intro.md) - [生命周期](fight-with-compiler/lifetime/intro.md)
- [生命周期过大-01](fight-with-compiler/lifetime/too-long1.md) - [生命周期过大-01](fight-with-compiler/lifetime/too-long1.md)
@ -194,7 +191,6 @@
- [线程间传递消息导致主线程无法结束](pitfalls/main-with-channel-blocked.md) - [线程间传递消息导致主线程无法结束](pitfalls/main-with-channel-blocked.md)
- [Rust 最佳实践 doing](practice/intro.md) - [Rust 最佳实践 doing](practice/intro.md)
- [日常开发三方库精选](practice/third-party-libs.md) - [日常开发三方库精选](practice/third-party-libs.md)
- [命名规范](practice/naming.md) - [命名规范](practice/naming.md)
- [代码开发实践 todo](practice/best-pratice.md) - [代码开发实践 todo](practice/best-pratice.md)
@ -229,7 +225,6 @@
- [Option 枚举 todo](profiling/compiler/optimization/option.md) - [Option 枚举 todo](profiling/compiler/optimization/option.md)
- [标准库解析 todo](std/intro.md) - [标准库解析 todo](std/intro.md)
- [标准库使用最佳时间 todo](std/search.md) - [标准库使用最佳时间 todo](std/search.md)
- [Vector 常用方法 todo](std/vector.md) - [Vector 常用方法 todo](std/vector.md)
- [HashMap todo](std/hashmap.md) - [HashMap todo](std/hashmap.md)

@ -1,5 +1,4 @@
# 疯狂字符串 # 疯狂字符串
字符串让人疯狂,这句话用在 Rust 中一点都不夸张,不信?那你能否清晰的说出 `String`、`str`、`&str`、`&String`、`Box<str>` 或 `Box<&str>` 的区别? 字符串让人疯狂,这句话用在 Rust 中一点都不夸张,不信?那你能否清晰的说出 `String`、`str`、`&str`、`&String`、`Box<str>` 或 `Box<&str>` 的区别?
Rust 语言的类型可以大致分为两种:基本类型和标准库类型,前者是由语言特性直接提供的,而后者是在标准库中定义。即将登场的 `str` 类型就是唯一定义在语言特性中的字符串。 Rust 语言的类型可以大致分为两种:基本类型和标准库类型,前者是由语言特性直接提供的,而后者是在标准库中定义。即将登场的 `str` 类型就是唯一定义在语言特性中的字符串。
@ -7,7 +6,6 @@ Rust 语言的类型可以大致分为两种:基本类型和标准库类型,
> 在继续之前,大家需要先了解字符串的[基本知识](https://course.rs/basic/compound-type/string-slice.html),本文主要在于概念对比,而不是字符串讲解 > 在继续之前,大家需要先了解字符串的[基本知识](https://course.rs/basic/compound-type/string-slice.html),本文主要在于概念对比,而不是字符串讲解
## str ## str
如上所述,`str` 是唯一定义在 Rust 语言特性中的字符串,但是也是我们几乎不会用到的字符串类型,为何? 如上所述,`str` 是唯一定义在 Rust 语言特性中的字符串,但是也是我们几乎不会用到的字符串类型,为何?
原因在于 `str` 字符串它是 [`DST` 动态大小类型](https://course.rs/advance/custom-type.html#动态大小类型),这意味着编译器无法在编译期知道 `str` 类型的大小,只有到了运行期才能动态获知,这对于强类型、强安全的 Rust 语言来说是不可接受的。 原因在于 `str` 字符串它是 [`DST` 动态大小类型](https://course.rs/advance/custom-type.html#动态大小类型),这意味着编译器无法在编译期知道 `str` 类型的大小,只有到了运行期才能动态获知,这对于强类型、强安全的 Rust 语言来说是不可接受的。
@ -17,7 +15,6 @@ let string: str = "banana";
``` ```
上面代码创建一个 `str` 类型的字符串,看起来很正常,但是编译就会报错: 上面代码创建一个 `str` 类型的字符串,看起来很正常,但是编译就会报错:
```shell ```shell
error[E0277]: the size for values of type `str` cannot be known at compilation time error[E0277]: the size for values of type `str` cannot be known at compilation time
--> src/main.rs:4:9 --> src/main.rs:4:9
@ -28,14 +25,20 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
如果追求更深层的原因,我们可以总结如下:**所有的切片都是动态类型,它们都无法直接被使用,而 `str` 就是字符串切片,`[u8]` 是数组切片。** 如果追求更深层的原因,我们可以总结如下:**所有的切片都是动态类型,它们都无法直接被使用,而 `str` 就是字符串切片,`[u8]` 是数组切片。**
同时还是 String 和 &str 的底层数据类型。 由于 str 是动态 同时还是 String 和 &str 的底层数据类型。 由于 str 是动态
`str` 类型是硬编码进可执行文件,也无法被修改,但是 `String` 则是一个可增长、可改变且具有所有权的 UTF8 编码字符串,**当 Rust 用户提到字符串时,往往指的就是 `String` 类型和 `&str` 字符串切片类型,这两个类型都是 UTF8 编码**。 `str` 类型是硬编码进可执行文件,也无法被修改,但是 `String` 则是一个可增长、可改变且具有所有权的 UTF8 编码字符串,**当 Rust 用户提到字符串时,往往指的就是 `String` 类型和 `&str` 字符串切片类型,这两个类型都是 UTF8 编码**。
除了 `String` 类型的字符串Rust 的标准库还提供了其他类型的字符串,例如 `OsString` `OsStr` `CsString` 和` CsStr` 等,注意到这些名字都以 `String` 或者 `Str` 结尾了吗?它们分别对应的是具有所有权和被借用的变量。 除了 `String` 类型的字符串Rust 的标准库还提供了其他类型的字符串,例如 `OsString` `OsStr` `CsString` 和` CsStr` 等,注意到这些名字都以 `String` 或者 `Str` 结尾了吗?它们分别对应的是具有所有权和被借用的变量。
**未完待续**
https://pic1.zhimg.com/80/v2-177bce575bfaf289ae12d677689a26f4_1440w.png https://pic1.zhimg.com/80/v2-177bce575bfaf289ae12d677689a26f4_1440w.png
https://pic2.zhimg.com/80/v2-697ad53cb502ccec4b2e98c40975344f_1440w.png https://pic2.zhimg.com/80/v2-697ad53cb502ccec4b2e98c40975344f_1440w.png
https://medium.com/@alisomay/strings-in-rust-28c08a2d3130
https://medium.com/@alisomay/strings-in-rust-28c08a2d3130

@ -16,7 +16,7 @@ Rust 最早是 Mozilla 雇员 Graydon Hoare 的个人项目。从 2009 年开始
## 为何又来了一门新语言? ## 为何又来了一门新语言?
简而言之,因为还缺一门无 GC、性能高、工程性强、语言级安全性以及能同时得到工程派和学院派认可的语言,而 Rust 算是这样的语言。你也可以回忆下熟悉的语言,看是不是有另外一门语言可以同时满足这些需求:) 简而言之,**因为还缺一门无 GC 且无需手动内存管理、性能高、工程性强、语言级安全性以及能同时得到工程派和学院派认可的语言**,而 Rust 就是这样的语言。你也可以回忆下熟悉的语言,看是不是有另外一门语言可以同时满足这些需求:)
Rust 最为人诟病的点,也就一个:学习曲线陡峭。不过其实严格来说,当语言生态起来后,这个不算问题。 Rust 最为人诟病的点,也就一个:学习曲线陡峭。不过其实严格来说,当语言生态起来后,这个不算问题。

Loading…
Cancel
Save