介绍

本系列录制的视频主要放在B站上Rust死灵书学习视频

Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source

详细内容

支持slice功能,我们实际上可以看成是对数据进行引用,因此我们只要实现Deref<Target=[T]>即可。

#![feature(ptr_internals)]
use std::mem;
use std::alloc::{alloc, realloc, dealloc, Layout, handle_alloc_error};
use std::ptr::{Unique, self};
use std::ops::{Deref, DerefMut};
use std::slice;pub struct MyVec<T> {ptr: Unique<T>,cap: usize,len: usize,
}impl<T> MyVec<T> {fn new() -> Self {assert!(mem::size_of::<T>() != 0, "还没准备好处理零尺寸类型");MyVec { ptr: Unique::dangling(), len: 0, cap: 0 }}fn grow(&mut self) {unsafe {let align = mem::align_of::<T>();let elem_size = mem::size_of::<T>();let layout: Layout;let (new_cap, ptr) = if self.cap == 0 {layout = Layout::from_size_align_unchecked(elem_size, align);let ptr = alloc(layout);(1, ptr)} else {let new_cap = self.cap * 2;let old_num_bytes = self.cap * elem_size;assert!(old_num_bytes <= (isize::MAX as usize) / 2,"capacity overflow");let new_num_bytes = old_num_bytes * 2;layout = Layout::from_size_align_unchecked(new_num_bytes, align);let ptr = realloc(self.ptr.as_ptr() as *mut _,layout,new_num_bytes);(new_cap, ptr)};if ptr.is_null() { handle_alloc_error(layout); }if let Some(ptr) = Unique::new(ptr as *mut _) {self.ptr = ptr;} else {panic!("error!");}self.cap = new_cap;}}fn push(&mut self, elem: T) {if self.len == self.cap { self.grow(); }//关键点在于要直接覆盖,因为不知道内存之前是否有东西unsafe {ptr::write(self.ptr.as_ptr().offset(self.len as isize), elem);}self.len += 1;}fn pop(&mut self) -> Option<T> {if self.len == 0 {None} else {self.len -= 1;unsafe {Some(ptr::read(self.ptr.as_ptr().offset(self.len as isize)))}}}
}impl<T> Drop for MyVec<T> {fn drop(&mut self) {if self.cap != 0 {while let Some(_) = self.pop() {}let align = mem::align_of::<T>();let elem_size = mem::size_of::<T>();let num_bytes = elem_size * self.cap;unsafe {let layout: Layout = Layout::from_size_align_unchecked(num_bytes, align);dealloc(self.ptr.as_ptr() as *mut _, layout)}println!("release memory in drop function!");}}
}impl<T> Deref for MyVec<T> {type Target = [T];fn deref(&self) -> &[T] {unsafe {slice::from_raw_parts(self.ptr.as_ptr(), self.len)}}
}impl<T> DerefMut for MyVec<T> {fn deref_mut(&mut self) -> &mut [T] {unsafe {slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len)}}
}fn main() {{let mut vec: MyVec<i32> = MyVec::new();vec.push(8);vec.push(7);vec.push(6);while let Some(v) = vec.pop() {println!("v == {}", v);}vec.push(8);vec.push(7);vec.push(6);let s = &vec[1..];println!("s[0] == {}", s[0]);let mut s = &mut vec[1..];s[0] = 10;println!("s[0] == {}", s[0]);}println!("Hello, world!");
}

上面实现了可变引用和不可变应用

030 Rust死灵书之让Vec支持slice相关推荐

  1. 033 Rust死灵书之重构Vec

    介绍 本系列录制的视频主要放在B站上Rust死灵书学习视频 Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source 详 ...

  2. 026 Rust死灵书之实现Vec

    介绍 本系列录制的视频主要放在B站上Rust死灵书学习视频 Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source 从 ...

  3. 035 Rust死灵书之Vec处理零尺寸类型

    介绍 本系列录制的视频主要放在B站上Rust死灵书学习视频 Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source 详 ...

  4. 032 Rust死灵书之Vec的IntoIter

    介绍 本系列录制的视频主要放在B站上Rust死灵书学习视频 Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source 详 ...

  5. 036 Rust死灵书之Vec的完整代码测试

    介绍 本系列录制的视频主要放在B站上Rust死灵书学习视频 Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source 详 ...

  6. 031 Rust死灵书之Vec实现insert和remove

    介绍 本系列录制的视频主要放在B站上Rust死灵书学习视频 Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source 详 ...

  7. 027 Rust死灵书之Vec内存分配

    介绍 本系列录制的视频主要放在B站上Rust死灵书学习视频 Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source V ...

  8. 029 Rust死灵书之Vec实现Drop

    介绍 本系列录制的视频主要放在B站上Rust死灵书学习视频 Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source 详 ...

  9. 028 Rust死灵书之Vec的push和pop

    介绍 本系列录制的视频主要放在B站上Rust死灵书学习视频 Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source V ...

最新文章

  1. qt能使用logback_Spring boot使用logback实现日志配置
  2. 保护眼睛设置.txt
  3. 与Google用户帐户集成
  4. 产品经理不得不知的APP数据分析及报表设计基础
  5. 安装 |GitBash闪退问题解决方案及Git安装教程( win10系统安装Git后)
  6. log.php(157),Log出现permission Denied的错误
  7. 2016年,新的一年,新的元素。
  8. 理解A*寻路算法具体过程
  9. 教你如何完全解析Kotlin中的注解
  10. 【Java】实现矩阵的转置
  11. datatable中使用linq的条件或_C# 10. LINQ 的三种查询语句写法
  12. 一步步学习SPD2010--第四章节--创建和修改网页(9)--附上母版页
  13. NSArray 和 NSMutableArray
  14. android:异步任务asyncTask介绍及异步任务下载图片(带进度条)
  15. WMI 查询分析工具更新
  16. 【CAD arx二次开发】CAD2020 通过Wizard向导新建arx项目
  17. Linux学习——编辑器Vim学习
  18. linux查看硬盘读取速度慢,Linux检测硬盘读取速度
  19. 世界知名游戏公司简介(国内,欧美,日韩)
  20. 为实施了IFD的Dynamics 365更换自签名的SSL证书以符合Chrome的要求

热门文章

  1. 企业邮箱域名怎么填写,企业邮箱号怎么注册?
  2. WOT2015 互联网运维与开发者大会上的演讲
  3. 树莓派3B网线连接笔记本电脑以及安装ubuntu16
  4. mega raid linux,在lsi megaraid sas 8204elp 装linux系统(未完待续)
  5. Windows 10通过cmd进入bios教程
  6. 《教务信息管理系统》项目总结
  7. 计算机内存die,你们说的美光E-DIE其实非常强(C9BJZ)
  8. java计算时针和分针的夹角_【Java算法】一天24小时中,时针和分针一共重合多少次?...
  9. Java设计模式之简单工厂模式实验(软件工程综合实践课程第二周)
  10. K8S 学习笔记三 核心技术 Helm nfs prometheus grafana 高可用集群部署 容器部署流程