|
|
|
@ -35,7 +35,7 @@ Bingo,果然报错了,编译器提示`greet`函数需要一个`String`类型
|
|
|
|
|
|
|
|
|
|
## 切片(slice)
|
|
|
|
|
|
|
|
|
|
切片并不是Rust独有的概念,在Go语言中就非常流行,它允许你引用集合中一段连续的元素序列,而不是引用整个集合。
|
|
|
|
|
切片并不是Rust独有的概念,在Go语言中就非常流行,它允许你引用集合中部分连续的元素序列,而不是引用整个集合。
|
|
|
|
|
|
|
|
|
|
对于字符串而言,切片就是对`String`类型中某一部分的引用,它看起来像这样:
|
|
|
|
|
```rust
|
|
|
|
@ -121,7 +121,7 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta
|
|
|
|
|
|
|
|
|
|
回忆一下借用的规则:当我们已经有了可变借用时,就无法再拥有不可变的借用。因为`clear`需要清空改变`String`,因此它需要一个可变借用,而之后的`println!`又使用了不可变借用,因此编译无法通过。
|
|
|
|
|
|
|
|
|
|
从上述代码可以看出,Rust不仅让我们的`api`更加容易使用,而且也在编译期就消除了大量错误!
|
|
|
|
|
从上述代码可以看出,Rust不仅让我们的`API`更加容易使用,而且也在编译期就消除了大量错误!
|
|
|
|
|
|
|
|
|
|
#### 其它切片
|
|
|
|
|
因为切片是对集合的部分引用,因此不仅仅字符串有切片,其它集合类型也有,例如数组:
|
|
|
|
@ -348,9 +348,9 @@ for b in "中国人".bytes() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 字符串深度剖析
|
|
|
|
|
那么问题来了,为啥`String`可变,而字符串字面值却不可以?
|
|
|
|
|
那么问题来了,为啥`String`可变,而字符串字面值`str`却不可以?
|
|
|
|
|
|
|
|
|
|
就字符串字面值来说,我们在编译时就知道其内容,最终文本被直接硬编码进可执行文件中。这使得字符串字面值快速且高效,上述特性主要得益于字符串的不可变性。不幸的是,我们不能为了获得这种性能,而把每一个在编译时大小未知的文本放进内存中(你也做不到!).
|
|
|
|
|
就字符串字面值来说,我们在编译时就知道其内容,最终字面值文本被直接硬编码进可执行文件中,这使得字符串字面值快速且高效,这主要得益于字符串的不可变性。不幸的是,我们不能为了获得这种性能,而把每一个在编译时大小未知的文本都放进内存中(你也做不到!),因为有的字符串是在程序运行得过程中动态生成的。
|
|
|
|
|
|
|
|
|
|
对于 `String` 类型,为了支持一个可变、可增长的文本片段,需要在堆上分配一块在编译时未知大小的内存来存放内容,这些都是在程序运行时完成的:
|
|
|
|
|
- 首先向操作系统请求内存来存放`String`对象
|
|
|
|
@ -358,9 +358,9 @@ for b in "中国人".bytes() {
|
|
|
|
|
|
|
|
|
|
其中第一个由`String::from`完成,它创建了一个全新的String.
|
|
|
|
|
|
|
|
|
|
重点来了,到了第二部分,就是百家齐放的环节,在有**垃圾回收GC**的语言中,GC来负责标记并清除这些不再使用的内存对象,这些都是自动完成,无需开发者关心,非常简单好用;在无GC的语言,是开发者手动去释放这些内存对象,就像创建对象一样,需要通过编写代码来完成,因为未能正确释放对象造成的结局简直不可估量.
|
|
|
|
|
重点来了,到了第二部分,就是百家齐放的环节,在有**垃圾回收GC**的语言中,GC来负责标记并清除这些不再使用的内存对象,这个过程都是自动完成,无需开发者关心,非常简单好用;但是在无GC的语言,需要开发者手动去释放这些内存对象,就像创建对象需要通过编写代码来完成一样,未能正确释放对象造成的结局简直不可估量.
|
|
|
|
|
|
|
|
|
|
对于Rust而言,安全和性能是写到骨子里的核心特性,使用GC牺牲了性能,使用手动管理内存牺牲了安全,那该怎么办?为此,Rust的开发者想出了一个无比惊艳的办法:变量在离开作用域后,就自动释放其占用的内存:
|
|
|
|
|
对于Rust而言,安全和性能是写到骨子里的核心特性,如果使用GC,那么会牺牲性能;如果使用手动管理内存,那么会牺牲安全,这该怎么办?为此,Rust的开发者想出了一个无比惊艳的办法:变量在离开作用域后,就自动释放其占用的内存:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
{
|
|
|
|
|