首页 > 其他分享 >rust 集合当成智能指针

rust 集合当成智能指针

时间:2023-11-04 14:45:48浏览次数:30  
标签:所有权 当成 Person Vec 集合 指针 rust 内存

集合当成智能指针

通过为集合实现 Deref trait,提供其拥有和借用的数据视图。

Vec是一个拥有T的集合,然后通过实现Deref完成&Vec到&[T]的隐式解引用,从而提供借用T的集合(即&[T])

#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> {
    fn drop(&mut self) {
        unsafe {
            // 对 [T] 使用 drop,使用原始切片将 vector 的元素称为最弱必要类型;
            //
            // 在某些情况下可以避免有效性问题
            ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len))
        }
        // RawVec 处理重新分配
    }
}

Vec 提供拥有T的集合,&[T] 提供借用T的集合。大部分情况下,只需要借用视图,提供两种方式,让用户在使用时在借用和拥有之间做出选择。

在 Rust 中,集合类型(如Vec[T]、String等)被视为智能指针。它们可以自动管理在堆上分配的内存,并在其所有权范围结束时自动释放该内存。下面是一个示例,展示了Vec[T]集合类型如何在其所有权范围结束时释放其内存。

struct Person {
    name: String,
    age: i32,
}

impl Person {
    fn new(name: String, age: i32) -> Self {
        Self { name, age }
    }
}

fn main() {
    let people = vec![
        Person::new("Alice".to_string(), 32),
        Person::new("Bob".to_string(), 28),
        Person::new("Charlie".to_string(), 75),
    ];
    
    for person in people.iter() {
        println!("{} is {} years old.", person.name, person.age);
    }
    
    println!("Done!");
} // 所有权范围结束,people集合释放其内存

在这个例子中,我们创建了一个包含三个Person的Vec[Person]集合。然后,我们遍历这个集合,并打印每个人的姓名和年龄。最后,我们结束了main函数,这导致people集合的所有权范围结束,并释放其在堆上分配的内存。Rust 借助所有权系统和集合类型的智能指针功能,确保我们不会遗漏释放内存的情况。

需要注意的是,这种智能指针功能仅在集合类型的所有权范围结束时起作用。如果我们意外地在集合之外保留了一个元素的引用,那么该元素的内存将不会被释放,这可能会导致内存泄漏。因此,在编写 Rust 代码时,需要注意集合元素的所有权范围,并确保本应释放的内存被正确释放。

标签:所有权,当成,Person,Vec,集合,指针,rust,内存
From: https://www.cnblogs.com/liuzonglin/p/17809307.html

相关文章

  • rust 指针
    指针deref()方法是将一个智能指针转换为底层数据类型的引用。fnmain(){leta=vec![1,2,3];a.iter().for_each(|f|println!("{}",f));//deref方法是将一个智能指针转换为底层数据类型的引用。letb=a.deref();b.iter().for_each(|f|printl......
  • rust 析构器中做最终处理
    析构器中做最终处理Rust中,通常在析构函数中运行退出前必须运行的代码。#[derive(Debug)]pubstructA(u8);implDropforA{fndrop(&mutself){println!("Aexit")}}#[derive(Debug)]pubstructB(u8);implDropforB{fndrop(&mutself)......
  • rust 使用 take 和 replace 来保留所有值
    使用take和replace来保留所有值枚举类型enumMyEnum{A{name:String,x:u32},B{name:String},}使用std::mem::take()和std::mem::replace()在不克隆name的情况下修改name这种方式可以不用#[derive(Clone)],不存在内存分配。#![allow(unused)......
  • rust 使用借用类型作为参数
    使用借用类型作为参数编码时应该总是倾向于使用借用类型而不是借用所有类型。对于String类型来说,应该倾向于使用使用&str,而不是&String;#[allow(unused)]fnmain(){letstring:String="hello".to_string();letborrow_string:&String=&string;letborrow......
  • rust PBFT
    PBFT(PracticalByzantineFaultTolerance)PBFT(PracticalByzantineFaultTolerance)算法是一种分布式共识算法,旨在解决拜占庭将军问题(ByzantineGeneralsProblem)。拜占庭将军问题是指在分布式系统中,由于网络故障或者节点故障等原因,导致节点之间无法达成共识或者达成错误的共识。......
  • rust Unsurprising
    Unsurprising(不意外)最少意外原则接口应尽可能直观(可预测,用户能猜对)至少应该不让人感到惊奇核心思想贴近用户已经知道的东西(不必重学概念)让接口可测试命名实践实现常用的Traits人体工程学(Ergonomic)Traits包装类型(WrapperType)命名实践接口的名称,应符......
  • rust p2p
    p2p[+]Expanddescriptionp2p简介P2P:peer-to-peer(点对点)P2P是一种网络技术,可以在不同的计算机之间共享各种计算资源,如CPU、网络带宽和存储。P2P是当今用户在线共享文件(如音乐、图像和其他数字媒体)的一种非常常用的方法。Bittorrent和Gnutella是流行的文件共享p2p......
  • rust async
    asyncSend和Sync在跨线程时需要关注Send:ownership(所有权)可以send到其他线程AtypeisSendifitissafetosendittoanotherthread.Sync:可以并发,无线程安全问题AtypeisSyncifitissafetosharebetweenthreads(TisSyncifandonlyif&T......
  • Rust 结构体的方法描述
    Rust结构体的方法描述原文地址:https://rustwiki.org/zh-CN/rust-by-example/fn/methods.htmlRust的方法(method)是依附于对象的函数。这些方法通过关键字self来访问对象中的数据和其他。方法在impl代码块中定义。静态方法(staticmethod)静态方法不需要实例来调用,把结构体......
  • 实验3 类与数组、指针
    实验任务1Point.hpp1#pragmaonce23#include<iostream>4usingstd::cout;5usingstd::endl;67classPoint{8public:9Point(intx0=0,inty0=0);10~Point()=default;1112intget_x()const;13intget_y()co......