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

网站网页制作机构资深的网站建设

网站网页制作机构,资深的网站建设,网站做效果联系方式,wordpress怎么设置搜索显示页面说句题外话#xff0c;这篇文章真心很难#xff0c;有看不懂可以在评论区问#xff0c;我会尽快作答的。 喜欢的话别忘了点赞、收藏加关注哦#xff08;加关注即可阅读全文#xff09;#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵#xff01;(#xff65;ω…说句题外话这篇文章真心很难有看不懂可以在评论区问我会尽快作答的。 喜欢的话别忘了点赞、收藏加关注哦加关注即可阅读全文对接下来的教程有兴趣的可以关注专栏。谢谢喵(ω) 15.7.1. 内存泄漏 Rust极高的安全性使得内存泄漏很难出现但并不是完全不可能。 例如使用RcT和RefCellT就可能创造出循环引用造成内存泄漏每个指针的引用计数都不会减少到0值也不会被清理。 看个例子 use crate::List::{Cons, Nil}; use std::cell::RefCell; use std::rc::Rc;#[derive(Debug)] enum List {Cons(i32, RefCellRcList),Nil, }impl List {fn tail(self) - OptionRefCellRcList {match self {Cons(_, item) Some(item),Nil None,}} }fn main() {let a Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));println!(a initial rc count {}, Rc::strong_count(a));println!(a next item {:?}, a.tail());let b Rc::new(Cons(10, RefCell::new(Rc::clone(a))));println!(a rc count after b creation {}, Rc::strong_count(a));println!(b initial rc count {}, Rc::strong_count(b));println!(b next item {:?}, b.tail());if let Some(link) a.tail() {*link.borrow_mut() Rc::clone(b);}println!(b rc count after changing a {}, Rc::strong_count(b));println!(a rc count after changing a {}, Rc::strong_count(a)); }首先创建了一个链表List使用RefCellT包裹RcT使其内部值可被修改 通过impl块为List写了一个叫tail的方法用于获取List下Cons变体附带的第二个元素如果有就返回其值用Some封装是Nil就返回None。 然后在main函数创建了a、b两个List的实例b内部共享了a的值。这种链表的代码看着就犯恶心所以我把其结构图放在 这里 main函数里还通过Rc::strong_count获取了a和b的强引用数量使用自定义的tail方法获了Cons附带的第二个元素用println!打印出来。 下面使用if let语句把a的Cons的第二个值绑在link上通过borrow_mut方法获得其可变引用Cons使用解引用符号*把它转为Cons最后把b的值通过Rc::clone共享赋给了link也就改变了a内部的结构变为了 PS:我觉得自己画的太烂了所以这里就换成The Rust Programming Language里的图片了 输出: a initial rc count 1 a next item Some(RefCell { value: Nil }) a rc count after b creation 2 b initial rc count 1 b next item Some(RefCell { value: Cons(5, RefCell { value: Nil }) }) b rc count after changing a 2 a rc count after changing a 2第1行到第5行刚开始创建a时引用数量就为1当b被声明时a被共享了所以此时a的引用计数为2b为1。 第六行到第7行if let语句把a的内部结构改变了使a的第二个元素指向bb的引用数量加1变为2。此时a指向了bb又指向了a就会造成循环引用。 当a和b都走出了作用域Rust删除了变量b 这将b的引用计数从 2 减少到 1。此时RcList在堆上的内存不会被删除因为它的引用计数是1而不是0。然后 Rust 删除a 这会将a的RcList实例的引用计数从 2 减少到 1如图所示。这个实例的内存也不能被删除因为另一个实例的内存 RcList实例仍然引用它。分配给列表的内存将永远保持未回收状态。 接下来我们看看循环引用的内容是什么,使用这条代码 println!(a next item {:?}, a.tail());Rust 将尝试打印此循环其中a指向b指向a等等直到溢出堆栈。最终的结果会是栈溢出错误。 15.7.2. 防止内存泄漏的方法 那有什么方法来防止内存泄漏吗这只能依靠开发者不能依靠Rust。 不然就只能重新组织数据结构把引用拆分成持有和不持有所有权的两种情况一些引用用来表达所有权一些引用不表达所有权。循环引用的一部分具有所有权关系另一部分不涉及所有权关系。这样写只有所有权的指向关系才会影响到值的清理。 15.7.3. 把RcT换成WeakT以防止循环引用 我们知道Rc::clone会生成数据的强引用使RcT内部的引用计数加1而RcT只有在strong_count为0时才会被清理。 然而RcT实例通过调用Rc::downgrade方法创建值的弱引用(Weak Reference)。这个方法的返回类型是weakT也是智能指针每次调用Rc::downgrade会为weak_count加1而不是strong_count所以弱引用并不影响RcT的清理。 15.7.4. Strong vs. Weak 强引用(Strong Reference)是关于如何分析RcT实例的所有权。弱引用(Weak Reference)并不表达上述意思使用它不会创建循环引用当强引用数量为0时弱引用就会自动断开。 使用弱引用之前需要保证它指向的值仍然存在。在WeakT实例上调用upgrade方法返回OptionRcT通过Option枚举来完成值是否存在的验证。 看个例子 use std::cell::RefCell; use std::rc::Rc;#[derive(Debug)] struct Node {value: i32,children: RefCellVecRcNode, }fn main() {let leaf Rc::new(Node {value: 3,children: RefCell::new(vec![]),});let branch Rc::new(Node {value: 5,children: RefCell::new(vec![Rc::clone(leaf)]),}); }Node结构体代表一个节点有两个字段 value字段存储当前值类型是i32。children字段存储子节点类型是RefCellVecRcNode这里使用RcT是为了让所有子节点共享所有权。具体来说我们希望一个Node拥有它的子节点并且我们希望与储存这个节点的变量共享该所有权以便我们可以直接访问树中的每个Node 。为此我们将VecT项定义为RcNode类型的值。 这个例子的需求是每个节点都能指向自己的父节点和子节点。 再看一下main函数 创建了leaf是Node实例value为3children的值是被RefCell包裹的空Vector。创建了branch是Node实例value为5children的值指向了leaf。 这意味着leaf它里面的Node节点有两个所有者。目前可以通过branch的children字段访问leaf而反过来如果想通过leaf来访问branch暂时还不行所以这里还需要修改。 想要实现需求就得用双向引用但是双向的引用会创建循环引用所以这时候就得使用WeakT避免产生循环 struct Node {value: i32,parent: RefCellWeakNode,children: RefCellVecRcNode, }添加了parent字段表示父节点使用弱引用WeakT。这里不用Vec是因为这是个树结构父节点只可能有一个。 这么写得把WeakT引入作用域还得重构下文修改完后的整体代码如下 use std::cell::RefCell; use std::rc::{Rc, Weak};#[derive(Debug)] struct Node {value: i32,parent: RefCellWeakNode,children: RefCellVecRcNode, }fn main() {let leaf Rc::new(Node {value: 3,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![]),});println!(leaf parent {:?}, leaf.parent.borrow().upgrade());let branch Rc::new(Node {value: 5,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![Rc::clone(leaf)]),});*leaf.parent.borrow_mut() Rc::downgrade(branch);println!(leaf parent {:?}, leaf.parent.borrow().upgrade()); }在leaf被创建后先打印了其parent字段的内容这时parent字段还没有内容在branch被创建后打印了leaf的parent字段内容这时其内容就是branch。 *leaf.parent.borrow_mut() Rc::downgrade(branch);这句话把branch的内容从RcNode变为WeakNode指向了leaf的parent字段 leaf.parent是表示leaf父节点的字段其类型是RefCellWeakNode所以可以使用borrow_mut来获得其可变引用mut RefMutWeakNode使用解引用符号*把可变引用mut RefMutWeakNode变为RefMutWeakNode通过downgrade方法把branch的RcNode变为WeakNode并赋给parent 输出 leaf parent None leaf parent Some(Node { value: 5, parent: RefCell { value: (Weak) }, children: RefCell { value: [Node { value: 3, parent: RefCell { value: (Weak) }, children: RefCell { value: [] } }] } })第一次打印时其parent字段还没有被赋值所以其值是Option下的None变体。第二次打印时其父节点已被指定为branch不是无限输出表明此代码没有创建循环引用。 最后我们通过修改main函数——添加打印语句和修改作用域来看看强引用和弱引用的数量 fn main() {let leaf Rc::new(Node {value: 3,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![]),});println!(leaf strong {}, weak {},Rc::strong_count(leaf),Rc::weak_count(leaf),);{let branch Rc::new(Node {value: 5,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![Rc::clone(leaf)]),});*leaf.parent.borrow_mut() Rc::downgrade(branch);println!(branch strong {}, weak {},Rc::strong_count(branch),Rc::weak_count(branch),);println!(leaf strong {}, weak {},Rc::strong_count(leaf),Rc::weak_count(leaf),);}println!(leaf parent {:?}, leaf.parent.borrow().upgrade());println!(leaf strong {}, weak {},Rc::strong_count(leaf),Rc::weak_count(leaf),); }代码的逻辑是 创建完leaf之后打印里面有多少强引用和弱引用 这部分完了之后加了{}创建了新的作用域 把branch的声明和指定leaf父节点的操作放到里面打印branch和leaf在此时强引用、弱引用的数量 走出作用域后 打印leaf的parent打印leaf的强引用、弱引用 输出 leaf strong 1, weak 0 branch strong 1, weak 1 leaf strong 2, weak 0 leaf parent None leaf strong 1, weak 0第1行创建了leaf只有一个强引用第2行创建了branch由于branch使用强引用对leaf进行了关联其parent字段使用了Weak::new()创建所以branch有1个强引用一个弱引用第3行branch使用了leaf的强引用其本身在声明时又是一个强引用所以此时leaf就有两个强引用第4行由于branch已经走出其作用域所以leaf的parent字段此时就为None第5行branch已经走出其作用域导致它对leaf的强引用失效leaf的强引用减1变为1
http://www.w-s-a.com/news/288526/

相关文章:

  • 响应式企业网站开发所用的平台西安知名网站推广
  • 高端响应式网站建设wordpress 全屏主题
  • 国内工程机械行业网站建设现状ui是什么意思
  • 成都网站开发哪家公司好出售家教网站模板
  • 订阅号做流量 那些电影如何链接网站温州市建设监理协会网站
  • 成都网站建设成功案例单招网商丘网站建设大全
  • 受欢迎的购物网站建设网推专员是做什么的
  • 商城网站前期准备湖南郴州建设局网站
  • 企业如何在自己的网站上做宣传外贸自建站可以自己做网站吗
  • 甘肃网站建设制作商网站空间哪家公司的好
  • 思途旅游网站建设系统用vscode做网站
  • 广州站改造最新消息半年工作总结ppt模板
  • logo模板下载网站推荐哪家网站开发培训好
  • 做外贸网站效果图页面关键词优化
  • 广平网站建设成都活动轨迹
  • 小型网站网站建设需要网络公司是什么行业
  • 滑动 手机网站 代码网页制作与设计讨论
  • 自己做网站处理图片用什么软件wordpress html5支持
  • 校园网站怎么建软文文案范文
  • 中国建设官方网站如何创建自己的软件
  • 来宾住房与城乡建设网站天津西青区怎么样
  • 西安网站建设培训班鄂州网页定制
  • 西部数码网站备份自己怎么做网站啊
  • h5网站开发用什么软件制作公司网站建设代理怎么做
  • 网站建设资料准备网上购物app有哪些
  • 沧州做网站优化哪家公司便宜国内百度云网站建设
  • 网站的最近浏览 怎么做龙岩市人才网最新招聘信息
  • 网站建设需要找工信部吗网站开发账务处理
  • 做那种的视频网站个体工商网站备案
  • 推广网官方推广网站中国建设招聘信息网站