文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
7.5 结构
三种结构体风格:
- 命名结构:字段名。
- 元组结构:命名元组。
- 单元结构:不带任何字段。
命名结构
初始化必须是 {key:val, ...}
,除非是同名变量。必须包含全部字段。
添加
#[derive(Debug)]
,以便{:?}
详细输出。字段默认为私有,外部模块访问需添加pub
。
#[derive(Debug)] struct Name { a: i64, b: i64, c: i64, } fn main() { let b = 3; let c = 4; let u = Name {a:1, b, c}; // 简写:b、c 字段值为同名变量或参数。 let u2 = Name{ c:10, ..u // 更新:同类型其他变量更新(填充)其余字段。 }; assert_eq!(u2.a, u.a); assert_eq!(u2.b, u.b); assert_eq!(u2.c, 10); }
struct Point { x: i32, y: i32, } fn main() { let p = Point { x: 0, y: 7 }; let Point { x: a, y: b } = p; // 利用解构方式,定义变量 a、b。 // let Point { x: a, .. } = p; // 部分内容。 assert_eq!(0, a); assert_eq!(7, b); let Point { x, y } = p; // 与字段同名变量。 // let Point { x, .. } = p; assert_eq!(0, x); assert_eq!(7, y); }
struct Point { x: i32, y: i32, } fn main() { let p = Point { x: 6, y: 7 }; let r = &p; assert_eq!(6, (*r).x); assert_eq!(7, r.y); // 操作符 “.” 隐式解引用。 }
不能标记局部字段可变。
可用
Cell
设定一个可变字段。
struct Point { x: i32, mut y: i32, // 错误!不允许局部修改。 }
但可以有可变引用。
作为字段的引用本身不会改变,改变的是其引用的目标对象(mut)。目标对象不属于结构组成部分,自然不存在局部修改问题。
struct PointRef<'a> { x: &'a mut i32, y: &'a mut i32, } fn main() { let mut x = 10; let mut y = 20; let p = PointRef{x: &mut x, y: &mut y}; *p.x = 100; // p.x 访问字段,*(p.x) 透过字段访问外部变量。 *p.y = 200; assert_eq!(x, 100); assert_eq!(y, 200); }
对齐
编译器会对字段布局进行对齐(align)优化,减少内存占用。
use std::mem::size_of; struct X { a: i32, b: i64, c: i32, } #[repr(C)] struct Y { a: i32, b: i64, c: i32, } fn main() { assert_eq!(size_of::<X>(), 16); assert_eq!(size_of::<Y>(), 24); let x = X{a:1, b:2, c:3}; let y = Y{a:1, b:2, c:3}; // offset: // x.a - x > 0 // y.a - y == 0 assert!(&x.a as *const i32 as usize - &x as *const X as usize > 0); assert!(&y.a as *const i32 as usize - &y as *const Y as usize == 0); } /* (gdb) x/2xg &x 0x7fffffffe150: 0x0000000000000002 0x0000000300000001 (gdb) x/3xg &y 0x7fffffffe160: 0x0000000000000001 0x0000000000000002 0x7fffffffe170: 0x0000000000000003 */
元组结构
元祖结构(tuple structs)有类型名,但字段没有,以序号访问。
#[derive(Debug)] struct RGB(i32, i32, i32); fn main() { let grey = RGB(119, 136, 153); println!("{:?}", grey); println!("{} {} {}", grey.0, grey.1, grey.2); }
fn main() { let grey = RGB(119, 136, 153); let RGB(r, g, b) = grey; // 解构,定义变量。 assert_eq!(r, grey.0); assert_eq!(g, grey.1); assert_eq!(b, grey.2); }
单元结构
单元结构(unit-like structs)没有字段,隐式定义了与类型同名的实例。
struct Electron;
等价于:
struct Electron {} // 类型 Electron: Electron = Electron {}; // 实例
注意:
struct T{}
和struct T
不同,缺了实例定义。
struct Y {} struct X; fn main() { let _a = X; let _b = Y; ^ use struct literal syntax instead: Y{} }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论