lifetime/basic #180
Replies: 19 comments 9 replies
|
第10题的longest函数中参数y的生命周期是可以消除的吧 |
4 replies
第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() {} |
0 replies
|
第八题这样为什么也能过编译?虽然与答案不同,如果这样可以的话应该可以应用生命周期消除。。然而不标注生命周期的话无法过编译 /* 修复函数的签名 */
fn fix_me<'a>(foo: &'a Example) -> &'a NoCopyType {
foo.b
} |
4 replies
|
done. |
0 replies
|
第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!")
} |
0 replies
|
答案链接 |
0 replies
|
第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!")
} |
0 replies
|
第四题,可以简写,为了练习没有简写。应该是对的吧 /* 使用三种方法修复下面的错误 */
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() {
} |
0 replies
|
lala |
0 replies
|
done |
0 replies
|
第4题的另一种解法 #![feature(string_leak)]
fn invalid_output() ->&'static str {
String::from("foo").leak()
} |
1 reply
|
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() {} |
0 replies
/* 使用三种方法修复下面的错误 */
fn invalid_output<'a>() -> &'a str {
"foo"
}
fn main() {
}上面能够通过编译,是因为"foo": &str具有'static |
0 replies
|
done~~~ |
0 replies
|
有的题就和脑筋急转弯一样,不看答案是真难想啊 |
0 replies
|
第三题 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() {} |
0 replies
|
done |
0 replies
|
done |
0 replies
|
done. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
lifetime/basic
Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team
https://practice.rs/lifetime/basic.html
All reactions