研读Rust圣经解析——Rust learn-15(unsafe Rust )

这篇具有很好参考价值的文章主要介绍了研读Rust圣经解析——Rust learn-15(unsafe Rust )。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

不安全的Rust

Rust 还隐藏有第二种语言,它不会强制执行这类内存安全保证:这被称为 不安全 Rust(unsafe Rust)

不安全 Rust 之所以存在,是因为静态分析本质上是保守的。当编译器尝试确定一段代码是否支持某个保证时,拒绝一些合法的程序比接受无效的程序要好一些。这必然意味着有时代码 可能 是合法的,但如果 Rust 编译器没有足够的信息来确定,它将拒绝该代码。在这种情况下,可以使用不安全代码告诉编译器,“相信我,我知道我在干什么。” 不过千万注意,使用不安全 Rust 风险自担:如果不安全代码出错了,比如解引用空指针,可能会导致不安全的内存使用。

另一个 Rust 存在不安全一面的原因是:底层计算机硬件固有的不安全性。如果 Rust 不允许进行不安全操作,那么有些任务则根本完成不了。Rust 需要能够进行像直接与操作系统交互,甚至于编写你自己的操作系统这样的底层系统编程!这也是 Rust 语言的目标之一。

主要来说共有5大操作

  1. 解引用裸指针
  2. 调用不安全的函数或方法
  3. 访问或修改可变静态变量
  4. 实现不安全 trait
  5. 访问 union 的字段

不过在这里我们只看1,2,3

unsafe关键字

使用unsafe 关键字我们可以创建一块不安全的区域,在其中使用unsafe rust

unsafe{
	//...
}

解引用裸指针

裸指针是可变或不可变的
应用于调用c语言中的接口
裸指针与引用和智能指针的区别在于:

  1. 允许忽略借用规则,可以同时拥有不可变和可变的指针,或多个指向相同位置的可变指针
  2. 不保证指向有效的内存
  3. 允许为空
  4. 不能实现任何自动清理功能

声明一个不可变的裸指针

不可变使用关键字*const并在后部指明类型

let a = 1;
let b = &a as *const i32;

声明可变的裸指针

可变使用关键字*mut并在后部指明类型

let c = &a as *mut i32;

注意点

可以在安全代码中 创建裸指针,只是不能在不安全块之外 解引用裸指针

调用不安全函数或方法

我们通过unsafe关键字可以设置一块区域,区域中使用不安全的代码(函数)

//声明
unsafe fn func(){}
//调用
unsafe{
	func();
}

创建不安全代码的安全抽象

仅仅因为函数包含不安全代码并不意味着整个函数都需要标记为不安全的。事实上,将不安全代码封装进安全函数是一个常见的抽象

以下是官方的例子:

fn main() {
    let mut v = vec![1, 2, 3, 4, 5, 6];

    let r = &mut v[..];

    let (a, b) = r.split_at_mut(3);

    assert_eq!(a, &mut [1, 2, 3]);
    assert_eq!(b, &mut [4, 5, 6]);
}

由于官方对split_at_mut说的非常详细,我再去复制显然没什么必要https://kaisery.github.io/trpl-zh-cn/ch19-01-unsafe-rust.html添加链接描述

使用 extern 函数调用外部代码

我们在学习一些Rust项目的时候,我们很可能在代码中看到一些使用其他语言的例子,事实上这个特性并不是Rust所独有的,只是你在Rust中使用起来更加为所欲为,在其他语言中,很可能是语言帮你隐式的调用,而非你能够感受的到(如:Java获取环境变量)
extern关键字可以创建一个外部函数接口以使用其他语言的函数,以下是调用了C语言中的abs函数,至于成不成功,这需要程序员保证,而不是Rust

extern "C" {
    fn abs(input: i32) -> i32;
}

fn main() {
    unsafe {
        println!("Absolute value of -3 according to C: {}", abs(-3));
    }
}

使用 extern和#[no_mangle] 暴露Rust函数给其他语言

相应的,可以调用别的语言的函数,我们也可以暴露自己的函数让其他语言调用

Rust中有一个宏:#[no_mangle]

告诉 Rust 编译器不要 mangle 此函数的名称。Mangling 发生于当编译器将我们指定的函数名修改为不同的名称时,这会增加用于其他编译过程的额外信息,不过会使其名称更难以阅读。每一个编程语言的编译器都会以稍微不同的方式 mangle 函数名,所以为了使 Rust 函数能在其他语言中指定,必须禁用 Rust 编译器的 name mangling。

#[no_mangle]
pub extern "Java" fn get_env(){
	return env::args().collect();
}

访问或修改可变静态变量

数据竞争:当多个线程访问相同的可变全局变量,通常静态变量的名称采用SCREAMING_SNAKE_CASE写法。静态变量只能储存拥有 'static 生命周期的引用,这意味着 Rust 编译器可以自己计算出其生命周期而无需显式标注。访问不可变静态变量是安全的。

常量与不可变静态变量的一个微妙的区别是静态变量中的值有一个固定的内存地址。使用这个值总是会访问相同的地址。另一方面,常量则允许在任何被用到的时候复制其数据。另一个区别在于静态变量可以是可变的。访问和修改可变静态变量都是不安全的

声明静态变量

使用static关键字对静态变量进行声明

static TEST: &str = "TEST";

修改静态变量

由于修改静态变量是非安全的操作,所以我们必须要在unsafe块中

static mut TEST: i32 = 100;

fn add() {
    unsafe {
        TEST += 5
    }
}

fn main() {
    add();
    unsafe {
        println!("{}", TEST);
    }
}

而当多个线程进行访问的时候我们需要用到消息传递机制和共享状态保证数据竞争不会发生文章来源地址https://www.toymoban.com/news/detail-429668.html

到了这里,关于研读Rust圣经解析——Rust learn-15(unsafe Rust )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 30天拿下Rust之unsafe代码

    概述         在Rust语言的设计哲学中,\\\"安全优先\\\" 是其核心原则之一。然而,在追求极致性能或者与底层硬件进行交互等特定场景下,Rust提供了unsafe。unsafe代码允许开发者暂时脱离Rust的安全限制,直接操作内存和执行低级操作。虽然unsafe代码在某些情况下是必要

    2024年04月17日
    浏览(45)
  • 开发安全之:Dangerous Function: Unsafe Regular Expression

    Overview 无法安全地使用函数 split()。不应该使用此函数。 Details 某些函数不论如何使用都有危险性。这一类函数通常是在没有考虑安全问题的情况下就执行了。 在这种情况下,您正在使用的危险函数为 dingdan_pc_list.php 的第 65 行中的 split()。 split() 函数不安全,因为它是已弃用

    2024年01月18日
    浏览(28)
  • rust-learn

    参考: 安装 - Rust 程序设计语言 中文版 安装 rustup:curl --proto \\\'=https\\\' --tlsv1.2 https://sh.rustup.rs -sSf | sh 完成后,提示:source \\\"$HOME/.cargo/env\\\"。输入命令即可! 其实就是执行:export PATH=\\\"$HOME/.cargo/bin:$PATH\\\"

    2024年02月21日
    浏览(38)
  • vs如何运行不安全的代码/不安全代码只会在使用 /unsafe 编译的情况下出现

    🔑 作者:@哈桑c(CSDN平台) 🐛 专栏:Bug解决记录 Visual Studio 报错: CS0227: 不安全代码只会在使用 /unsafe 编译的情况下出现。 在 Visual Studio 中右击报错的项目选择属性,找到生成里面的 允许使用“unsafe\\\"编译的代码 ,勾选即可。 图示步骤: 完成上述步骤之后,就可

    2024年02月12日
    浏览(45)
  • Angular安全专辑之二——‘unsafe-eval’不是以下内容安全策略中允许的脚本源

    一:错误出现 这个错误的意思是,拒绝将字符串评估为 JavaScript,因为‘unsafe-eval’不是以下内容安全策略中允许的脚本源。 二:错误场景 类似的不安全的表达式还有: eval() Function() ——When passing a string literal like to methods like: setTimeout(\\\"alert(\\\"Hello World!\\\");\\\", 500); setTimeout() s

    2024年02月12日
    浏览(50)
  • ERR_UNSAFE_PORT浏览器安全问题导致无法访问的解决方案

    配置好web的https协议的服务器后,使用浏览器访问服务器的时候出现ERR_UNSAFE_PORT无法访问,如下图提示。 img src=“https://juejin.cn/ “点击并拖拽以移动”” style=“margin: auto” / 经过抓取报文分析,并没有抓到访问服务器的报文,定位发现是浏览器的保护机制自动拦截了请求,和

    2024年02月03日
    浏览(101)
  • 使用net/http/pprof时,发现6000端口是Chrome限制的非安全端口,报错ERR_UNSAFE_PORT

    最近在go项目中,涉及到性能分析,使用了go自有的net/http/pprof包,设置了6000端口后,发现浏览器打不开。PC上只有Edge和Chrome两个浏览器,刚好都是chrome内核。排查了系统问题、端口占用问题后,一直卡在这里-_- 后面发现浏览器报错了ERR_UNSAFE_PORT。才知道浏览器为了安全问题

    2024年02月07日
    浏览(39)
  • Rust 正式发布八周年纪念日 2023.5.15

    图源:维基百科 目录 Rust 1. Rust的特点 1.1 安全性 1.2 并发性 1.3 性能 1.4 代码可读性 2. 使用场景 2.1 系统编程 2.2 Web开发 2.3 游戏开发 3. 与其他语言的对比 4. 代码示例  1. Hello, World! 2. 简单的函数 3. 变量绑定和变量类型推断 4. 结构体 5. 数组和向量 5. 未来展望 是一门由Mozilla开

    2024年02月05日
    浏览(43)
  • 听GPT 讲Rust源代码--library/std(15)

    题图来自 An In-Depth Comparison of Rust and C++ [1] 文件路径:rust/library/std/src/os/wasi/io/fd.rs 该文件的作用是实现与文件描述符(File Descriptor)相关的操作,具体包括打开文件、读写文件、修改文件状态等功能。 以下是该文件的详细内容介绍: 引用 该文件首先引入了一些需要使用到的

    2024年02月05日
    浏览(35)
  • scanf函数不安全: C4996 ‘scanf‘: This function or variable may be unsafe. Consider using scanf_s instead

    代码报错: scanf函数易受缓冲区溢出攻击的影响,可能导致安全问题。 scanf_s函数是一种更安全的选择,它将缓冲区的大小作为参数并避免了缓冲区溢出攻击 举个栗子: 字符数组的大小为 5 , 若输入的字符串字符数目不超过 5 ,那么没问题, ( 注意字符串后面默认会多出来一个 ‘

    2024年02月03日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包