Replies: 95 comments 114 replies
-
这章的爬坡陡度太高了,可能是基础知识还是没掌握 |
Beta Was this translation helpful? Give feedback.
-
后面会对生命周期两个章节进行下大幅优化,目前确实存在一些问题 |
Beta Was this translation helpful? Give feedback.
-
最后的这个例子中的错误实在是...太反直觉了。 |
Beta Was this translation helpful? Give feedback.
-
&*self 是为什么, 不能是&self呢 |
Beta Was this translation helpful? Give feedback.
-
看前:我是新手,就是想头铁 0 0 |
Beta Was this translation helpful? Give feedback.
-
建议加入Variance相关的知识点,目前的内容貌似没有cover这块难点 |
Beta Was this translation helpful? Give feedback.
-
&self &Self &*self self 啥区别啊,越看越蒙😒 |
Beta Was this translation helpful? Give feedback.
-
无语感觉自己在看天书了。。。太玄幻了 |
Beta Was this translation helpful? Give feedback.
-
写的很通俗易懂!飞哥🐂🍺 |
Beta Was this translation helpful? Give feedback.
-
大佬,针对例2的情况怎么解决那? |
Beta Was this translation helpful? Give feedback.
-
关于再借用
这是可以运行的。 我理解是: 理解的对吗? |
Beta Was this translation helpful? Give feedback.
-
rustc 1.61.0 第一个例子可以了 |
Beta Was this translation helpful? Give feedback.
-
都说学rust是陡坡,感觉形容悬崖更合适。 |
Beta Was this translation helpful? Give feedback.
-
真复杂。好难懂。 |
Beta Was this translation helpful? Give feedback.
-
关于闭包,强行标注生命周期也是可以通过编译的,就是费劲,还是普通函数好。 let closure_slision: &dyn for<'x> Fn(&'x i32) -> &'x i32 = &|x: &i32| -> &i32 { x }; |
Beta Was this translation helpful? Give feedback.
-
fn main() {
} fn fun<'a>(x: &'a i32) -> impl Fn(&'a i32) -> &'a i32 { fn fun2<T, F: Fn(&T) -> &T>(f: F) -> F { |
Beta Was this translation helpful? Give feedback.
-
fn main() {
let closure: &dyn Fn(&i32) -> &i32 = &|x| { x };
println!("{}", closure(&114))
} 根据编译器的提示一步步改的,没想到最后过了 |
Beta Was this translation helpful? Give feedback.
-
What I need is another C, not another C++language |
Beta Was this translation helpful? Give feedback.
-
use std::vec::Vec; |
Beta Was this translation helpful? Give feedback.
-
rust最大的难点就是生命周期设计了。哎,学习起来好吃力! |
Beta Was this translation helpful? Give feedback.
-
'a:'b,表示 'a 至少要活得跟 'b 一样久。 |
Beta Was this translation helpful? Give feedback.
-
最后一个例子可以理解为:通过新建一个生命周期,传递给借用对象,缩短再借用的时间。 |
Beta Was this translation helpful? Give feedback.
-
#[derive(Debug)]
struct Foo;
impl Foo {
fn mutate_and_share(&mut self) -> &Self {
&*self
}
fn share(&self) {}
}
fn main() {
let mut foo = Foo;
let loan = foo.mutate_and_share();
loan.share();
println!("{:?}", loan);
} |
Beta Was this translation helpful? Give feedback.
-
【2024-09-21 19:21:53】附上一个实战中碰到、同样诡异的例子: struct S {
a: String,
}
impl S {
fn get_non_empty_a(&self) -> Option<&str> {
if self.a.is_empty() {
None
} else {
Some(&self.a)
}
}
fn get_a_or_inset_new(&mut self, input_s: &str) -> Option<&str> {
// ↓这里借用了&self,&mut self生命周期结束
let may_empty_a = self.get_non_empty_a();
if let Some(a) = may_empty_a {
Some(a)
} else {
// 但这里又要借用&mut self
self.a = input_s.to_string(); // ! 报错:cannot assign to `self.a` because it is borrowed
Some(&self.a)
}
}
} 完整编译器报错参考:
|
Beta Was this translation helpful? Give feedback.
-
针对最后一个例子,给出自己的一些想法: |
Beta Was this translation helpful? Give feedback.
-
针对最后一个例子,给出自己的一点想法: // (8) 一个复杂的例子
{
#[allow(dead_code)]
struct Interface<'b, 'a: 'b> {
manager: &'b mut Manager<'a>,
}
#[allow(dead_code)]
impl<'b, 'a: 'b> Interface<'b, 'a> {
pub fn noop(self) {
println!("interface consumed");
}
}
#[allow(dead_code)]
struct Manager<'a> {
text: &'a str,
}
#[allow(dead_code)]
struct List<'a> {
manager: Manager<'a>,
}
#[allow(dead_code)]
impl<'a> List<'a> {
// 我们给予了一个额外的生命周期参数 'b
// 这个'b 给予了 Interface 中的 manager, 'a 给了 Interface 中 manager 的text
// 所以此时 Interface 对 manager 的可变借用跟list不挂钩了, 之前是挂钩的, 因为用的都是 'a
pub fn get_interface<'b>(&'b mut self) -> Interface<'b, 'a>
where
'a: 'b,
{
Interface {
manager: &mut self.manager,
}
}
}
#[allow(dead_code)]
fn xx() {
let mut list = List {
manager: Manager { text: "hello" },
};
list.get_interface().noop();
println!("Interface should be dropped here and the borrow released");
// 下面的调用可以通过,因为Interface的生命周期不需要跟list一样长
use_list(&list);
}
// 因为 use_list 对 List 进行了不可变借用, 并且使用到其内部的 manager
// 必须保证 manager 此时是不存在可变借用的
// 如果按照原来的 'a , 那么此时 Interface 中的 manager 还是持有跟list一样长的可变借用, 这违反了借用法则
// 所以给予了 'b 之后, Interface 中的 manager 没有持有这么长的可变借用了, 此时可以用
fn use_list(list: &List) {
println!("{}", list.manager.text);
}
} |
Beta Was this translation helpful? Give feedback.
-
struct ImportantExcerpt<'a> { impl<'a: 'b, 'b> ImportantExcerpt<'a> { |
Beta Was this translation helpful? Give feedback.
-
写的很好,就是个人觉得可能有时候对生命周期进行下命名也是很好的,比如最后一个例子中如果用 稍微魔改了一下最后一个例子 struct Manager<'m> {
text: &'m str
}
struct Interface<'i, 'm: 'i> {
manager: &'i mut Manager<'m>
}
impl<'i, 'm> Interface<'i, 'm> {
pub fn rewrite<'s>(&'i mut self, text: &'s str)
where 's: 'm
{
self.manager.text = text;
}
}
struct ManagerList<'m> {
manager_list: Vec<Manager<'m>>
}
impl<'m> ManagerList<'m> {
// 重点是这里的 self: &'i mut Self 的生命周期要和返回值 Interface 一样。
// 如果还是 `&'m mut self` 的话仍然不能通过编译。
//
// 以及,在当前例子中,下面的`where 'm: 'i`和Interface声明中的`'m: 'i`不
// 是必须的,因为结构体和其中的元素生命周期可以不一样。只不过删去
// 后的二者的关系就和我们设想的有所出入了。
pub fn get_interface<'i>(&'i mut self, index: usize) -> Interface<'i, 'm>
where 'm: 'i
{
if index >= self.manager_list.len() {
panic!("index out of bounds");
}
Interface {
manager: &mut self.manager_list[index]
}
}
}
fn print_list(list: &ManagerList) {
for i in 0..list.manager_list.len() {
println!("{}", list.manager_list[i].text)
}
}
fn main() {
let mut list = ManagerList {
manager_list: vec![Manager { text: "hello" }]
};
print_list(&list);
list.get_interface(0).rewrite("world");
println!("Interface should be dropped here and the borrow released");
print_list(&list);
} |
Beta Was this translation helpful? Give feedback.
-
https://course.rs/advance/lifetime/advance.html
Beta Was this translation helpful? Give feedback.
All reactions