|
|
@ -24,17 +24,24 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
|
|
|
|
|
|
|
|
|
|
|
|
也就是说,我们无法直接使用 `str`,而对于 `[u8]` 也是类似的,大家可以自己动手试试。
|
|
|
|
也就是说,我们无法直接使用 `str`,而对于 `[u8]` 也是类似的,大家可以自己动手试试。
|
|
|
|
|
|
|
|
|
|
|
|
总之,我们可以总结出一个结论:**在 Rust 中,所有的切片都是动态类型,它们都无法直接被使用**。
|
|
|
|
总之,我们可以总结出一个结论:**在 Rust 中,所有的切片都是动态大小类型,它们都无法直接被使用**。
|
|
|
|
|
|
|
|
|
|
|
|
### 为什么切片是动态类型
|
|
|
|
#### 为何切片是动态大小类型
|
|
|
|
很简单,切片就是一个未知长度的数组,前面已经讲过, 未知长度的类型是不能分配在栈上的, 所以你不能用 `let s: [T] = ...` 的形式来声明一个栈上的变量。 那么有什么办法来使用数组呢?
|
|
|
|
原因在于底层的切片长度是可以动态变化的,而编译器无法在编译期得知它的具体的长度,因此该类型无法被分配在栈上,只能分配在堆上。
|
|
|
|
1. 固定长度数组, 声明时带上长度: `let a: [i8;4] = [1,2,3,4];`
|
|
|
|
|
|
|
|
2. 对于不固定长度的, 使用切片引用,切片引用类似于`trait object`,也是一个胖指针, 包含了切片的起始位置和长度,这样一来因为切片引用的大小是固定的(一个起始位置,一个长度,当然大小固定啦),也就能在栈上分配了。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 为何切片只能通过引用来使用
|
|
|
|
|
|
|
|
既然切片只能分配到堆上,我们就无法直接使用它,大家可以想想,所有分配在堆上的数据,是不是都是通过一个在栈上的引用来访问的?切片也不例外。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 为何切片引用可以存储在栈上
|
|
|
|
|
|
|
|
切片引用是一个宽指针,存储在栈上,指向了堆上的切片数据,该引用包含了切片的起始位置和长度,而且最重要的是,类似于指针,引用的大小是固定的(起始位置和长度都是整形),因此它才可以存储在栈上。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 有没有可以存储在栈上的
|
|
|
|
|
|
|
|
有,使用固定长度的数组: `let a: [i8;4] = [1,2,3,4];`,注意看,数组的类型与切片是不同的,前者的类型带有长度:`[i8;4]`,而后者仅仅是 `[i8]`。
|
|
|
|
|
|
|
|
|
|
|
|
那么问题来了,该如何使用切片呢?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 切片引用
|
|
|
|
## 切片引用
|
|
|
|
|
|
|
|
那么问题来了,该如何使用切片呢?
|
|
|
|
|
|
|
|
|
|
|
|
何以解忧,唯有引用。由于引用类型的大小在编译期是已知的,因此在 Rust 中,如果要使用切片,就必须要使用它的引用。
|
|
|
|
何以解忧,唯有引用。由于引用类型的大小在编译期是已知的,因此在 Rust 中,如果要使用切片,就必须要使用它的引用。
|
|
|
|
|
|
|
|
|
|
|
|
`str` 切片的引用类型是 `&str`,而 `[i32]` 的引用类型是 `&[i32]`,相信聪明的读者已经看出来了,`&str` 和 `&[i32]` 都是我们非常常用的类型,例如:
|
|
|
|
`str` 切片的引用类型是 `&str`,而 `[i32]` 的引用类型是 `&[i32]`,相信聪明的读者已经看出来了,`&str` 和 `&[i32]` 都是我们非常常用的类型,例如:
|
|
|
|