rust - 在范围内有不正确(大于正确)生命周期的引用是否可以?
问题描述
如果大于引用的值,引用是否会&'a T
立即导致 UB(未定义的行为) ?'a
或者,只要它不超过 type 的引用值,就可以拥有这样的引用T
?
作为比较:mem::transmute::<u8, bool>(2)
是立即 UB,即使您从不访问返回值。如果您有带有 value 的引用,情况也是如此0
,因为引用必须始终有效。即使您从不访问它们。另一方面,在ptr::null()
您尝试取消引用空指针之前,拥有不是问题。
考虑这段代码:
let x = '';
let r_correct: &char = &x;
{
let r_incorrect: &'static char = unsafe { mem::transmute(r_correct) };
println!("{}", r_incorrect);
}
在此代码中,有两个对x
. 两者都没有寿命x
。但类型的r_incorrect
显然是一个谎言,因为x
它不会永远存在。
此代码是否表现出明确定义的行为?我看到三个选项:
- (a) 此代码表现出未定义的行为。
- (b) 这段代码的行为是明确定义的(“安全的”)。
- (c) Rust 还没有定义这部分语言的规则。
解决方案
r_incorrect
不,只有在超出范围后访问才会发生未定义的行为x
,而您在这里没有这样做。
Rust 中的生命周期注解由编译器检查,以确保您没有做任何会导致内存不安全的事情,但是——假设借用检查器很高兴——它们对生成的二进制文件或变量实际存在的时间没有影响。
在您的示例中,您向编译器声称其生命周期r_incorrect
比实际长得多,但没有问题,因为您只能在其有效生命周期内访问它。
这样做的危险在于,未来对代码的更改可能会尝试r_incorrect
在其真实生命周期之外使用。编译器无法阻止这种情况的发生,因为您已经坚持认为没关系。
推荐阅读
- java - 检查 Java 对象是否为 Collection、Array 或 String 并且为空
- c# - 将响应与异常一起包装的正确方法
- javascript - 改变时间格式
- kubernetes - 在已安装的版本上运行 helm 测试套件引入延迟
- scripting - 这个脚本怎么知道'currentPlayer'是谁?
- prolog - Prolog 中的实体关系数据模型
- javascript - 使用 D3.js 在生产 React.js 中运行构建项目与项目时的不同结果
- php - 如何遍历json数据并发送到数据库中?
- python - python循环在行中插入值
- react-native - 如何使用 React native Ii18 进行语言更改?