Rust所有权规则

这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战

所有权规则

所有权是有一套规则的,首先看一下所有权的具体规则:

- 每个值都有一个变量,这个变量是该值的所有者(owner)
- 每个值任一时刻有且只能有一个所有者
- 当所有者(变量)离开其作用域,这个值就会被删除
复制代码

变量作用域(scope)

上述所有权规则中提到当所有者(变量)离开其作用域,这个值就会被删除,这一小部分我们就来看一下变量的作用域。

作用域scope 就是一个item 在程序中的有效范围,比如如下代码,变量i绑定了一个字符串字面值,这个变量从声明的点开始直到当前 作用域 结束时都是有效的。

fn main() {
    // i 在还没有声明的时候是无效的
    let i = "rust";  // 从此处起,i 是有效的
    
    println!("{}", i); // 可以对i变量进行操作
}
// i 作用域到此结束,i 不再有效
复制代码

总结来说,上面代码有两个重要的事件点:

  • i 进入作用域 时,它就是有效的。
  • 这一直持续到它 离开作用域 为止。

目前为止,变量是否有效与作用域的关系跟其他编程语言是类似的。现在我们在此基础上介绍 String 类型。

string类型

string类型是比前面文章介绍的基本的标量类型都要更复杂的数据类型,前面介绍的数据类型都是存储时被移出栈,因此需要一个存储在堆上的数据来探索 Rust 是如何知道该在何时清理数据的。而string类型就是存储在堆上的数据。

不过这里的重点是关注string类型喝所有权相关的部分,这些部分也同样适用于标准库提供的或者自己创建的其他的复杂数据类型,后面的文章中会更加详细的介绍string类型。

字符串字面值很方便,但是并不适合使用文本的每一种场景。原因之一就是它们是不可变的。另一个原因是并非所有字符串的值都能在编写代码时就知道:例如,要是想获取用户输入并存储该怎么办呢?为此,Rust 有第二个字符串类型,String。这个类型被分配到堆上,所以能够存储在编译时未知大小的文本。可以使用 from 函数基于字符串字面值来创建 String,如下:

fn main() {
    let s = String::from("rust");
}
复制代码

这两个冒号(::)是运算符,允许将特定的 from 函数置于 String 类型的命名空间(namespace)下,而不需要使用类似 string_from 这样的名字。

我们也可以修改此类字符串:

fn main() {
    let s = String::from("rust");
    s.push_str(", good");  // push_str 方法在字符串后面追加值
    println!("{}", s);  // 结果是 rust, good
}
复制代码

这里就会产生一个问题,为什么String类型可变而字面值却不行呢?区别就在于两种数据类型对内存的处理上,这里留一个小悬念,在下一篇文章中进行解答哦~

结语

文章首发于微信公众号程序媛小庄,同步于掘金

码字不易,转载请说明出处,走过路过的小伙伴们伸出可爱的小指头点个赞再走吧(╹▽╹)

猜你喜欢

转载自juejin.im/post/7033591042930802725