【Rust练习】6.所有权

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

1

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

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

1

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

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

2

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

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

3

rust 复制代码
// 不要修改 main 中的代码
fn main() {
    let s1 = String::from("hello, world");
    let s2 = take_ownership(s1);

    println!("{}", s2);
}

// 只能修改下面的代码!
fn take_ownership(s: String) {
    println!("{}", s);
}

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

rust 复制代码
// 不要修改 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

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

    print_str(s);

    println!("{}", s);
}

fn print_str(s: String)  {
    println!("{}",s)
}

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

rust 复制代码
fn main() {
    let s = String::from("hello, world");

    print_str(&s);

    println!("{}", s);
}

fn print_str(s: &String)  {
    println!("{}",s)
}

5

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

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

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

6

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

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

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

7

rust 复制代码
fn main() {
    let s = String::from("hello, ");
    
    // 只修改下面这行代码 !
    let s1 = s;

    s1.push_str("world")
}

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

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

    s1.push_str("world")
}

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

rust 复制代码
fn main() {
    let mut s = String::from("hello, ");

    // 只修改下面这行代码 !
    let s1 = &mut s;

    s1.push_str("world")
}

8

rust 复制代码
fn main() {
   let t = (String::from("hello"), String::from("world"));

   let _s = t.0;

   // 仅修改下面这行代码,且不要使用 `_s`
   println!("{:?}", t);
}

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

rust 复制代码
fn main() {
    let t = (String::from("hello"), String::from("world"));

    let _s = t.0;

    // 仅修改下面这行代码,且不要使用 `_s`
    println!("{}", t.1);
}

9

rust 复制代码
fn main() {
   let t = (String::from("hello"), String::from("world"));

   // 填空,不要修改其它代码
   let (__, __) = __;

   println!("{:?}, {:?}, {:?}", s1, s2, t); // -> "hello", "world", ("hello", "world")
}

同上,改为引用即可:

rust 复制代码
fn main() {
    let t = (String::from("hello"), String::from("world"));
 
    // 填空,不要修改其它代码
    let (s1, s2) = &t;
 
    println!("{:?}, {:?}, {:?}", s1, s2, t); // -> "hello", "world", ("hello", "world")
 }
相关推荐
小陈工2 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
H Journey2 小时前
C++之 CMake、CMakeLists.txt、Makefile
开发语言·c++·makefile·cmake
大鸡腿同学6 小时前
【成长类】《只有偏执狂才能生存》读书笔记:程序员的偏执型成长地图
后端
0xDevNull6 小时前
MySQL数据冷热分离详解
后端·mysql
AI袋鼠帝6 小时前
OpenClaw(龙虾)最强开源对手!Github 40K Star了,又一个爆火的Agent..
后端
lly2024066 小时前
C 标准库 - `<stdio.h>`
开发语言
沫璃染墨6 小时前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
jwn9996 小时前
Laravel6.x核心特性全解析
开发语言·php·laravel
迷藏4946 小时前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
功德+n7 小时前
Linux下安装与配置Docker完整详细步骤
linux·运维·服务器·开发语言·docker·centos