compound-types/enum #170
Replies: 32 comments 9 replies
-
第6题这样也可以通过,跟参考答案有不少差距,不是很明白,可以解释一下吗?
|
Beta Was this translation helpful? Give feedback.
-
Done, 废了些功夫总算是解决了这个问题。很多东西不是很理解,之后估计还有回来再理解一下 |
Beta Was this translation helpful? Give feedback.
-
链表就是函数式那一套.. 理解了其实很直观, 比用c写简单其实 |
Beta Was this translation helpful? Give feedback.
-
// C语言风格的枚举定义
enum Number2 {
Zero = 0,
One = 1,
}
enum Number{
Zero(u8),
One(u8),
} 这种直接赋值和元祖申明类型,有什么区别。然后结构体那种不能直接赋值吗? |
Beta Was this translation helpful? Give feedback.
-
2022.11.15 Done |
Beta Was this translation helpful? Give feedback.
-
done,6 not understand |
Beta Was this translation helpful? Give feedback.
-
第6题还没打算看,等看完了基础部分再回来试试叭 |
Beta Was this translation helpful? Give feedback.
-
第三题还能修改msg的定义是没想到的。。 |
Beta Was this translation helpful? Give feedback.
-
第四题, 数组的概念还没学... |
Beta Was this translation helpful? Give feedback.
-
第二题的: |
Beta Was this translation helpful? Give feedback.
-
Done。最后一题链表如果没有提供好框架让我们从头开始写的话确实是相当高难度的了。打印链表那里怕读者想不到怎么递归还提示了调用函数,他温我哭。 |
Beta Was this translation helpful? Give feedback.
-
加了几个常用方法,最后pop函数那儿不得以还是引入了Copy特征,但是暂时也想不到别的好办法了,模式匹配可以用Clone特征取值吗? use std::fmt::Debug;
use crate::List::*;
enum List<T> {
Cons(T, Box<List<T>>),
Nil,
}
impl<T> List<T> where T: Debug + Copy {
fn new() -> Self {
Nil
}
fn prepend(self, elem: T) -> Self {
Cons(elem, Box::new(self))
}
fn append(&mut self, elem: T) {
match *self {
Cons(_, ref mut tail) => tail.append(elem),
Nil => *self = Cons(elem, Box::new(Nil))
}
}
fn is_empty(&self) -> bool {
if let Nil = *self {
return true
}
return false
}
fn pop(&mut self) -> Option<T> {
if let Cons(elem, ref mut tail) = *self {
if tail.is_empty() {
*self = Nil;
return Some(elem)
} else {
tail.pop()
}
} else {
return None
}
}
fn front_pop(self) -> (Self, Option<T>) {
if let Cons(elem, tail) = self {
return (*tail, Some(elem))
} else {
return (self, None)
}
}
fn len(&self) -> usize {
match *self {
Cons(_, ref tail) => 1 + tail.len(),
Nil => 0
}
}
fn stringify(&self) -> String {
match *self {
Cons(ref head, ref tail) => {
format!("{:?}->{}", head, tail.stringify())
},
Nil => {
format!("Nil")
},
}
}
}
fn main() {
let mut list: List<u8> = List::new();
list.append(0_u8);
list = list.prepend(1_u8);
list = list.prepend(2_u8);
list = list.prepend(3_u8);
println!("{} Len: {}", list.stringify(), list.len());
list.append(10_u8);
println!("{} Len: {}", list.stringify(), list.len());
println!("{} pop out!", list.pop().unwrap());
println!("{} Len: {}", list.stringify(), list.len());
let (list, opt) = list.front_pop();
if let Some(elem) = opt {
println!("{} pop out from front!", elem);
}
println!("{} Len: {}", list.stringify(), list.len());
} |
Beta Was this translation helpful? Give feedback.
-
3,5 题出现了第八节的 if let, 第 6 题出现 impl, 这些还没学过. 虽然去搜资料能够完成现在的题目, 但是整个过程很下头. 思绪被某些东西弄乱了. |
Beta Was this translation helpful? Give feedback.
-
虽然没有完全理解这个链表,但是跟着注释,竟然一次就全对了 |
Beta Was this translation helpful? Give feedback.
-
1、 Q: // 修复错误
enum Number {
Zero,
One,
Two,
}
enum Number1 {
Zero = 0,
One,
Two,
}
// C语言风格的枚举定义
enum Number2 {
Zero = 0.0,
One = 1.0,
Two = 2.0,
}
fn main() {
// 通过 `as` 可以将枚举值强转为整数类型
assert_eq!(Number::One, Number1::One);
assert_eq!(Number1::One, Number2::One);
} A: // 修复错误
enum Number {
Zero,
One,
Two,
}
enum Number1 {
Zero = 0,
One,
Two,
}
// C语言风格的枚举定义
enum Number2 {
//不可以是浮点数
Zero = 0,
One = 1,
Two = 2,
}
fn main() {
// 通过 `as` 可以将枚举值强转为整数类型
assert_eq!(Number::One as u8, Number1::One as u8);
assert_eq!(Number1::One as u8, Number2::One as u8);
} 2、枚举成员可以持有各种类型的值 Q: // 填空
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msg1 = Message::Move{__}; // 使用x = 1, y = 2 来初始化
let msg2 = Message::Write(__); // 使用 "hello, world!" 来初始化
} A: // 填空
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msg1 = Message::Move{x:1,y:2}; // 这里需要显式赋值的变量名,并且用:作为分割
let msg2 = Message::Write(String::from("hello, world")); // 使用 "hello, world!" 来初始化
} 3、枚举成员中的值可以使用模式匹配来获取 Q: // 仅填空并修复错误
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msg = Message::Move{x: 1, y: 2};
if let Message::Move{__} = msg {
assert_eq!(a, b);
} else {
panic!("不要让这行代码运行!");
}
} A: // 仅填空并修复错误
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msg = Message::Move{x: 1, y: 1};//我们希望不要触发断言,所以由a=b推出x=y
if let Message::Move{x:a,y:b} = msg {//x的值赋给a,y的值赋给b
assert_eq!(a,b);
} else {
panic!("不要让这行代码运行!");
}
} 4、 使用枚举对类型进行同一化 Q: // 填空,并修复错误
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msgs: __ = [
Message::Quit,
Message::Move{x:1, y:3},
Message::ChangeColor(255,255,0)
];
for msg in msgs {
show_message(msg)
}
}
fn show_message(msg: Message) {
println!("{}", msg);
} A: // 填空,并修复错误
#[derive(Debug)]
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msgs: [Message;3] = [//额,其实用一些rust编译插件会自动帮你填充格式,比如vscode里面的rust analyzer
Message::Quit,
Message::Move{x:1, y:3},
Message::ChangeColor(255,255,0)
];
for msg in msgs {
show_message(msg)
}
}
fn show_message(msg: Message) {
println!("{:?}", msg);//无法直接打印,需要用{:?}或者{:#?}
} 5、Rust 中没有 Q: fn main() {
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);
if let __ = six {
println!("{}", n)
}
panic!("不要让这行代码运行!");
}
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
__ => None,
__ => Some(i + 1),
}
} A: //第一版实现,没有错误,但是出现了warning
fn main() {
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);
if let n = six {
println!("{:#?}", n)
}
panic!("不要让这行代码运行!");
}
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
} 6、使用枚举来实现链表 Q: // 填空,让代码运行
use crate::List::*;
enum List {
// Cons: 链表中包含有值的节点,节点是元组类型,第一个元素是节点的值,第二个元素是指向下一个节点的指针
Cons(u32, Box<List>),
// Nil: 链表中的最后一个节点,用于说明链表的结束
Nil,
}
// 为枚举实现一些方法
impl List {
// 创建空的链表
fn new() -> List {
// 因为没有节点,所以直接返回 Nil 节点
// 枚举成员 Nil 的类型是 List
Nil
}
// 在老的链表前面新增一个节点,并返回新的链表
fn prepend(self, elem: u32) -> __ {
Cons(elem, Box::new(self))
}
// 返回链表的长度
fn len(&self) -> u32 {
match *self {
// 这里我们不能拿走 tail 的所有权,因此需要获取它的引用
Cons(_, __ tail) => 1 + tail.len(),
// 空链表的长度为 0
Nil => 0
}
}
// 返回链表的字符串表现形式,用于打印输出
fn stringify(&self) -> String {
match *self {
Cons(head, ref tail) => {
// 递归生成字符串
format!("{}, {}", head, tail.__())
},
Nil => {
format!("Nil")
},
}
}
}
fn main() {
// 创建一个新的链表(也是空的)
let mut list = List::new();
// 添加一些元素
list = list.prepend(1);
list = list.prepend(2);
list = list.prepend(3);
// 打印列表的当前状态
println!("链表的长度是: {}", list.len());
println!("{}", list.stringify());
} A: // 填空,让代码运行
use crate::List::*;
enum List {
// Cons: 链表中包含有值的节点,节点是元组类型,第一个元素是节点的值,第二个元素是指向下一个节点的指针
Cons(u32, Box<List>),
// Nil: 链表中的最后一个节点,用于说明链表的结束
Nil,
}
// 为枚举实现一些方法
impl List {
// 创建空的链表
fn new() -> List {
// 因为没有节点,所以直接返回 Nil 节点
// 枚举成员 Nil 的类型是 List
Nil
}
// 在老的链表前面新增一个节点,并返回新的链表
fn prepend(self, elem: u32) -> List {
Cons(elem, Box::new(self))
}
// 返回链表的长度
fn len(&self) -> u32 {
match *self {
// 这里我们不能拿走 tail 的所有权,因此需要获取它的引用
Cons(_,ref tail) => 1 + tail.len(),
// 空链表的长度为 0
Nil => 0
}
}
// 返回链表的字符串表现形式,用于打印输出
fn stringify(&self) -> String {
match *self {
Cons(head, ref tail) => {
// 递归生成字符串
format!("{}, {}", head, tail.len())
},
Nil => {
format!("Nil")
},
}
}
}
fn main() {
// 创建一个新的链表(也是空的)
let mut list = List::new();
// 添加一些元素
list = list.prepend(1);
list = list.prepend(2);
list = list.prepend(3);
// 打印列表的当前状态
println!("链表的长度是: {}", list.len());
println!("{}", list.stringify());
} |
Beta Was this translation helpful? Give feedback.
-
第三题: 为什么 let msg = Message::Move { x: 1, y: 1 }; 匹配可以过; |
Beta Was this translation helpful? Give feedback.
-
Done. |
Beta Was this translation helpful? Give feedback.
-
第一题编译器是怎么知道Number::One是1呢? |
Beta Was this translation helpful? Give feedback.
-
尝试写了写 append pop_front pop_back enum MyList {
Node(i32, Box<MyList>),
Null,
}
impl MyList {
fn new() -> MyList {
MyList::Null
}
fn size(&self) -> u32 {
match self {
Self::Null => 0,
Self::Node(_, ref next) => next.size() + 1,
}
}
fn stringify(&self) -> String {
match self {
Self::Null => String::from("Null"),
Self::Node(n, next) => format!("{}->{}", n, next.stringify()),
}
}
fn print(&self) {
match self {
Self::Null => println!("len={}, list={}", self.size(), self.stringify()),
Self::Node(_, _) => println!(
"len={}, front={}, back={}, list={}",
self.size(),
self.front().unwrap(),
self.back().unwrap(),
self.stringify()
),
}
}
fn front(&self) -> Option<i32> {
match self {
Self::Null => None,
Self::Node(num, _) => Some(*num),
}
}
fn back(&self) -> Option<i32> {
match self {
Self::Null => None,
Self::Node(num, next) => match **next {
Self::Null => Some(*num),
Self::Node(_, _) => next.back(),
},
}
}
fn preppend(self, num: i32) -> MyList {
Self::Node(num, Box::new(self))
}
fn pop_front(self) -> MyList {
match self {
Self::Null => self,
Self::Node(_, next) => *next,
}
}
fn append(&mut self, num: i32) {
match self {
Self::Null => *self = Self::Node(num, Box::new(Self::Null)),
Self::Node(_, next) => next.append(num),
}
}
fn pop_back(&mut self) {
if let Self::Node(_, next) = self {
match **next {
Self::Null => *self = Self::Null,
Self::Node(_, _) => next.pop_back(),
}
}
}
}
fn main() {
let mut list = MyList::new();
list.print();
list = list.preppend(1);
list = list.preppend(2);
list = list.preppend(3);
list.print();
list.append(4);
list.append(5);
list.append(6);
list.print();
list = list.pop_front();
list = list.pop_front();
list.print();
list.pop_back();
list.pop_back();
list.print();
} |
Beta Was this translation helpful? Give feedback.
-
mark finished |
Beta Was this translation helpful? Give feedback.
-
compound-types/enum
Learning Rust By Practice, narrowing the gap between beginner and skilled-dev with challenging examples, exercises and projects.
https://zh.practice.rs/compound-types/enum.html
Beta Was this translation helpful? Give feedback.
All reactions