【Rust练习】6.所有权
创始人
2024-11-12 11:07:24

练习题来自:https://practice-zh.course.rs/ownership/ownership.html

1

fn main() {     // 使用尽可能多的方法来通过编译     let x = String::from("hello, world");     let y = x;     println!("{},{}",x,y); } 

这是最典型的所有权转移的错误,x拥有字符串的所有权,然后转给了y,此时x不再拥有所有权了。以下给出两种方法:

1

可以对字符串执行一次克隆clone:

fn main() {     // 使用尽可能多的方法来通过编译     let x = String::from("hello, world");     let y = x.clone();     println!("{},{}",x,y); } 

2

让x作为引用,而不是所有者,但是就不能用string了,得用str:

fn main() {     // 使用尽可能多的方法来通过编译     let x: &str = "hello, world";     let y = x;     println!("{},{}",x,y); } 

3

// 不要修改 main 中的代码 fn main() {     let s1 = String::from("hello, world");     let s2 = take_ownership(s1);      println!("{}", s2); }  // 只能修改下面的代码! fn take_ownership(s: String) {     println!("{}", s); } 

一个很简单的所有权转移:

// 不要修改 main 中的代码 fn main() {     let s1 = String::from("hello, world");     let s2 = take_ownership(s1);      println!("{}", s2); }  // 只能修改下面的代码! fn take_ownership(s: String) -> String {     println!("{}", s);     return s; } 

4

// 修复错误,不要删除任何代码行 fn main() {     let s = String::from("hello, world");      print_str(s);      println!("{}", s); }  fn print_str(s: String)  {     println!("{}",s) } 

s的所有权在print_str中转移了,函数结束后就丢失了,因此此处改为借用即可:

fn main() {     let s = String::from("hello, world");      print_str(&s);      println!("{}", s); }  fn print_str(s: &String)  {     println!("{}",s) } 

5

// 不要使用 clone,使用 copy 的方式替代 fn main() {     let x = (1, 2, (), "hello".to_string());     let y = x.clone();     println!("{:?}, {:?}", x, y); } 

唯一问题在于string不是基本类型,因此去掉to_string即可,改为&str

fn main() {     let x = (1, 2, (), "hello");     let y = x;     println!("{:?}, {:?}", x, y); } 

6

 fn main() {     let x = Box::new(5);          let ...      // 完成该行代码,不要修改其它行!          *y = 4;          assert_eq!(*x, 5); } 

不知道这个Box类存在的意义是什么(我也懒得去查),这题的目的明显是想让y成为一个针对数字类型的可变引用,这么改就行:

fn main() {     let x = Box::new(5);          let y = &mut 5;      // 完成该行代码,不要修改其它行!          *y = 4;          assert_eq!(*x, 5); } 

7

fn main() {     let s = String::from("hello, ");          // 只修改下面这行代码 !     let s1 = s;      s1.push_str("world") } 

第一种方法就是克隆一份s变量:

fn main() {     let s = String::from("hello, ");          // 只修改下面这行代码 !     let mut s1 = s.clone();      s1.push_str("world") } 

第二种直接修改s,但要修改s为可变变量,不如第一种破坏小(但没准更接近作者本意):

fn main() {     let mut s = String::from("hello, ");      // 只修改下面这行代码 !     let s1 = &mut s;      s1.push_str("world") } 

8

fn main() {    let t = (String::from("hello"), String::from("world"));     let _s = t.0;     // 仅修改下面这行代码,且不要使用 `_s`    println!("{:?}", t); } 

t的第一部分的所有权转移给了_s,但是第二部分还是没有转移的,所以可以修改如下:

fn main() {     let t = (String::from("hello"), String::from("world"));      let _s = t.0;      // 仅修改下面这行代码,且不要使用 `_s`     println!("{}", t.1); } 

9

fn main() {    let t = (String::from("hello"), String::from("world"));     // 填空,不要修改其它代码    let (__, __) = __;     println!("{:?}, {:?}, {:?}", s1, s2, t); // -> "hello", "world", ("hello", "world") } 

同上,改为引用即可:

fn main() {     let t = (String::from("hello"), String::from("world"));       // 填空,不要修改其它代码     let (s1, s2) = &t;       println!("{:?}, {:?}, {:?}", s1, s2, t); // -> "hello", "world", ("hello", "world")  } 

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...