lifetime/basic #180
Replies: 16 comments 7 replies
-
第10题的longest函数中参数y的生命周期是可以消除的吧 |
Beta Was this translation helpful? Give feedback.
-
第1题/* 为 `i` 和 `borrow2` 标注合适的生命周期范围 */
// `i` 拥有最长的生命周期,因为它的作用域完整的包含了 `borrow1` 和 `borrow2` 。
// 而 `borrow1` 和 `borrow2` 的生命周期并无关联,因为它们的作用域没有重叠
fn main() {
let i = 3; // `i`生命周期开始 ─────────────────────────────┐
{ │
let borrow1 = &i; // `borrow1` 生命周期开始. ─────┐ │
// │ │
println!("borrow1: {}", borrow1); // │ │
} // `borrow1` 生命周期结束. ─────────────────────────┘ │
{ │
let borrow2 = &i; // `borrow2`生命周期开始 ───┐ │
│ │
println!("borrow2: {}", borrow2); │ │
} // `borrow2`生命周期结束─┘ │
} // `i`生命周期结束 ────────────────────────────────────────┘ 第2题/* 像上面的示例一样,为 `r` 和 `x` 标准生命周期,然后从生命周期的角度. */
fn main() {
{
let r; // ---------+-- 'a
// |
{ // |
let x = 5; // -+-- 'b |
r = &x; // | |
} // -+ |
// |
println!("r: {}", r); // |
} // ---------+
} // 引用的生命周期'a比被引用对象的生命周期'b长,因此编译错误。 第3题/* 添加合适的生命周期标注,让下面的代码工作 */
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {} 第4题4.1 方法1/* 使用三种方法修复下面的错误 */
fn invalid_output() -> String {
String::from("foo")
}
fn main() {
} 4.2 方法2/* 使用三种方法修复下面的错误 */
fn invalid_output() -> &'static str {
"foo"
}
fn main() {
} 4.3 方法3/* 使用三种方法修复下面的错误 */
fn invalid_output<'a>() -> &'a str {
"foo"
}
fn main() {
} 第5题// `print_refs` 有两个引用参数,它们的生命周期 `'a` 和 `'b` 至少得跟函数活得一样久
fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {
println!("x is {} and y is {}", x, y);
}
/* 让下面的代码工作 */
fn failed_borrow() {
let _x = 12;
// ERROR: `_x` 活得不够久does not live long enough
let y: &i32 = &_x;
// 在函数内使用 `'a` 将会报错,原因是 `&_x` 的生命周期显然比 `'a` 要小
// 你不能将一个小的生命周期强转成大的
}
fn main() {
let (four, nine) = (4, 9);
print_refs(&four, &nine);
// 这里,four 和 nice 的生命周期必须要比函数 print_refs 长
failed_borrow();
// `failed_borrow` 没有传入任何引用去限制生命周期 `'a`,因此,此时的 `'a` 生命周期是没有任何限制的,它默认是 `'static`
} 第6题/* 增加合适的生命周期标准,让代码工作 */
// `i32` 的引用必须比 `Borrowed` 活得更久
#[derive(Debug)]
struct Borrowed<'a>(&'a i32);
// 类似的,下面两个引用也必须比结构体 `NamedBorrowed` 活得更久
#[derive(Debug)]
struct NamedBorrowed<'a> {
x: &'a i32,
y: &'a i32,
}
#[derive(Debug)]
enum Either<'a> {
Num(i32),
Ref(&'a i32),
}
fn main() {
let x = 18;
let y = 15;
let single = Borrowed(&x);
let double = NamedBorrowed { x: &x, y: &y };
let reference = Either::Ref(&x);
let number = Either::Num(y);
println!("x is borrowed in {:?}", single);
println!("x and y are borrowed in {:?}", double);
println!("x is borrowed in {:?}", reference);
println!("y is *not* borrowed in {:?}", number);
} 第7题/* 让代码工作 */
#[derive(Debug)]
struct NoCopyType {}
#[derive(Debug)]
struct Example<'a, 'b> {
a: &'a u32,
b: &'b NoCopyType
}
fn main()
{
let var_a = 35;
let example: Example;
let var_b = NoCopyType {};
/* 修复错误 */
example = Example { a: &var_a, b: &var_b };
println!("(Success!) {:?}", example);
} 第8题#[derive(Debug)]
struct NoCopyType {}
#[derive(Debug)]
#[allow(dead_code)]
struct Example<'a, 'b> {
a: &'a u32,
b: &'b NoCopyType
}
/* 修复函数的签名 */
fn fix_me<'a: 'b, 'b>(foo: &'a Example) -> &'b NoCopyType
{ foo.b }
fn main()
{
let no_copy = NoCopyType {};
let example = Example { a: &1, b: &no_copy };
fix_me(&example);
println!("Success!")
} 第9题/* 添加合适的生命周期让下面代码工作 */
struct ImportantExcerpt<'a> {
part: &'a str,
}
impl<'a> ImportantExcerpt<'a> {
fn level(&'a self) -> i32 {
3
}
}
fn main() {} 第10题/* 移除所有可以消除的生命周期标注 */
fn nput(x: &i32) {
println!("`annotated_input`: {}", x);
}
fn pass(x: &i32) -> &i32 { x }
fn longest<'a>(x: &'a str, y: &str) -> &'a str {
x
}
struct Owner(i32);
impl Owner {
fn add_one(&mut self) { self.0 += 1; }
fn print(&self) {
println!("`print`: {}", self.0);
}
}
struct Person<'a> {
age: u8,
name: &'a str,
}
enum Either<'a> {
Num(i32),
Ref(&'a i32),
}
fn main() {} |
Beta Was this translation helpful? Give feedback.
-
第八题这样为什么也能过编译?虽然与答案不同,如果这样可以的话应该可以应用生命周期消除。。然而不标注生命周期的话无法过编译 /* 修复函数的签名 */
fn fix_me<'a>(foo: &'a Example) -> &'a NoCopyType {
foo.b
} |
Beta Was this translation helpful? Give feedback.
-
第8题我是这样写的,通过了: #[derive(Debug)]
struct NoCopyType {}
#[derive(Debug)]
#[allow(dead_code)]
struct Example<'a, 'b> {
a: &'a u32,
b: &'b NoCopyType
}
/* 修复函数的签名 */
fn fix_me<'a, 'b>(foo: &Example<'a, 'b>) -> &'b NoCopyType
{ foo.b }
fn main()
{
let no_copy = NoCopyType {};
let example = Example { a: &1, b: &no_copy };
fix_me(&example);
println!("Success!")
} |
Beta Was this translation helpful? Give feedback.
-
答案链接 |
Beta Was this translation helpful? Give feedback.
-
第8题这样改也不错的: #[derive(Debug)]
struct NoCopyType {
}
#[derive(Debug)]
#[allow(dead_code)]
struct Example<'a, 'b> {
a: &'a u32,
b: &'b NoCopyType
}
/* 修复函数的签名 */
fn fix_me<'b>(foo: &Example<'_, 'b>) -> &'b NoCopyType {
foo.b
}
fn main()
{
let no_copy = NoCopyType {};
let example = Example { a: &1, b: &no_copy };
fix_me(&example);
println!("Success!")
} |
Beta Was this translation helpful? Give feedback.
-
第四题,可以简写,为了练习没有简写。应该是对的吧 /* 使用三种方法修复下面的错误 */
fn invalid_output1<'a>() -> String {
String::from("foo")
}
fn invalid_output2<'a>(s: &'a str) -> &'a str {
s
}
fn invalid_output3<'a>() -> &'static str {
"foo"
}
fn main() {
} |
Beta Was this translation helpful? Give feedback.
-
第4题的另一种解法 #![feature(string_leak)]
fn invalid_output() ->&'static str {
String::from("foo").leak()
} |
Beta Was this translation helpful? Give feedback.
-
1、讲真,我本来以为标注是在代码中插入 fn main() {
let i = 3; // Lifetime for `i` starts. ────────────────┐
// │
{ // │
let borrow1 = &i; // `borrow1` lifetime starts. ──┐│
// ││
println!("borrow1: {}", borrow1); // ││
} // `borrow1 ends. ──────────────────────────────────┘│
// │
// │
{ // │
let borrow2 = &i; // `borrow2` lifetime starts. ──┐│
// ││
println!("borrow2: {}", borrow2); // ││
} // `borrow2` ends. ─────────────────────────────────┘│
// │
} // Lifetime ends. ─────────────────────────────────────┘ 发现是示例没好好看……2333 2、略 3、生命周期使用: /* 添加合适的生命周期标注,让下面的代码工作 */
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {} 4、 第一种,不要考虑生命周期 /* 使用三种方法修复下面的错误 */
fn invalid_output() -> String {
String::from("foo")
}
fn main() {
} 第二种,引入入参 /* 使用三种方法修复下面的错误 */
fn invalid_output<'a>(input:&'a mut String) -> &'a String {
(*input)=String::from("foo");
input
}
fn main() {
} 第三种,考虑使用 fn invalid_output() -> &'static str {
"foo"
}
fn main() {
} 5、函数内使用``a // `print_refs` 有两个引用参数,它们的生命周期 `'a` 和 `'b` 至少得跟函数活得一样久
fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {
println!("x is {} and y is {}", x, y);
}
/* 让下面的代码工作 */
fn failed_borrow<'a>() {
let _x = 12;
// ERROR: `_x` 活得不够久does not live long enough
let y = &_x;//删除就好
// 在函数内使用 `'a` 将会报错,原因是 `&_x` 的生命周期显然比 `'a` 要小
// 你不能将一个小的生命周期强转成大的
}
fn main() {
let (four, nine) = (4, 9);
print_refs(&four, &nine);
// 这里,four 和 nice 的生命周期必须要比函数 print_refs 长
failed_borrow();
// `failed_borrow` 没有传入任何引用去限制生命周期 `'a`,因此,此时的 `'a` 生命周期是没有任何限制的,它默认是 `'static`
} 6、结构体中的引用 /* 增加合适的生命周期标准,让代码工作 */
// `i32` 的引用必须比 `Borrowed` 活得更久
#[derive(Debug)]
struct Borrowed<'a>(&'a i32);
// 类似的,下面两个引用也必须比结构体 `NamedBorrowed` 活得更久
#[derive(Debug)]
struct NamedBorrowed<'a>{
x: &'a i32,
y: &'a i32,
}
#[derive(Debug)]
enum Either<'a> {
Num(i32),
Ref(&'a i32),
}
fn main() {
let x = 18;
let y = 15;
let single = Borrowed(&x);
let double = NamedBorrowed { x: &x, y: &y };
let reference = Either::Ref(&x);
let number = Either::Num(y);
println!("x is borrowed in {:?}", single);
println!("x and y are borrowed in {:?}", double);
println!("x is borrowed in {:?}", reference);
println!("y is *not* borrowed in {:?}", number);
} 7、结构体的引用需要比结构体活得更久或者等同 /* 让代码工作 */
#[derive(Debug)]
struct NoCopyType {}
#[derive(Debug)]
struct Example<'a, 'b> {
a: &'a u32,
b: &'b NoCopyType
}
fn main()
{
let var_a = 35;
let example: Example;
{
let var_b = NoCopyType {};
/* 修复错误 */
example = Example { a: &var_a, b: &var_b };
println!("(Success!) {:?}", example);
}
//不可以在外面 println!("(Success!) {:?}", example);因为结构体引用的var_b在上一个}被消除了
} 8、 #[derive(Debug)]
struct NoCopyType {}
#[derive(Debug)]
#[allow(dead_code)]
struct Example<'a, 'b> {
a: &'a u32,
b: &'b NoCopyType
}
/* 修复函数的签名 */
fn fix_me<'a>(foo: &'a Example) -> &'a NoCopyType
{ foo.b }
fn main()
{
let no_copy = NoCopyType {};
let example = Example { a: &1, b: &no_copy };
fix_me(&example);
println!("Success!")
} 9、带引用的结构体实现方法的写法 /* 添加合适的生命周期让下面代码工作 */
struct ImportantExcerpt<'a> {
part: &'a str,
}
impl <'a>ImportantExcerpt<'a> {
fn level(&self) -> i32 {
3
}
}
fn main() {} 10、 /* 移除所有可以消除的生命周期标注 */
fn nput(x: & i32) {
println!("`annotated_input`: {}", x);
}
fn pass(x: & i32) -> &i32 { x }
fn longest<'a,'b>(x: &'a str, y: &'b str) -> &'a str {
x
}
struct Owner(i32);
impl Owner {
fn add_one(& mut self) { self.0 += 1; }
fn print(& self) {
println!("`print`: {}", self.0);
}
}
struct Person<'a> {
age: u8,
name: &'a str,
}
enum Either<'a> {
Num(i32),
Ref(&'a i32),
}
fn main() {} |
Beta Was this translation helpful? Give feedback.
-
/* 使用三种方法修复下面的错误 */
fn invalid_output<'a>() -> &'a str {
"foo"
}
fn main() {
} 上面能够通过编译,是因为"foo": &str具有'static |
Beta Was this translation helpful? Give feedback.
-
有的题就和脑筋急转弯一样,不看答案是真难想啊 |
Beta Was this translation helpful? Give feedback.
-
第三题 fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
} 第四题 fn invalid_output1() -> String {
String::from("foo")
}
fn invalid_output2() -> &'static str {
"foo"
}
fn invalid_output3<'a>(s: &'a mut String) -> &'a String {
*s = String::from("foo");
s
} 第五题 fn failed_borrow() {
let _x = 12;
let y: &i32 = &_x;
} 第六题 /* 增加合适的生命周期标准,让代码工作 */
// `i32` 的引用必须比 `Borrowed` 活得更久
#[derive(Debug)]
struct Borrowed<'a>(&'a i32);
// 类似的,下面两个引用也必须比结构体 `NamedBorrowed` 活得更久
#[derive(Debug)]
struct NamedBorrowed<'a> {
x: &'a i32,
y: &'a i32,
}
#[derive(Debug)]
enum Either<'a> {
Num(i32),
Ref(&'a i32),
}
fn main() {
let x = 18;
let y = 15;
let single = Borrowed(&x);
let double = NamedBorrowed { x: &x, y: &y };
let reference = Either::Ref(&x);
let number = Either::Num(y);
println!("x is borrowed in {:?}", single);
println!("x and y are borrowed in {:?}", double);
println!("x is borrowed in {:?}", reference);
println!("y is *not* borrowed in {:?}", number);
} 第七题 /* 让代码工作 */
#[derive(Debug)]
struct NoCopyType {}
#[derive(Debug)]
struct Example<'a, 'b> {
a: &'a u32,
b: &'b NoCopyType
}
fn main()
{
let var_a = 35;
let example: Example;
{
let var_b = NoCopyType {};
/* 修复错误 */
example = Example { a: &var_a, b: &var_b };
println!("(Success!) {:?}", example);
}
} 第八题 fn fix_me<'a>(foo: &'a Example) -> &'a NoCopyType 第九题 /* 添加合适的生命周期让下面代码工作 */
struct ImportantExcerpt<'a> {
part: &'a str,
}
impl <'a>ImportantExcerpt<'a> {
fn level(&'a self) -> i32 {
3
}
}
fn main() {} 第10题 /* 移除所有可以消除的生命周期标注 */
fn nput(x: &i32) {
println!("`annotated_input`: {}", x);
}
fn pass(x: &i32) -> &i32 { x }
fn longest<'a, 'b>(x: &'a str, y: &str) -> &'a str {
x
}
struct Owner(i32);
impl Owner {
fn add_one(&mut self) { self.0 += 1; }
fn print(&self) {
println!("`print`: {}", self.0);
}
}
struct Person<'a> {
age: u8,
name: &'a str,
}
enum Either<'a> {
Num(i32),
Ref(&'a i32),
}
fn main() {} |
Beta Was this translation helpful? Give feedback.
-
lifetime/basic
Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team
https://practice.rs/lifetime/basic.html
Beta Was this translation helpful? Give feedback.
All reactions