31.结构体申明
结构体在这里给了三种声明样式
(1)字典样式的键值对(使用花括号)
(2)元组样式的数值元组(使用圆括号)
(3)空结构体,可以被格式化输出名字
rust
// 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!");
}
}
32.结构体的解包
我们可以在一个结构体实例里面使用..otherStruct来对otherStruct里面未被定义的变量原封不动解包到该结构体实例里面
rust
// 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);
}
}
33.类里面的方法除了当前区域内的变量,其他都要加self引用
rust
// 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);
}
}