当前位置: 首页 > news >正文

抖音代运营有什么内容优化推广联盟

抖音代运营有什么内容,优化推广联盟,网推是干什么的,代还软件开发装箱是最简单直接的一种智能指针&#xff0c;它的类型是Box<T>。装箱使我们可以把数据存储到堆上&#xff0c;并在栈上保留一个指向堆数据的指针。装箱操作常常被用于下面的场景&#xff1a; 当你拥有一个无法在编译时确定大小的类型&#xff0c;但又想使用这个类型的值…

装箱是最简单直接的一种智能指针,它的类型是Box<T>。装箱使我们可以把数据存储到堆上,并在栈上保留一个指向堆数据的指针。装箱操作常常被用于下面的场景:

  1. 当你拥有一个无法在编译时确定大小的类型,但又想使用这个类型的值时。
  2. 当你需要传递大量数据的所有权,但又不希望产生大量数据的复制行为时。
  3. 当你希望拥有一个实现了指定trait的类型值,但又不关心具体的类型时。
fn main() {let b = Box::new(5);println!("b = {}", *b + 3);println!("b = {}", b);
}

常规引用就是一种类型的指针,你可以将指针形象地理解为一个箭头,它会指向存储在别处的某个值。

装箱类似于常规指针,也可以通过解引用来获取装箱实际的值,代码中*b就是如此。这个定义和Go中的unsafe.Pointer非常类似,所有具体类型的指针都可以用一种类型的指针来表示。

定义递归类型

RUST必须在编译时知道每一种类型占据的空间大小,但有一种递归的类型却无法在编译时被确定具体大小。比如下面例子中的链表:

use crate::List::{Cons, Nil};
enum List {Cons(i32, List),Nil,
}fn main() {let list = Cons(1, Cons(2, Cons(3, Nil)));
}

我们尝试使用枚举来表达一个持有i32值的链表数据类型,通过不断嵌套元组的形式最终组成一个列表。

但程序无法编译通过,RUST认为这个类型拥有无限大小,无法确认类型所占用的存储空间大小。

enum Message {Quit,Move { x: i32, y: i32 },Write(String),ChangeColor(i32, i32, i32),
}

RUST如何计算Message类型的大小?为了计算Message值需要多大的存储空间,RUST会遍历枚举中的每一个成员来找到需要最大空间的那个变体。Message::Quit不需要占用任何空间,Message::Move需要两个存储i32值的空间,以此类推。

因为指针大小是恒定的,要改变这样无穷递归的情况,就应该将Cons变体中存放一个Box<T>而不是直接存放另外一个List值,而Box<T>则会指向下一个List并存储在堆上。

use crate::List::{Cons, Nil};
enum List {Cons(i32, Box<List>),Nil,
}fn main() {let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
}

新的Cons变体中需要一部分存储i32的空间和一部分存储装箱指针的空间,这样调整之后,List值都只需要占用一个i32值加上一个装箱指针的空间。通过使用装箱,我们打破了无限递归的过程,进而使编译器可以计算出List值所占用的空间。

Box<T>属于智能指针的一种,因为它实现了Defer trait,所以允许我们将Box<T>的值当做引用来对待。当一个Box<T>值离开作用域时,因为它实现了Drop trait,所以Box<T>指向的堆数据会自动地被清理释放。==

实现 Defer trait将类型视作引用

定义我们自己的智能指针,Box<T>类型最终被定义为拥有两个元素的元组结构体。结构体给Deref trait实现了defef方法,该方法会借用self并返回一个指向元素第一个元素的引用。

RUST所有权系统决定了deref方法需要返回一个引用。假设deref方法使编译器直接返回了值而不是指向值的引用,那么这个值就会被移除self。在大多数使用解引用运算符的场景下,我们并不希望获取MyBox<T>内部值的所有权。

type Target = T 定义了Deref trait的一个关联类型。我们在deref方法体中返回指向第一个元素的引用,进而允许调用者通过*运算符访问值。

use std::ops::Deref;struct MyBox<T>(T, T);impl<T> MyBox<T> {fn new(x: T, y: T) -> MyBox<T> {MyBox(x, y)}
}impl<T> Deref for MyBox<T> {type Target = T;fn deref(&self) -> &Self::Target {&self.0}
}fn hello(language: &str) {println!("Hello, {}", language)
}fn main() {let m = MyBox::new(String::from("Rust"), String::from("Go"));hello(&m);
}

在没有Deref trait的情况下,编译器只能对&形式的常规引用执行解引用操作。deref方法使编译器可以从任何实现了Deref的类型中获取值,并能够调用deref方法来获取一个可以进行解引用的引用。

解引用转换(deref coercion)是RUST为函数和方法的参数提供的一种便捷特性。当某个类型T实现了Deref trait时,它能够将T的引用转换为T经过Deref操作之后的引用。

函数hello接收&str字符串切片类型,自定义MyBox<T>自动解引用为元组第一个元素的引用&String。函数体需要&str类型,但现在传入的是&String类型,为什么编译依然能够通过呢?

能够使用&String的原因也是因为解引用操作,编译器可以自动将&String类型的参数强制转换为&str类型。

解引用转换与可变性

使用Deref trait能够重载不可变引用的*运算符,与之类似,使用DerefMut trait能够重载可变引用*运算符。

RUST会在类型与trait满足下面三种情形下执行解引用转换:

  • T: Deref<Traget=U>时,允许&T转换为&U
  • T: DerefMut<Target=U>时,允许&mut T转换为&mut U
  • T: Deref<Target=U>时,允许&mut T转换为&U

第三种情况,RUST会将一个可变引用转换为一个不可变引用。但这个过程绝对不可逆,也就是说不可变引用永远不可能转换为可变引用。因为按照借用规则,如果存在一个可变引用,那么它就必须是唯一的引用,否则程序无法编译通过。

Drop trait在清理时运行代码

我们可以通过实现Drop trait来指定值离开作用域时需要运行的代码。Drop trait要求实现一个接收self可变引用作为参数的drop函数。

Go语言中的defer也有类似的能力,在离开作用域时执行代码。

struct CustomSmartPointer {data: String,
}impl Drop for CustomSmartPointer {fn drop(&mut self) {println!("Dropping CustomSmartPoint with data {}", self.data)}
}fn main() {let c = CustomSmartPointer {data: String::from("my stuff"),};let d = CustomSmartPointer {data: String::from("other stuff"),};// drop(c);println!("main")
}

这段代码没有显示地将Drop trait引入作用域,因为它已经被包含在预导入模块中。RUST会在实例离开作用域时自动调用我们编写的drop代码。因为变量的丢弃顺序与创建顺序相反,所以,dc之前被丢弃。

RUST并不允许我们手动调用Drop traitdrop方法,因为自动和手动会两次触发drop,这种行为试图对同一个值清理两次而导致重复释放(double free)错误。

如果需要提前清理一个值,可以调用标准库中的std::mem:drop函数来提前清理某个值。代码注释部分的代码就用来提前清理c

使用Drop无需担心正在使用的值被意外清理掉:所有权系统会保证所有引用的有效性,而drop只会在确定不使用这个值时被调用一次。

http://www.zhongyajixie.com/news/17062.html

相关文章:

  • 明星用什么软件做视频网站怎么免费注册域名
  • 自建网站国家审核要多久百度新闻客户端
  • 手表商城网站建设外贸网站建设优化
  • 东莞网站推广模板产品推广计划书怎么写
  • 网站建设专家论证会专业网站优化培训
  • 廊坊网站排名优化公司热词分析工具
  • 海口市龙华区核酸检测优化方法
  • 贵州省建设项目验收备案网站模板建站平台
  • 贵州建设厅安全员b证考试网站谷歌搜索引擎大全
  • 做外贸通常用哪些网站新乡网站优化公司
  • 哪个网站有手机网络推广的方法和技巧
  • 编程 给别人做网站网站备案查询官网
  • 徐老师在那个网站做发视频下载海外seo推广公司
  • 重庆綦江网站制作公司哪家专业win7优化设置
  • 淮北矿业 集团 工程建设有限责任公司网站简述seo和sem的区别
  • 汽车品牌推广策划方案seo综合查询怎么关闭
  • 淘宝联盟怎么自己做网站推广域名查询网址
  • 谷歌 网站做推广优化seo深圳
  • 精品网站建设费用网站的seo 如何优化
  • 单位网站制作费用报价单大数据培训课程
  • 网站建设 广西杭州网站优化效果
  • 什么网站可以申请做汉语老师网站目录提交
  • 最后的目的是什么sem优化
  • 郑州网站设计培训html简单网页代码
  • 手机兼职赚钱日结一单一结上海seo公司排名
  • 用dreamweaver做网站渠道网络
  • 批量做网站佛山竞价账户托管
  • 宠物电子商务网站建设方案中国十大经典广告
  • 怎么在网站挂黑链接汽车宣传软文
  • 上海大规模网站建设平台电池优化大师下载