结构体在这里给了三种声明样式
(1)字典样式的键值对(使用花括号)
(2)元组样式的数值元组(使用圆括号)
(3)空结构体,可以被格式化输出名字
- // structs1.rs
- // Address all the TODOs to make the tests pass!
- // Execute `rustlings hint structs1` or use the `hint` watch subcommand for a hint.
-
- // I AM NOT DONE
-
- struct ColorClassicStruct {
- // TODO: Something goes here
- red:u8,
- green:u8,
- blue:u8,
- }
-
- struct ColorTupleStruct(u8,u8,u8);
-
- #[derive(Debug)]
- struct UnitLikeStruct;
-
- #[cfg(test)]
- mod tests {
- use super::*;
-
- #[test]
- fn classic_c_structs() {
- // TODO: Instantiate a classic c struct!
- let green =ColorClassicStruct{red:0,green:255,blue:0};
-
- assert_eq!(green.red, 0);
- assert_eq!(green.green, 255);
- assert_eq!(green.blue, 0);
- }
-
- #[test]
- fn tuple_structs() {
- // TODO: Instantiate a tuple struct!
- let green =ColorTupleStruct(0,255,0);
-
- assert_eq!(green.0, 0);
- assert_eq!(green.1, 255);
- assert_eq!(green.2, 0);
- }
-
- #[test]
- fn unit_structs() {
- // TODO: Instantiate a unit-like struct!
- let unit_like_struct =UnitLikeStruct;
- let message = format!("{:?}s are fun!", unit_like_struct);
-
- assert_eq!(message, "UnitLikeStructs are fun!");
- }
- }
我们可以在一个结构体实例里面使用..otherStruct来对otherStruct里面未被定义的变量原封不动解包到该结构体实例里面
- // structs2.rs
- // Address all the TODOs to make the tests pass!
- // Execute `rustlings hint structs2` or use the `hint` watch subcommand for a hint.
-
- // I AM NOT DONE
-
- #[derive(Debug)]
- struct Order {
- name: String,
- year: u32,
- made_by_phone: bool,
- made_by_mobile: bool,
- made_by_email: bool,
- item_number: u32,
- count: u32,
- }
-
- fn create_order_template() -> Order {
- Order {
- name: String::from("Bob"),
- year: 2019,
- made_by_phone: false,
- made_by_mobile: false,
- made_by_email: true,
- item_number: 123,
- count: 0,
- }
- }
-
- #[cfg(test)]
- mod tests {
- use super::*;
-
- #[test]
- fn your_order() {
- let order_template = create_order_template();
- // TODO: Create your own order using the update syntax and template above!
- let your_order = Order{
- name: String::from("Hacker in Rust"),
- count:1,
- ..order_template
- };
- assert_eq!(your_order.name, "Hacker in Rust");
- assert_eq!(your_order.year, order_template.year);
- assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
- assert_eq!(your_order.made_by_mobile, order_template.made_by_mobile);
- assert_eq!(your_order.made_by_email, order_template.made_by_email);
- assert_eq!(your_order.item_number, order_template.item_number);
- assert_eq!(your_order.count, 1);
- }
- }
- // structs3.rs
- // Structs contain data, but can also have logic. In this exercise we have
- // defined the Package struct and we want to test some logic attached to it.
- // Make the code compile and the tests pass!
- // Execute `rustlings hint structs3` or use the `hint` watch subcommand for a hint.
-
- // I AM NOT DONE
-
- #[derive(Debug)]
- struct Package {
- sender_country: String,
- recipient_country: String,
- weight_in_grams: i32,
- }
-
- impl Package {
- fn new(sender_country: String, recipient_country: String, weight_in_grams: i32) -> Package {
- if weight_in_grams <= 0 {
- panic!("Can not ship a weightless package.")
- } else {
- Package {
- sender_country,
- recipient_country,
- weight_in_grams,
- }
- }
- }
-
- fn is_international(&self) -> bool {
- // Something goes here...
- return self.sender_country!=self.recipient_country
- }
-
- fn get_fees(&self, cents_per_gram: i32) -> i32 {
- // Something goes here...
- return cents_per_gram*self.weight_in_grams
- }
- }
-
- #[cfg(test)]
- mod tests {
- use super::*;
-
- #[test]
- #[should_panic]
- fn fail_creating_weightless_package() {
- let sender_country = String::from("Spain");
- let recipient_country = String::from("Austria");
-
- Package::new(sender_country, recipient_country, -2210);
- }
-
- #[test]
- fn create_international_package() {
- let sender_country = String::from("Spain");
- let recipient_country = String::from("Russia");
-
- let package = Package::new(sender_country, recipient_country, 1200);
-
- assert!(package.is_international());
- }
-
- #[test]
- fn create_local_package() {
- let sender_country = String::from("Canada");
- let recipient_country = sender_country.clone();
-
- let package = Package::new(sender_country, recipient_country, 1200);
-
- assert!(!package.is_international());
- }
-
- #[test]
- fn calculate_transport_fees() {
- let sender_country = String::from("Spain");
- let recipient_country = String::from("Spain");
-
- let cents_per_gram = 3;
-
- let package = Package::new(sender_country, recipient_country, 1500);
-
- assert_eq!(package.get_fees(cents_per_gram), 4500);
- assert_eq!(package.get_fees(cents_per_gram * 2), 9000);
- }
- }
- // enums1.rs
- // No hints this time! ;)
-
- // I AM NOT DONE
-
- #[derive(Debug)]
- enum Message {
- // TODO: define a few types of messages as used below
- Quit,
- Echo,
- Move,
- ChangeColor,
- }
-
- fn main() {
- println!("{:?}", Message::Quit);
- println!("{:?}", Message::Echo);
- println!("{:?}", Message::Move);
- println!("{:?}", Message::ChangeColor);
- }
使用向enumeration type添加一个方法
- // enums2.rs
- // Execute `rustlings hint enums2` or use the `hint` watch subcommand for a hint.
-
- // I AM NOT DONE
-
- #[derive(Debug)]
- enum Message {
- // TODO: define the different variants used below
- Move { x: i32, y: i32 },
- Echo(String),
- ChangeColor(u8, u8, u8),
- Quit,
- }
- // impl用于向一个类型(可以是结构体、枚举、特质 trait 等)添加方法或实现 trait,从而为该类型定义特定的行为。
- impl Message {
- fn call(&self) {
- println!("{:?}", &self);
- }
- }
-
- fn main() {
- let messages = [
- Message::Move { x: 10, y: 30 },
- Message::Echo(String::from("hello world")),
- Message::ChangeColor(200, 255, 255),
- Message::Quit,
- ];
-
- for message in &messages {
- message.call();
- }
- }
match 匹配格式如下
- match vailableType {
- namespace1::fun1(args1,args2) => {
- return self.fun1(args1,args2)
- }
- }
- // enums3.rs
- // Address all the TODOs to make the tests pass!
- // Execute `rustlings hint enums3` or use the `hint` watch subcommand for a hint.
-
- // I AM NOT DONE
-
- enum Message {
- // TODO: implement the message variant types based on their usage below
- ChangeColor((u8,u8,u8)),
- Echo(String),
- Move(Point ),
- Quit,
- // state.process(Message::ChangeColor((255, 0, 255)));
- // state.process(Message::Echo(String::from("hello world")));
- // state.process(Message::Move(Point { x: 10, y: 15 }));
- // state.process(Message::Quit);
- }
-
- struct Point {
- x: u8,
- y: u8,
- }
-
- struct State {
- color: (u8, u8, u8),
- position: Point,
- quit: bool,
- }
-
- impl State {
- fn change_color(&mut self, color: (u8, u8, u8)) {
- self.color = color;
- }
-
- fn quit(&mut self) {
- self.quit = true;
- }
-
- fn echo(&self, s: String) {
- println!("{}", s);
- }
-
- fn move_position(&mut self, p: Point) {
- self.position = p;
- }
-
- fn process(&mut self, message: Message) {
- // TODO: create a match expression to process the different message variants
- match message {
- Message::ChangeColor(objects) => {
- return self.change_color((objects.0,objects.1,objects.2))
- }
- Message::Echo(string) => {
- return self.echo(string)
- }
- Message::Move(point) => {
- return self.move_position( point)
- }
- Message::Quit => {
- return self.quit()
- }
-
- }
- }
- }
-
- #[cfg(test)]
- mod tests {
- use super::*;
-
- #[test]
- fn test_match_message_call() {
- let mut state = State {
- quit: false,
- position: Point { x: 0, y: 0 },
- color: (0, 0, 0),
- };
- state.process(Message::ChangeColor((255, 0, 255)));
- state.process(Message::Echo(String::from("hello world")));
- state.process(Message::Move(Point { x: 10, y: 15 }));
- state.process(Message::Quit);
-
- assert_eq!(state.color, (255, 0, 255));
- assert_eq!(state.position.x, 10);
- assert_eq!(state.position.y, 15);
- assert_eq!(state.quit, true);
- }
- }
可以调用&str对象的to_string()方法或者使用String::from(&str)将其转换
- // strings1.rs
- // Make me compile without changing the function signature!
- // Execute `rustlings hint strings1` or use the `hint` watch subcommand for a hint.
-
- // I AM NOT DONE
-
- fn main() {
- let answer = current_favorite_color();
- println!("My current favorite color is {}", answer);
- }
-
- fn current_favorite_color() -> String {
- String::from("blue")
- }
试运行如下代码:
- fn main() {
- let string1 = "aaaa".to_string();
- let string2 = "aaaa";
-
- if string1 == string2 {
- println!("Strings are equal");
- } else {
- println!("Strings are not equal");
- }
- }
- //输出 Strings are equal
- // strings2.rs
- // Make me compile without changing the function signature!
- // Execute `rustlings hint strings2` or use the `hint` watch subcommand for a hint.
-
- // I AM NOT DONE
-
- fn main() {
- let word = String::from("green"); // Try not changing this line :)
- if is_a_color_word(word) {
- println!("That is a color word I know!");
- } else {
- println!("That is not a color word I know.");
- }
- }
-
- fn is_a_color_word(attempt: String) -> bool {
- //对象类型不一致 都返回false
- // attempt == "green" || attempt == "blue" || attempt == "red"
- // let attempt = attempt.to_string();
- println!("{}|{}|{}",attempt == "green" ,attempt == "blue" ,attempt == "red");
- attempt == "green" || attempt == "blue" || attempt == "red"
-
- }
通常情况下&str使用方法后都会变成String
- // strings3.rs
- // Execute `rustlings hint strings3` or use the `hint` watch subcommand for a hint.
-
- // I AM NOT DONE
-
- fn trim_me(input: &str) -> String {
- // TODO: Remove whitespace from both ends of a string!
- input.trim().to_string()
- }
-
- fn compose_me(input: &str) -> String {
- // TODO: Add " world!" to the string! There's multiple ways to do this!
- input.trim().to_string()+" world!"
- }
-
- fn replace_me(input: &str) -> String {
- // TODO: Replace "cars" in the string with "balloons"!
- input.replace("cars","balloons")
- }
-
- #[cfg(test)]
- mod tests {
- use super::*;
-
- #[test]
- fn trim_a_string() {
- assert_eq!(trim_me("Hello! "), "Hello!");
- assert_eq!(trim_me(" What's up!"), "What's up!");
- assert_eq!(trim_me(" Hola! "), "Hola!");
- }
-
- #[test]
- fn compose_a_string() {
- assert_eq!(compose_me("Hello"), "Hello world!");
- assert_eq!(compose_me("Goodbye"), "Goodbye world!");
- }
-
- #[test]
- fn replace_a_string() {
- assert_eq!(replace_me("I think cars are cool"), "I think balloons are cool");
- assert_eq!(replace_me("I love to look at cars"), "I love to look at balloons");
- }
- }
看看就好,记住中间保持&str的特例函数和切片(trim()函数和切片变成&str)
- // strings4.rs
-
- // Ok, here are a bunch of values-- some are `String`s, some are `&str`s. Your
- // task is to call one of these two functions on each value depending on what
- // you think each value is. That is, add either `string_slice` or `string`
- // before the parentheses on each line. If you're right, it will compile!
- // No hints this time!
-
- // I AM NOT DONE
-
- fn string_slice(arg: &str) {
- println!("{}", arg);
- }
- fn string(arg: String) {
- println!("{}", arg);
- }
-
- fn main() {
- string_slice("blue");
- string("red".to_string());
- string(String::from("hi"));
- string("rust is fun!".to_owned());
- string("nice weather".into());
- string(format!("Interpolation {}", "Station"));
- string_slice(&String::from("abc")[0..1]);
- string_slice(" hello there ".trim());
- string("Happy Monday!".to_string().replace("Mon", "Tues"));
- string("mY sHiFt KeY iS sTiCkY".to_lowercase());
- }