hint: Remember that the generic lifetime ‘a will get the concrete lifetime that is equal to the smaller of the lifetimes of x and y. You can take at least two paths to achieve the desired result while keeping the inner block:
Move the string2 declaration to make it live as long as string1 (how is result declared?)
Move println! into the inner block
lifetimes3
结构体中生命周期标注:
对结构体本身类似泛型:<'a>
对结构体成员:&'a
结构体成员引用的生命周期要大于等于结构体
lifetime others
输入生命周期 & 输出生命周期
生命周期的消除
方法中的生命周期(类似泛型参数语法)
impl中必须使用结构体的完整名称,包括<'a>,因为生命周期标注也是结构体类型的一部分!
方法签名中,往往不需要标注生命周期,得益于生命周期消除的第一和第三规则
静态生命周期
tests4
#[should_panic]:The test passes if the code inside the function panics; the test fails if the code inside the function doesn’t panic. <!– * tests5(自动进行时这个被跳过了,直接到了迭代器)
into_iter() takes ownership of the values and consumes the actual type once iterated completely. The original collection can no longer be accessed.
collect()会根据函数返回值自动调整格式
iterators4
这不让用那不让用,那自然是得用自带的工具咯
(1..=num).product()
iterators5
一点思考:
1 2 3 4 5 6 7 8 9 10 11
fncount_for(map: &HashMap<String, Progress>, value: Progress) -> usize { letmut count = 0; for val in map.values() { // 此处为什么不是*val == value呢? // 下面这中方式中,实际上是在比较两者对应的实体是否相同 if val == &value { count += 1; } } count }
扁平化(Flatten)
1 2 3 4 5 6
fncount_collection_iterator(collection: &[HashMap<String, Progress>], value: Progress) -> usize { collection.iter() // Iterate over the slice of hashmaps .flat_map(|map| map.values()) // Flatten the values of each hashmap into a single iterator .filter(|val| **val == value) // Filter values equal to the target value .count() // Count the filtered values }
| 29 | fn send_tx(q: Queue, tx: mpsc::Sender<u32>) -> () { | -- move occurs because `tx` has type `Sender<u32>`, which does not implement the `Copy` trait ... 34 | thread::spawn(move || { | ------- value moved into closure here ... 37 | tx.send(*val).unwrap(); | -- variable moved due to use in closure ... 42 | thread::spawn(move || { | ^^^^^^^ value used here after move ... 45 | tx.send(*val).unwrap(); | -- use occurs due to use in closure error: aborting due to 1 previous error
分析:tx变量move到第一个闭包后,已经无法在该闭包外获取了,而在第二次进程创建仍然尝试move。通过为每个变量创建tx的clone,我们确保了每个闭包都拥有其独立的sender,从而避免了use after move错误
--> exercises/conversions/using_as.rs:17:11 | 17 | total / values.len() | ^ no implementation for `f64 / usize` | = help: the trait `Div<usize>` is not implemented for `f64` = help: the following other types implement trait `Div<Rhs>`: <&'a f64 as Div<f64>> <&f64 as Div<&f64>> <f64 as Div<&f64>> <f64 as Div>
分析:错误提示指出 f64 类型没有实现 Div<usize> trait,因此无法执行除法操作。为了解决这个问题,我们可以将 values.len() 转换为 f64 类型,以便进行除法运算。 在修改后的代码中,我们使用 values.len() as f64 将 values.len() 的结果转换为 f64 类型,以便与 total 执行除法操作。
from_into
为Person结构实现From<&str> trait
from_str
需要实现FromStr trait 来将字符串解析为 Person 结构体,并返回相应的错误类型 ParsePersonError
/// # Safety /// /// The `address` must be a valid memory address that points to a mutable `u32` value. /// /// It is the caller's responsibility to ensure that the `address` is a valid memory address /// and that it points to a mutable `u32` value. Failing to meet these requirements may lead /// to undefined behavior, such as memory corruption or crashes. unsafefnmodify_by_address(address: usize) { // SAFETY: The caller must ensure that `address` is a valid memory address // and that it points to a mutable `u32` value. let value_ptr = address as *mutu32; let value = &mut *value_ptr; *value = 0xAABBCCDD; }