- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直很难理解生命周期,如果能帮助我理解这里的资源和其他问题/答案中通常缺少的一些微妙之处,我将不胜感激。甚至本书的整个部分都具有误导性,因为它的主要示例被用作生命周期背后的基本原理或多或少是错误的(即编译器可以很容易地推断出所提到函数的生命周期)。
以这个函数(有点像书上的)为例:
fn foo<'a>(x: &'a str, y: &'a str) -> &'a str {
x
}
我的理解是显式生命周期断言返回引用的生命周期不应长于x
和y
的最短生命周期。或者换句话说,x
和 y
都应该比返回的引用长寿。 (虽然我完全不确定编译器到底做了什么,但它会检查参数的生命周期,然后将最小值与返回引用的生命周期进行比较吗?)
但是如果我们没有返回值,那么生命周期意味着什么呢?它是否意味着特殊的含义(例如,与使用两个不同的生命周期相比?)
fn foo<'a>(x: &'a str, y: &'a str) {
}
然后我们有如下结构:
struct Foo<'a, 'b> {
x: &'a i32,
y: &'b i32,
}
和
struct Foo<'a> {
x: &'a i32,
y: &'a i32,
}
似乎对字段使用相同的生命周期会增加一些约束,但导致 some examples 的约束到底是什么?不上类?
这可能需要一个自己的问题,但是有很多生命周期和范围的不同提及但没有详细说明,是否有任何资源对此进行更深入的研究,尤其是考虑非词汇生命周期?
最佳答案
要了解生命周期,您必须注意它们实际上是类型的一部分,而不是值的一部分。这就是将它们指定为通用参数的原因。
也就是说,当你写:
fn test(a: &i32) {
let i: i32 = 0;
let b: &i32 = &i;
let c: &'static i32 = &0;
}
然后是变量 a
, b
和 c
实际上是不同的类型:一种是&'__unnamed_1 i32
, 另一个是 &_unnamed_2 i32
另一个是&'static i32
.
有趣的是,生命周期创建了一个类型层次结构,因此当一种类型比另一种类型生命周期更长,但除了它们相同之外,那么长生命周期类型是短生命周期类型的子类型.
特别是,在极端多重继承的情况下,&'static i32
type 是任何其他 &'_ i32
的子类型.
您可以使用此示例检查 Rust 子类型是否真实:
fn test(mut a: &i32) {
let i: i32 = 0;
let mut b: &i32 = &i;
let mut c: &'static i32 = &0;
//c is a subtype of a and b
//a is a subtype of b
a = c; // ok
c = a; // error
b = a; // ok
a = b; // error
}
值得注意的是,生命周期是一个借用检查器的问题。一旦满足并且代码被证明是安全的,生命周期将被删除并且代码生成是盲目完成的,假设所有对内存值的访问都是有效的。这就是为什么即使生命周期是通用参数,foo<'a>()
仅实例化一次。
回到你的例子:
fn foo<'a>(x: &'a str, y: &'a str) -> &'a str {
x
}
你可以用不同生命周期的值调用这个函数,因为编译器会推导出'a
作为两者中较短的一个,所以 &'a str
将是另一个的父类(super class)型:
let s = String::from("hello");
let r = foo(&s, "world");
这等同于(为生命周期注释发明的语法):
let s: &'s str = String::from("hello");
let r: &'s str = foo::<'s>(&s, "world" as &'s str);
关于具有多个生命周期的结构,这通常无关紧要,我通常将所有生命周期声明为相同,特别是如果该类型对我的 crate 是私有(private)的。
但对于公共(public)泛型类型,声明多个生命周期可能很有用,特别是因为用户可能希望制作一些生命周期'static
.
例如:
struct Foo<'a, 'b> {
x: &'a i32,
y: &'b str,
}
struct Bar<'a> {
x: &'a i32,
y: &'a str,
}
Foo
的用户可以将其用作:
let x = 42;
let foo = Foo { x: &x, y: "hello" };
但是Bar
的用户必须分配一个 String
,或者做一些堆栈分配的 str
魔法:
let x = 42;
let y = String::from("hello");
let bar = Bar { x: &x, y: &y };
请注意 Foo
可以像Bar
一样使用但反之则不然。
还有 impl Foo
可能会提供 impl Bar
无法提供的附加功能:
impl<'a> Foo<'a, 'static> {
fn get_static_str(&self) -> &'static str {
self.y
}
}
关于rust - 关于理解生命周期的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68763457/
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我正在尝试将 JSON 发送到我的服务器并作为结果检索 JSON。例如发送用户名和密码并取回 token 和其他内容。 这就是我正在为发送的 HTTP 请求所做的。我现在如何检索同一请求中的内容?
我有以下 xts 矩阵: > options(digits.secs = 6) > set.seed(1234) > xts(1:10, as.POSIXlt(1366039619, tz="EST"
我目前正在开发一个应用程序,当用户到达某个位置时,它会提醒用户。我希望这个应用程序也在后台运行并搜索解决方案。 在 AppStore 中,我发现了一款名为“Sleep Cycle”的应用程序,它可
我想创建一个基于 farbtastic color picker 的颜色选择器。我想要实现的是添加我想要链接到色轮的 RGB slider 。这是我到目前为止所拥有的。 app.controller(
RFC 5545 允许 RDATE 属性具有 PERIOD 数据类型。该数据类型的语义是什么?据我所知,这是未指定的。它会改变事件的持续时间吗?如果时区更改且没有持续时间怎么办? 最佳答案 尽管我
在 CodinGame学习平台,C# 教程中用作示例的问题之一是: The aim of this exercise is to check the presence of a number in a
我听说网上有一本英特尔书,它描述了特定汇编指令所需的 CPU 周期,但我找不到(经过努力)。谁能告诉我如何找到CPU周期? 这是一个例子,在下面的代码中,mov/lock 是 1 个 CPU 周期,x
据我所知,Java GC有次要GC(低成本)和主要GC周期(高成本)。如果对象在本地范围内,则会在 Minor GC 中清理它。如果对象的引用存储在代码中的其他位置,则它会在主 GC 中被清除。 例如
到目前为止,我有一个很好的自旋锁,可以用作 intendend: std::atomic_flag barrier = ATOMIC_FLAG_INIT; inline void lo
晚上好,我将 cycle2 与 prev 和 next 函数一起使用,但我无法将 prev 和 next 函数置于图像下方的中心。我环顾四周,我知道这会很愚蠢,但我就是看不到它。非常令人沮丧。谢谢加里
出于教育目的,我想知道在优化(在不同级别)和编译之后执行函数需要多少 CPU 周期。有没有办法分析代码或可执行文件以获得可重现的答案?我在 64 位 Windows 7 Pro 上使用 Eclipse
我想彻底测量和调整我的 C/C++ 代码,以便在 x86_64 系统上更好地使用缓存。我知道如何使用计数器(我的 Windows 机器上的 QueryPerformanceCounter)来测量时间,
我尝试将一些数据分组到每四周一次的存储桶中,并使用 pd.Grouper(key='created_at', freq='4W')。我希望这些组是这样的,如果我有从 2019-08-26 到 2019
我正在做一个关于随机数的大型学校项目,但我找不到 Math.random() 的句点。我安装了 7.0.800.15 版本,并且正在使用 Windows 10 计算机。我试过用一个简单的程序来确定周期
我正在努力解决我们生产环境中垃圾收集利用率高的问题,我想知道设置一个大的堆大小来保证老年代永远不会被填满是否会阻止触发主要的 GC 周期。 为了实现这一点,我想有一个特定的阈值标记会触发主要的 GC
我想测量在 Python 3 中执行加法运算所需的时钟周期数。 我写了一个程序来计算加法运算的平均值: from timeit import timeit def test(n): for i
我正在寻找一种方法来测量线程上的函数调用所花费的 cpu 周期。 示例伪代码: void HostFunction() { var startTick = CurrentThread.Cur
就 CPU 周期而言,malloc() 的成本是多少?(Vista/OS,最新版本的 gcc,最高优化级别,...) 基本上,我正在实现一个复杂的 DAG 结构(类似于链表)由一些 16B(不太常见)
C/C++ 中的类型转换会导致额外的 CPU 周期吗? 我的理解是,至少在某些情况下应该消耗额外的 CPU 周期。就像从浮点类型转换为整数一样,CPU 需要将浮点结构转换为整数。 float a=2.
我是一名优秀的程序员,十分优秀!