Rust中的各种指针

xtutujs、golang、rust、关注他49 人赞同了该文章Rust 中的指针大体可以分为以下四种:引用 references“胖指针 fat pointers”(该分类存有争议)智能指针 smart pointers裸指针 raw pointers1. 引用就是直接对一个变量执行 &、&mut 操作,永远不会为 null。其占用的大小与 usize 一致。与引用相关的一个名词是 借用(borrowing)。其定义为:将获取引用作为函数参数称为 借用(borrowing)fn test_ref(){    let mut num = 5;    let num_ref = &mut num;    *num_ref = 100;    println!("{} sizeof &i32 {}", num, std::mem::size_of::<&i32>())    // output 100 sizeof &i32:8}2. 胖指针比引用多了些其它数据。在 rust 中,属于胖指针的数据:切片( &[T] )。 T 为切片内元素的类型。切片类型存有: "地址(ptr) + 长度(len) "两个字段。图中红框内,就是一个切片。

fn test_fat_pointers(){    let mut arr = [1, 2, 3, 4];    let slice = &mut arr[1..4];    slice[0] = 100;    println!("{:?}", arr);   // [1, 100, 3, 4]    let slice = &arr[1..4];    println!("{:p} {:?}", slice, unsafe { transmute::<_, (usize, usize)>(slice) });    // Output: 0x8a6c0ff4ac (594518471852, 3)    //      0x8a6c0ff4ac 594518471852 这两个值是相等的。    //      (594518471852, 3) 分别表示 具体数据的堆地址 和 长度 两个字段。    //      注意这里是用 slice,而不是 &slice。(&slice表示这个变量本身的栈地址)    println!("sizeof &[i32]:{}", std::mem::size_of::<&[i32]>());    // Output: sizeof &[i32]:16    // 因为包含了两个字段:地址 + 长度,所以其占用内存为 2 个 usize 类型大小}3. 智能指针有特殊功能的,实现了 Deref、drop 相关的trait。在 rust 中,属于智能指针的数据:String、 Vec<T>、Box、Cell、Rc 等等。每一个智能指针的实现都不大一样,这里就不再展开叙述。仅以 Box 举例:fn test_smart_pointers(){    // 将本应存在栈上的地址,存在了堆上    let mut num = Box::new(1);    // num_address 指向 box 里面的具体内容(也就是储存在堆上的数值 1)    let num_address : *mut i32 = &mut *num;    unsafe {        *num_address = 100    }    println!("{}", *num + 100)     // Output: 200}4. 裸指针类似 C 语言里面的指针,可以为 null !创建裸指针,是 safe 的,读写裸指针,才需要 unsafe !裸指针又可以分为可变、不可变,分别写作 *mut T 和 *const T这里的星号不是解引用运算符,它是类型名称的一部分。这里的 T 表示指针指向的具体类型,裸指针本身的的类型大小与 usize 一致。评论区有朋友指出:裸指针也能指向不定长类型,而且跟指向不定长类型的引用具有一样的内存布局。所以调用 sizeof,获得的大小是原始类型的大小。(不过指针这个变量本身的占用大小应该还是 一个 usize)详见评论区的讨论fn test_raw_pointers(){    let mut num = 1;    // 将引用转为裸指针    let num_raw_point = &mut num as *mut i32;    unsafe {        *num_raw_point = 100;        println!("{} {} {:p}", num, *num_raw_point, &num);         // Output: 100 100 0x8d8c6ff6bc    }    let address = num_raw_point as usize;    // 将一个 usize 对象,转化为 裸指针    let raw = address as *mut i32;    unsafe {        *raw = 200;        println!("{} {} {:p} {}", num, *num_raw_point, &num, address);        // Output: 200 200 0x8d8c6ff6bc 607946536636    }}

(0)

相关推荐

  • Rust基础学习笔记(零):复习基本知识

    由于一个学期没有碰Rust,相关知识殆已忘尽.最近各课逐渐停授,余出时间来从基础重温这些知识,也算是对没有写的基础知识的补充.另外这次复习主要参照了Youtube上的Crush Course视频,两个 ...

  • 方法重载

    方法名必须相同,参数列表不同(类型或个数或排列顺序不同) public static int max(int num1, int num2) { //方法体 } public static doubl ...

  • 为什么我十分喜欢C却很不喜欢C(尽管你可以在 Excel 中编写光线追踪程序但最好还是使用其他语言)

    (尽管你可以在 Excel 中编写光线追踪程序但最好还是使用其他语言) https://m.toutiao.com/is/eXb3Ueb/ 以下为译文: 为什么说C不是最好的语言? 首先,这个世上没有 ...

  • Rust 中的 Closure

    原理 有些语言中没有 closure 和普通函数的区分,但 Rust 有.对 Rust 来说普通函数就是一段代码.而 closure 和 C 类似:每个 closure 会创建一个匿名的struct, ...

  • day05_运算符入门

    2020-11-19 21:31:42  阅读:6  来源: 互联网 运算符概述 运算符是指对操作数的运算方式.组成表达式的 Java 操作符有很多种(什么是操作数和操作符,例如 1+2,其中 1 和 ...

  • C语言指针用法详解 (三) 二重指针

    二重指针 例子1: Question int **ptr1 = NULL; cout<<"情况一 ptr1=="<<ptr1<<endl; co ...

  • javascript深入参数传递

    我们都知道javascript的基础数据类型有: Undefined . Null . Boolean . Number . String . 如果从一个变量向另一个变量复制基本类型的值,会在变量对象 ...

  • (25条消息) 【Rust每周一知】Rust中的读写锁RwLock

    本文简单介绍 Rust 中的读写锁RwLock,内容概览如下: 经典问题 读者-作家问题 基本概念 临界区 Critical p 互斥量 Mutex 信号量 Semaphore 读写锁 RWLock ...

  • (25条消息) Rust 中的属性

    属性是什么 属性(Attribute)是一种通用的自由格式的元数据,Rust 中的属性以ECMA-335中的为模型,其语法则来自ECMA-334(C#). 属性的用途 属性只能应用于 Rust 中的项 ...

  • rust中带move闭包和不带move闭包有什么区别

    福哥答案2020-11-01: 1.是否是同一个变量:带move闭包,函数外和函数内的同名变量不是同一个变量.不带move闭包,函数外和函数内的同名变量是同一个变量. 2.执行完闭包后:带move闭包 ...

  • Rust中的格式化输出

    Rust中的格式化输出 格式化输出 println的使用 fmt::Debug的使用 fmt::Display的使用 一个list类型的对象的自定义格式化输出 format的使用 格式化输出 rust ...

  • C/C++编程笔记:C++中的引用!(含引用和指针的对比)

    当将变量声明为引用时,它将成为现有变量的替代名称.通过在声明中添加"&",可以将变量声明为引用. C++: 输出: x = 20 ref= 30 应用范围:  修改函数中传 ...

  • C 语言中如何使用返回值为指针的函数

    宇宙辩证法2021-03-08 16:06:12 如何使用返回值为指针的函数 (一)程序代码如下: #include<iostream> using namespace std; int ...

  • (25条消息) rust 声明宏中可以捕获的类型列表

    item, 代表语言项,就是组成一个 Rust 包的基本单位,比如模块.声明.函数定义 .类型定义.结构体定义. imp!实现等. block ,代表代码块,由花括号限定的代码. stmt,代表语句 ...

  • Rust 智能指针(Rc)

    std::rc::Rc Rc代表引用计数 以下是标准库文档的介绍 Single-threaded reference-counting pointers. 'Rc' stands for 'Refer ...