主页 > 其他  > 

rust学习六、简单的struct结构

rust学习六、简单的struct结构

一、结构定义 struct-翻译为结构/结构体

总体上有两种定义方式:带有详细属性名的;不带属性名(元组)

从工程角度出发,并不推荐不带属性的定义方式,因为不友好。希望rust后面不要搞类似好像很友好,但是其实起到干扰作用的语法。

如果再考虑到一些rust的其它问题,定义一个结构其实也不是那么容易。

示例: struct Point{x:f64,y:f64} struct Triangle(Point,Point,Point);

/**  * 家庭结构体s  */ struct Family {     name: String,     father: String,     mather: String,     children: Vec<String>, } /**  * 这都什么狗屎语法。  */ struct Book<'a> {     name: &'a str,     author: &'a str,     price: f64,     pubyear: i32, } fn main() {     let mut family = Family {         name: String::from("家"),         father: String::from("爸爸"),         mather: String::from("妈妈"),         children: vec![],     };

    family.children.push(String::from("老大-独龙"));     family.children.push(String::from("老二-独眼"));     family.children.push(String::from("老三-独秀"));     family.children.push(String::from("老四-嘟嘟"));     family.children.push(String::from("老五-杜牧"));

    //打印家庭结构体     println!(         "家庭:{},父亲:{},母亲:{}",         family.name, family.father, family.mather     );     for child in &family.children {         println!("孩子:{}", child);     }     let mut 三国演义 = Book {         name: "三国演义",         author: "罗贯中",         price: 29.8,         pubyear: 1300,     };          //各种创建结构实例的方式     // 方式一:双点号复制     let mut 红楼梦=Book{         name:"红楼梦",         author:"曹雪芹",         ..三国演义     };     //方式二: 略属性名     let 西游记=write_book("西游记","吴承恩",24.0,1525);     //方式三:使用基于元组定义的。 比java的record还简单

    let books=[三国演义,红楼梦,西游记];     for i in 0..books.len() {         print_book(&books[i]);     }     let p1=Point{x:10.0,y:20.0};     let p2=Point{x:20.0,y:20.0};     let p3=Point{x:20.0,y:10.0};     let t=Triangle(p1,p2,p3);     print_triangle(&t); }

fn print_book(book:&Book){     println!(         "书名:{},作者:{},价格:{},出版年:{}",         book.name, book.author, book.price, book.pubyear     ); }

fn print_triangle(t:&Triangle){     println!("三点坐标:");     println!("{},{}",t.0.x,t.0.y);     println!("{},{}",t.1.x,t.1.y);     println!("{},{}",t.2.x,t.2.y); }

fn write_book<'a>(name:&'a str,author:&'a str,price:f64,pubyear:i32)->Book<'a>{     Book{         name,         author,         price,         pubyear     } }

在上例中,结构Book使用了非常奇怪的语法:

struct Book<'a> {

    name: &'a str,

    author: &'a str,

    price: f64,

    pubyear: i32,

}

这个能够定义出来,是因为编译器提示的。

作为初学者,先绕过这个吧。 

rust结构体实例的属性赋值也有两种方式: 属性逐一赋值

双点号复制属性值 例如以下就是: let mut 红楼梦=Book{         name:"红楼梦",         author:"曹雪芹",         ..三国演义     };

二、几种打印方式 至少有4种打印方式:

逐一访问属性名 println!使用宏符号:? println!使用宏符号:#? 使用dbg! 后面三种方式,要求定义结构的时候,在结构前添加

#[derive(Debug)] 这个东西应该怎么称呼了? "属性"还是"编译指示符"?,有点乱七八杂的。 

从宏观上而言,很多类似的都是可以称为编译指示符,所以为了更加精准一些,我愿意称为"功能编译指示"。

通过这个功能编译指示,rust编译器会自动实现特定功能。

示例:

#[derive(Debug)] struct Family{     father:String,     mather:String,     address:String }

fn main(){     let mut mf=Family{         father:String::from("lu"),         mather:String::from("hu"),         address:String::from("中国")     };     println!("我家-{},{},{}",mf.father,mf.mather,mf.address);     print_family(&mf);     print_family_use_dbg(&mf); }

fn print_family(f:&Family){     //你不能直接打印,否则会有奇奇怪怪的错误提示     //println!("{}",f);  // 这个会提示错误,所以注释掉了

    //使用奇怪符号 :?打印结构体     println!("我家:?-{:?}",f);

    //使用奇怪的符号,可以打印结构体 :#?     println!("我家:#?-{:#?}",f); }

fn print_family_use_dbg(f:&Family){     dbg!(f); }

三、定义结构内的函数 在没有看书本正文之前,我以为和java的record一样,在struct内部定义函数。

其实不是! 如果要为结构体定义函数,必须在结构体外。 不知道为什么要那样? 难道内部定义的话,有其它用途?

示例: #[derive(Debug)] struct Cube{     length: u32,     width: u32,     height: u32, } impl Cube{     fn volume(&self) -> u32{         return self.length * self.width * self.height;     }     fn is_bigger_than(&self, other: &Cube) -> bool{         return self.volume() > other.volume();     }

}

fn main() {     let cube = Cube{length: 10, width: 12, height: 25};     let cube2 = Cube{length: 15, width: 10, height: 30};     println!("立方体的体积={}立方厘米",cube.volume());     let is_bigger = cube.is_bigger_than(&cube2);     match is_bigger{         true => println!("cube的体积{}大于cube2体积{}",cube.volume(), cube2.volume()),         false =>println!("cube的体积{}小于cube2体积{}",cube.volume(), cube2.volume()),     }; }

结构体的函数有几个特点:

在结构体外,使用impl xxxx {}的方式,其中xxx是结构体名称 在一个impl xxx{}结构中,可以定义多个函数 书本建议我们:函数的第一个方法总是 &self,这点和python有点类似 参数&self虽然有定义,但是调用的时候不需要显示传递,因为这是编译器实现的

四、一点小补充 4.1定义没有成员的结构 在很多OOP,允许我们定义没有成员的对象。

我们可以把struct大体当做对象。

在rust中也可以定义没有成员的结构,例如:

#[derive(Debug)] struct NoItem;  struct NoItem2();

let nod=NoItem{}; println!("空结构体:{:?}",nod);  

rust允许这样做,是因为struct这个类型具有很多作用,即使它不用于存储数据,也有很多作用。具体什么作用,只能等待深入后了解。

总之在rust中,绝大部分复杂的类型,都是基于结构定义的。

4.2struct大有作用 前有言:某种程度上可以把struct视为OOP中的对象

虽然rust不是明面上的OOP,但还是吸收了很多OOP的营养。

总之,许多复杂类型都是基于结构定义的。具体不一一罗列。

五、小结 结构体无疑是一个有用的东西,它就算垃圾袋/宝物袋一样,什么都可以往里装,大大方便了工程师!

  

          关注灵活就业新业态,关注公账号:贤才宝

标签:

rust学习六、简单的struct结构由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“rust学习六、简单的struct结构