Rust的结构类型在使用前必须使用struct语法声明:struct Name { field1: T1, field2: T2 [, ...] },T1,T2…表示类型。当构造结构时,使用相同的语法,但不需要使用struct关键字:例如Point { x: 1.0, y: 2.0 }。
结构与C中的结构非常相似,甚至在内存中使用相同的布局方式(因此你能在C中读Rust结构,反之亦然)。使用点操作符访问结构的域,像mypoint.x。
struct Point { x: f64, y: f64 }
结构有“继承的可变性”,这意味着如果结构处在可变的位置,则结构的任何域都可能是可变的。
当这样类型的值(假设为mypoint)处在可变的位置,你可以执行mypoint.y += 1.0。但在不可变的位置,对没有继承可变性的结构这样的赋值将导致类型错误。
let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 }; mypoint.y += 1.0; // `mypoint` is mutable, and its fields as well origin.y += 1.0; // ERROR: assigning to immutable fieldmatch模式解构结构体,其基本语法为:Name{ fieldname: pattern, ... }
match mypoint { Point { x: 0.0, y: yy } => println!("{}", yy), Point { x: xx, y: yy } => println!("{} {}", xx, yy) }一般而言,结构的域名不必和它们在类型中出现的有相同的顺序。当你不感兴趣结构的所有域时,结构匹配以,..(就像Name{ field1, .. })结束预示你将忽略所有其他的域。此外,结构域有一个简写匹配形式,通过简单地重用域名作为绑定名。
match mypoint { Point { x, .. } => println!("{}", x) }
枚举是带有几个可选代表的数据类型。一个简单的enum定义了一个或者多个常量,所有的常量有相同的类型:
enum Direction { North, East, South, West }
枚举中的每个变量都有唯一且恒定的整型可识别的数值。如果变量没有显式定义可识别的值,则其值默认为前面变量值加1。如果第一个变量没有可识别的值,它默认为0。举个例子,North的值为0,East的值为1,South的值为2,West的值为3。
当枚举有简单的可识别值时,你可以通过as转换操作符将变量转换成其可识别值的int类型:
println!( "{:?} => {}", North, North as int );选择不同常量设置可识别值是可能的:
enum Color { Red = 0xff0000, Green = 0x00ff00, Blue = 0x0000ff }变量不必仅有简单的值,它们可能更复杂:
enum Shape { Circle(Point, f64), Rectangle(Point, Point) }
类型的值可能是Circle,此时它包含一个Point结构和一个f64,或者是Rectangle,此时它包含两个Point结构。值在运行时的表现取决于它所保持的实际形式,很像C中的“标签联合”,但却有更好地静态保证。
声明定义了涉及这样形状的类型Shape,两个函数Circle和Rectangle被用来构造这种类型的值。创建新的Circle,写做Circle(Point { x: 0.0, y: 0.0 }, 10.0)。
所有变量的构造器都能够用于模式上。访问枚举实例内容的唯一方式是通过匹配解构。例如:use std::f64; fn area(sh: Shape) -> f64 { match sh { Circle(_, size) => f64::consts::PI * size * size, Rectangle(Point { x, y }, Point { x: x2, y: y2 }) => (x2 - x) * (y2 - y) } }使用单独的_忽略个别域,使用类似Circle(..)形式忽略变量所有的域。无参枚举模式可以不必使用圆括号:
fn point_from_direction(dir: Direction) -> Point { match dir { North => Point { x: 0.0, y: 1.0 }, East => Point { x: 1.0, y: 0.0 }, South => Point { x: 0.0, y: -1.0 }, West => Point { x: -1.0, y: 0.0 } } }枚举变量也可能是结构,例如:
use std::f64; enum Shape { Circle { center: Point, radius: f64 }, Rectangle { top_left: Point, bottom_right: Point } } fn area(sh: Shape) -> f64 { match sh { Circle { radius: radius, .. } => f64::consts::PI * square(radius), Rectangle { top_left: top_left, bottom_right: bottom_right } => { (bottom_right.x - top_left.x) * (top_left.y - bottom_right.y) } } }
注意:编译器的该特征当前是被#[feature(struct_variant)]指令所限制。关于这些指令的更多细节在手册中可以找到。
let mytup: (int, int, f64) = (10, 20, 30.0); match mytup { (a, b, c) => println!("{}", a + b + (c as int)) }
Rust也有元组结构,它的行为类似元组和结构。和元组的不同是,元组结构有名字(因此,Foo(1, 2)与Bar(1, 2)是不同的类型)且元组结构的域没有名字。例如:
struct MyTup(int, int, f64); let mytup: MyTup = MyTup(10, 20, 30.0); match mytup { MyTup(a, b, c) => println!("{}", a + b + (c as int)) }有单个域的元组结构是一个特殊情况,有时被称作“新类型”(和Haskell的newtype特征相同)。这种方式被用来定义新类型,新的名字不仅仅是已存在类型的同义词,而是具有不同的类型。
struct GizmoId(int);像这样的类型被用于区分那些具有相同的基本类型但必须以不同的方式使用的数据。
struct Inches(int); struct Centimeters(int);上述定义允许程序能够通过简单的方式避免混淆与不同单元关联的数字。它们的整数值能够被模式匹配提取:
let length_with_unit = Inches(10); let Inches(integer_length) = length_with_unit; println!("length is {} inches", integer_length);
原文:http://blog.csdn.net/wsgzg1991/article/details/23214279