如果我有这两个功能
// implicit
fn foo(x: &i32) {
}
// explicit
fn bar<'a>(x: &'a i32) {
}
Run Code Online (Sandbox Code Playgroud)
何时会foo返回错误并bar成为正确的函数头?我很困惑为什么我会明确地声明一生:
'a读'生命'a'.从技术上讲,每个引用都有一些与之相关的生命周期,但编译器允许您在常见情况下忽略它们.
我明白一生是什么,但明确指定一生的'a 事情对我有什么影响?作为参考,我使用Rust书作为阅读材料
我在我的库的文档示例中修复错误时遇到了困难.我有像我的箱子一样的文件结构bignum
.
|-- Cargo.lock
|-- Cargo.toml
|-- examples
| |-- dat
| | `-- euler_13.dat
| |-- debug.rs
| `-- euler_13.rs
|-- README.md
|-- src
| |-- error.rs
| |-- inits.rs
| `-- lib.rs
Run Code Online (Sandbox Code Playgroud)
在我的示例中,我的标题看起来像
// euler_13.rs
extern crate bignum;
use bignum::inits::Zero;
// ...
Run Code Online (Sandbox Code Playgroud)
这编译并且工作得很好,但是现在当我在我的文档中写一个例子时lib.rs,我似乎无法导入bignum::inits::Zero
//lib.rs
//...
impl BigNum {
//...
/// Constructs a ...
///
/// # Examples
///
/// ```
/// extern crate bignum;
/// use bignum::inits::Zero;
///
/// let a = bignum::BigNum::new(Zero::zero());
/// …Run Code Online (Sandbox Code Playgroud) 我已经阅读了生命周期并了解每个变量绑定都有生命周期。然而,我似乎想不出什么时候你实际上需要使用它们,因为编译器在必要时在推断它们方面做了很多工作。
《Rust》这本书,我读过。我想要一个简单易懂的例子,即使对于像我这样的人来说也是如此!
如果我有一个封装两个成员的结构,并根据另一个更新一个,只要我这样做就可以了:
struct A {
value: i64
}
impl A {
pub fn new() -> Self {
A { value: 0 }
}
pub fn do_something(&mut self, other: &B) {
self.value += other.value;
}
pub fn value(&self) -> i64 {
self.value
}
}
struct B {
pub value: i64
}
struct State {
a: A,
b: B
}
impl State {
pub fn new() -> Self {
State {
a: A::new(),
b: B { value: 1 }
}
}
pub fn …Run Code Online (Sandbox Code Playgroud) 在搜索有关保守impl trait的文档时,我发现了这个例子:
struct A {
x: [(u32, u32); 10]
}
impl A {
fn iter_values<'a>(&'a self) -> impl 'a + Iterator<Item = u32> {
self.x.iter().map(|a| a.0)
}
}
Run Code Online (Sandbox Code Playgroud)
生命周期'a在返回类型中意味着什么?
我知道关于终身受限Box的这个问题,但我认为用例是不同的.如果我理解答案:
特质对象仅对生命周期'a有效
这意味着生活在堆中某处的特征对象将在一生中持续'a.
但在这里,这不是一个特质对象,而是一个生活在堆栈中的具体对象.因此编译器不需要提供有关其生命周期的提示.
我对此缺少什么?
终身省略的第三条规则说
如果有多个输入生命周期参数,但其中之一是
&self或&mut self因为这是一种方法,则生命周期self被分配给所有输出生命周期参数。这使得编写方法更好。
这是描述此功能发生了什么的教程
fn announce_and_return_part(&self, announcement: &str) -> &str
Run Code Online (Sandbox Code Playgroud)
有两个输入生命周期,所以 Rust 应用第一个生命周期省略规则并给出它们
&self和announcement它们自己的生命周期。然后,因为其中一个参数是&self,返回类型获得 的生命周期&self,并且所有生命周期都已被考虑在内。
我们可以证明所有生命周期都没有考虑在内,因为它的生命周期可能与announcement不同&self:
struct ImportantExcerpt<'a> {
part: &'a str,
}
impl<'a> ImportantExcerpt<'a> {
fn announce_and_return_part(&self, announcement: &str) -> &str {
println!("Attention please: {}", announcement);
announcement
}
}
fn main() {
let i = ImportantExcerpt { part: "IAOJSDI" };
let test_string_lifetime;
{
let a = String::from("xyz");
test_string_lifetime = i.announce_and_return_part(a.as_str());
} …Run Code Online (Sandbox Code Playgroud) 我读到这里是
编写了共享引用类型
&type,或者&'a type在您需要指定显式生存期时。
理解&是为了shared reference但不了解Rust语言type和之间有什么区别'a
在另一个位置,我读了这段代码:
#[derive(Debug)]
struct Person<'a> {
name: &'a str,
age: u8
}
fn main() {
let name = "Peter";
let age = 27;
let peter = Person { name, age };
// Pretty print
println!("{:#?}", peter);
}
Run Code Online (Sandbox Code Playgroud)
是什么'a在struct Person<'a> { }手段?我可以struct使用struct Person<'type> { }或构建相同的内容struct Person<T> { }吗?
那是什么意思name: &'a str …
我想我了解生命周期如何与函数参数/输出和结构一起工作,因为这些情况在书中(以及在nomicon 中进一步解释),但我不明白生命周期如何用于类型边界。例如:
trait Min<Elmt> {
fn get_min(&self) -> Elmt;
}
impl<T, Elmt> Min<Elmt> for T
where
&T: IntoIterator<Item = Elmt>,
Elmt: Ord,
{
fn get_min(&self) -> Elmt {
let mut iter = self.into_iter();
match iter.next() {
None => panic!("Empty List"),
Some(x) => iter.fold(x, |acc, y| acc.min(y)),
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我要求类型T满足以下属性:它的任何引用都必须实现IntoIterator<Item = Ord>. 这段代码无法编译,因为 Rust 想要&T有一个生命周期,而我不知道为什么。该where子句应该只确保某些东西是某种类型,这是在编译时完成的。生命周期/引用是如何产生的?确保&T实现类型的T实现IntoIterator与悬空指针或内存泄漏无关。
来自 Rust Discord …
我的理解是,当类型实现的变量Drop超出范围时,将fn drop(&mut self)插入对函数的调用,并将新创建的可变引用传递给超出范围的变量.
但是,如果变量是不可变的,那怎么可能呢?并且可变地借用它是违法的?这是我正在谈论的一个例子:
fn main() {
let x = vec![1, 2, 3];
let y = &mut x;
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下错误:无法将不可变局部变量借用x为可预期的变量.
类似的东西必须在x被丢弃时发生,因为drop期望一个可变的引用.
我正在尝试创建一个特征,其中包括在一些内部数据上返回迭代器的函数,然后可以由不同的结构实现。一个最小的例子如下:
trait WrapperTrait {
type WrapperIterator: Iterator<Item=u32>;
fn iter(&self) -> Self::WrapperIterator;
}
struct Wrapper {
data: Vec<u32>
}
impl WrapperTrait for Wrapper {
type WrapperIterator = ...;
fn iter(&self) -> Self::WrapperIterator {
return self.data.iter().map(|&x| x);
}
}
Run Code Online (Sandbox Code Playgroud)
但是, for 的类型WrapperIterator相当复杂 - 从错误消息(通过类型不匹配创建)我发现它是:
std::iter::Map<std::slice::Iter<'_, u32>, [closure@borrow.rs:45:37: 45:43]>
Run Code Online (Sandbox Code Playgroud)
有没有办法让 Rust 推断出正确的类型WrapperIterator?