Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

method #193

giscus[bot] bot announced in Book Comments
Apr 1, 2022 · 38 comments · 20 replies
Discussion options

method

Learning Rust By Practice, narrowing the gap between beginner and skilled-dev with challenging examples, exercises and projects.

https://zh.practice.rs/method.html

You must be logged in to vote

Replies: 38 comments 20 replies

Comment options

请教一下,第5题里面,为什么如下写法也可以编译通过并执行成功呢?

fn main() {
 let light = TrafficLight::new();
 assert_eq!(light.get_state(), "red");
}
You must be logged in to vote
7 replies
Comment options

为什么不行呢😂

Comment options

因为assert_eq!调用的是类型的PartialEq特征,而String有实现对str&str类型的PartialEq特征。

Comment options

回复 @religou:我猜没加解引用符的self是被"自动引用和解引用"了(如果我说的不对还请大佬们指正)

Comment options

@tn233 正确的,rust具有自动引用和解引用的功能

Comment options

这里的自动引用和解引用有条件限制,比如该事例加上*****就不会编译通过:

#![allow(unused)]
enum Message {
 Quit,
 Move{x:i32, y: i32},
 Write(String),
 ChangeColor(i32, i32, i32),
}
impl Message {
 fn call(&self) {
 match *self {
 Message::Write(message) => print!("{}", message),
 _ =>()
 }
 }
}
fn main() {
 let m = Message::Write(String::from("test"));
 m.call();
}
Comment options

done

You must be logged in to vote
0 replies
Comment options

最后一题应该返回字面值吧

#[derive(Debug)]
enum TrafficLightColor {
 Red,
 Yellow,
 Green,
}
// 为 TrafficLightColor 实现所需的方法
impl TrafficLightColor {
 fn color(&self) -> &str {
 match *self {
 TrafficLightColor::Red => "red",
 TrafficLightColor::Yellow => "yellow",
 TrafficLightColor::Green => "Green",
 }
 }
}
fn main() {
 let c = TrafficLightColor::Yellow;
 assert_eq!(c.color(), "yellow");
 println!("{:?}",c);
}
You must be logged in to vote
3 replies
Comment options

这样也能通过

impl TrafficLightColor {
 pub fn color(&self) -> &str {
 match *self {
 Self::Red => "red",
 Self::Green => "green",
 Self::Yellow => "yellow",
 }
 }
}
Comment options

fn color(&self)-> &str {
match &self {
TrafficLightColor::Red=>"red",
TrafficLightColor::Yellow=>"yellow",
TrafficLightColor::Green=>"green",
}
}

我这样也行, 自动解引用真的让我习惯c++之后感到有点混乱。。总是不自主去思考指针。。

Comment options

没有生命周期的话,会导致悬垂指针

Comment options

fn color(&self) ->&str{
match self {
Yellow => "yellow",
_ => "other"
}
}

You must be logged in to vote
4 replies
Comment options

self前面加不加*有什么区别?

Comment options

均通过了测试

Comment options

rust的自动引用和解引用机制

Comment options

向match传入一个引用,匹配一个非引用模式(模式前不包含"&"),Rust会尝试copy传入的指针,如果指针不支持copy(例如可变引用就没有实现copy),那么就会move指针,传入的指针被销毁,创建一个相同指向的新指针取代。由此,match获得了指针的"所有权"(指针其实不因该谈所有权,但是借用这个说法好理解)。之后新指针会被解引用,拿到所指向数据的值。

Comment options

impl TrafficLightColor {
fn color(&self) -> &str {
match *self {
TrafficLightColor::Red => "red",
TrafficLightColor::Yellow => "yellow",
TrafficLightColor::Green => "Green",
}
}
}

这个能改成 if let 匹配吗?

You must be logged in to vote
1 reply
Comment options

但题目的目的是针对不同的颜色返回不同的字符串

Comment options

done

You must be logged in to vote
0 replies
Comment options

done

You must be logged in to vote
0 replies
Comment options

You must be logged in to vote
1 reply
Comment options

Done

Comment options

DONE

You must be logged in to vote
0 replies
Comment options

done

You must be logged in to vote
0 replies
Comment options

为什么用 self 也能正常运行?

fn color(&self) -> &str{
 match self {
 Yellow => "yellow",
 Red => "red",
 Green => "red",
 _ => "unknow"
 }
 }
You must be logged in to vote
3 replies
Comment options

这样写会有警告吧。

Comment options

自动解引用。作者不是说这样写更好吗?让使用者知道这里使用的是引用

Comment options

请问这里一定得进行解引用这一步吗(不管是显式还是隐式),代码里

let c = TrafficLightColor::Yellow;

c本身就是TrafficLightColor的一个值,那color函数里的self是值的引用,不可以直接进行模式匹配吗

Comment options

lala

You must be logged in to vote
0 replies
Comment options

done

You must be logged in to vote
0 replies
Comment options

1、方法的声明

struct Rectangle {
 width: u32,
 height: u32,
}
impl Rectangle {
 // 完成 area 方法,返回矩形 Rectangle 的面积
 fn area(&self)->u32{
 self.width*self.height
 }
}
fn main() {
 let rect1 = Rectangle { width: 30, height: 50 };
 assert_eq!(rect1.area(), 1500);
}

2、方法中&selfself的区别

// 只填空,不要删除任何代码行!
#[derive(Debug)]
struct TrafficLight {
 color: String,
}
impl TrafficLight {
 pub fn show_state(&self) {//不可以用self,会导致所有权转移
 println!("the current state is {}", self.color);
 }
}
fn main() {
 let light = TrafficLight{
 color: "red".to_owned(),
 };
 // 不要拿走 `light` 的所有权
 light.show_state();
 // 否则下面代码会报错
 println!("{:?}", light);
}

3、方法中&self&mut self的用法

struct TrafficLight {
 color: String,
}
impl TrafficLight {
 // 使用 `Self` 填空
 pub fn show_state(&self) {
 println!("the current state is {}", self.color);
 }
 // 填空,不要使用 `Self` 或其变体
 pub fn change_state(&mut self) {
 self.color = "green".to_string()
 }
}
fn main() {}

4、Self代替对类型的说明

#[derive(Debug)]
struct TrafficLight {
 color: String,
}
impl TrafficLight {
 // 1. 实现下面的关联函数 `new`,
 // 2. 该函数返回一个 TrafficLight 实例,包含 `color` "red"
 // 3. 该函数必须使用 `Self` 作为类型,不能在签名或者函数体中使用 `TrafficLight`
 pub fn new()->Self{
 Self{
 color:String::from("red"),
 }
 }
 pub fn get_state(&self) -> &str {
 &self.color
 }
}
fn main() {
 let light = TrafficLight::new();
 //println!("{:?}",light);
 assert_eq!(light.get_state(), "red");
}

5、每个结构体可以对应多个impl模块

struct Rectangle {
 width: u32,
 height: u32,
}
// 使用多个 `impl` 语句块重写下面的代码
impl Rectangle {
 fn area(&self) -> u32 {
 self.width * self.height
 }
 
}
impl Rectangle{
 fn can_hold(&self, other: &Rectangle) -> bool {
 self.width > other.width && self.height > other.height
 }
}
fn main() {}

6、

//自己的答案,可以度过,但是很明显逻辑看上去很奇怪
#[derive(Debug)]
enum TrafficLightColor {
 Red,
 Yellow,
 Green,
}
// 为 TrafficLightColor 实现所需的方法
impl TrafficLightColor {
 pub fn color(&self)->&str{
 "yellow"
 }
}
fn main() {
 let c = TrafficLightColor::Yellow;
 assert_eq!(c.color(), "yellow");
 println!("{:?}",c);
}

官方答案

#[derive(Debug)]
enum TrafficLightColor {
 Red,
 Yellow,
 Green,
}
// implement TrafficLightColor with a method
impl TrafficLightColor {
 fn color(&self) -> String {
 //模式匹配赛高
 match *self {
 TrafficLightColor::Red => "red".to_string(),
 TrafficLightColor::Yellow => "yellow".to_string(),
 TrafficLightColor::Green => "green".to_string(),
 }
 }
}
fn main() {
 let c = TrafficLightColor::Yellow;
 assert_eq!(c.color(), "yellow");
 println!("{:?}", c);
}
You must be logged in to vote
0 replies
Comment options

done

You must be logged in to vote
0 replies
Comment options

assert_eq!()函数可以同时比较String与&str这两个类型具体的内容是否相同。

You must be logged in to vote
0 replies
Comment options

done~~~

You must be logged in to vote
0 replies
Comment options

mark finished

You must be logged in to vote
0 replies
Comment options

impl TrafficLightColor {
 fn color(&self) -> &str {
 match self {
 Self::Red => "red",
 Self::Yellow => "yellow",
 Self::Green => "green"
 }
 }
}
You must be logged in to vote
0 replies
Comment options

impl TrafficLightColor {
fn color(&self) -> String {
let f = format!("{:?}", self);
f.to_lowercase()
}
}
最后一题这样也行

You must be logged in to vote
0 replies
Comment options

day4 方法

You must be logged in to vote
0 replies
Comment options

done

You must be logged in to vote
0 replies
Comment options

Done

// 练习
// 语法糖:一种语法;使代码更已读或者更简洁。但不增加语法功能
// 字段初始化简写
// struct Point {
// x: i32,
// y: i32,
// }
// fn main() {
// let x = 5;
// let y = 10;
// let p = Point { x, y }; // 等同于 Point { x: x, y: y }
// }
// 模式匹配中的if let和while let
// let some_option = Some(5);
// // if let
// if let Some(x) = some_option {
// println!("Matched: {}", x);
// }
// // while let
// let mut stack = vec![1, 2, 3];
// while let Some(top) = stack.pop() {
// println!("{}", top);
// }
// // 如果不用语法糖,都需要用match进行匹配,上面的代码会变成这样:
// let some_option = Some(5);
// // 使用 match 代替 if let
// match some_option {
// Some(x) => println!("Matched: {}", x),
// None => {},
// }
// // 使用 match 代替 while let
// let mut stack = vec![1, 2, 3];
// loop {
// match stack.pop() {
// Some(top) => println!("{}", top),
// None => break,
// }
// }
// 方法调用的自动引用和解引用
// struct Circle {
// radius: f64,
// }
// impl Circle {
// fn area(&self) -> f64 {
// std::f64::consts::PI * self.radius * self.radius
// }
// }
// fn main() {
// let circle = Circle { radius: 5.0 };
// println!("Area: {}", circle.area()); // 自动引用
// // println!("Area: {}", Circle::area(&circle)); // 显式传递引用
// }
// 闭包的简写
// let add = |a, b| a + b; // 等同于 |a: i32, b: i32| -> i32 { a + b }
// println!("Sum: {}", add(2, 3));
// 1.
// struct Rectangle {
// width: u32,
// height: u32,
// }
// impl Rectangle {
// fn area(&self) -> u32 {
// self.width * self.height
// }
// }
// fn main() {
// let rect1 = Rectangle { width: 30, height: 50 };
// assert_eq!(rect1.area(), 1500);
// }
// 2. 
// #[derive(Debug)]
// struct TrafficLight {
// color: String,
// }
// impl TrafficLight {
// pub fn show_state(&self) {
// println!("the current state is: {}", &self.color);
// }
// }
// fn main() {
// let light = TrafficLight {
// color: "red".to_owned(),
// };
// light.show_state();
// println!("{:?}", light);
// }
// 3.
// struct TrafficLight {
// color: String,
// }
// impl TrafficLight {
// pub fn show_state(&self) {
// println!("the current state is: {}", self.color);
// }
// pub fn change_state(& mut self) {
// self.color = "green".to_string();
// }
// }
// fn main() {}
// 4.
// #![]和#[]区别
// #![]crate级别属性
// #[]项级别属性
// #[derive(Debug)]
// struct TrafficLight {
// color: String,
// }
// impl TrafficLight {
// pub fn new() -> TrafficLight {
// TrafficLight {
// color: "red".to_string(),
// }
// }
// pub fn get_status(&self) -> &str {
// &self.color
// }
// }
// fn main() {
// let light = TrafficLight::new();
// assert_eq!(light.get_status(), "red");
// }
// 5.
// struct Rectangle {
// width: u32,
// height: u32,
// }
// impl Rectangle {
// fn area(&self) -> u32 {
// self.width * self.height
// }
// }
// impl Rectangle {
// fn can_hold(&self, other: &Rectangle) -> bool {
// self.width > other.width && self.height > other.height
// }
// }
// fn main() {}
// 6.
#[derive(Debug)]
enum TrafficLightColor {
 Red,
 Yellow,
 Green,
}
impl TrafficLightColor {
 fn color(&self) -> &str {
 match self {
 TrafficLightColor::Red => "red",
 TrafficLightColor::Yellow => "yellow",
 TrafficLightColor::Green => "green",
 }
 }
}
fn main() {
 let c = TrafficLightColor::Yellow;
 assert_eq!(c.color(), "yellow");
 println!("{:?}", c);
}
You must be logged in to vote
0 replies
Comment options

请教一下,为什么第二题用的是self.color?

// println!("the current state is: {}", &self.color);
 println!("the current state is: {}", self.color);

两种方式我都试过了,都可以正常编译,使用答案中提示的self.color有什么好处?

You must be logged in to vote
0 replies
Comment options

done ✅

You must be logged in to vote
0 replies
Comment options

done

You must be logged in to vote
0 replies
Comment options

第 6 题

#[derive(Debug)]
enum TrafficLightColor {
 Red,
 Yellow,
 Green,
}
// 为 TrafficLightColor 实现所需的方法
impl TrafficLightColor {
 fn color(&self) -> &str {
 if let TrafficLightColor::Yellow = self {"yellow"} else {
 "not yellow"
 }
 }
}
fn main() {
 let c = TrafficLightColor::Yellow;
 assert_eq!(c.color(), "yellow");
 println!("{:?}",c);
}
You must be logged in to vote
0 replies
Comment options

done

You must be logged in to vote
0 replies
Comment options

第六题也可以这样实现:
impl TrafficLightColor {
fn color(&self) -> String {
format!("{:?}", &self).to_lowercase()
}
}

You must be logged in to vote
0 replies
Comment options

// 为 TrafficLightColor 实现所需的方法

impl TrafficLightColor {
 fn color(&self) -> String {
 format!("{:?}", &self).to_lowercase()
 }
}
You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /