语法
struct Name_of_structure {
field1: data_type,
field2: data_type,
field3: data_type,
}
注意:
不同于C++,Rust的struct语句仅用来定义类型,不能定义实例。
结尾不需要;。
每个字段定义之后用 , 分隔。最后一个逗号可有可无。
例子
struct Site {
domain: String,
name: String,
nation: String,
found: u32,
}
1.语法
let instance_name = Name_of_structure {
field1: value1,
field2: value2,
field3: value3,
};
Rust受JavaScript影响,使用JSON对象的key: value语法定义结构体的实例
例子
let runoob = Site {
domain: String::from("www.runoob.com"),
name: String::from("RUNOOB"),
nation: String::from("China"),
found: 2013,
};
2.如果字段名称和变量名称一样,可以简化书写:
例子
let domain = String::from("www.runoob.com");
let name = String::from("RUNOOB");
let runoob = Site {
domain, // 等同于domain : domain,
name, // 等同于name : name,
nation: String::from("China"),
found: 2013,
};
3.复制现成的实例,只修改部分字段,可以使用如下语法
let site = Site {
domain: String::from("www.xx.com"),
name: String::from("xx"),
..runoob,
};
这种语法要求至少重新设定一个字段的值
(一)
元组结构体的形式是元组,与元组的区别是它有名字和固定的类型格式。
它的意义是为了处理那些需要定义类型又不想太复杂的简单数据:
struct Color(u8, u8, u8);
struct Point(f64, f64);
let black = Color(0, 0, 0);
let origin = Point(0.0, 0.0);
元组结构体的使用方式和元组一样,通过 . 和下标来访问
例子
fn main() {
struct Color(u8, u8, u8);
struct Point(f64, f64);
let black = Color(0, 0, 0);
let origin = Point(0.0, 0.0);
println!("black = ({}, {}, {})", black.0, black.1, black.2);
println!("origin = ({}, {})", origin.0, origin.1);
}
运行结果:
black = (0, 0, 0)
origin = (0, 0)
(二)newtype模式
newtype模式是使用元组结构体创建一个新类型,这个元组结构体只有一个字段,相当于对这个字段类型的封装。
newtype模式的用处
1.newtype模式可以用于确保某值不被混淆
例子
Years和Days结构体都封装了i64值。
struct Years(i64);
struct Days(i64);
impl Years {
pub fn to_days(&self) -> Days {
Days(self.0 * 365)
}
}
impl Days {
pub fn to_years(&self) -> Years {
Years(self.0 / 365)
}
}
fn old_enough(age: &Years) -> bool {
age.0 >= 18
}
fn main() {
let age = Years(5);
let age_days = age.to_days();
println!("Old enough {}", old_enough(&age));
println!("Old enough {}", old_enough(&age_days.to_years()));
// println!("Old enough {}", old_enough(&age_days));
}
取消最后一行的注释,就会报错。传给old_enough的参数类型必须是Years类型的。
2.为外部类型实现外部trait
参考Rust特性
结构体可以没有任何成员,称为单元结构体。
struct MyStruct;
(一)输出结构体
以Debug方式打印结构体,需要实现Debug特性。
实例
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!("rect1 is {:?}", rect1);
}
输出一整个结构体:
rect1 is Rectangle { width: 30, height: 50 }
(二)访问结构体实例的元素
1.只读访问
使用元素访问符,也就是点号 ( . )
语法格式如下
struct_name_instance.field_name
范例
struct Employee {
name: String,
company: String,
age: u32
}
fn main() {
let emp1 = Employee {
company:String::from("TutorialsPoint"),
name:String::from("Mohtashim"),
age:50
};
println!("Name is :{} company is {} age is {}", emp1.name, emp1.company, emp1.age);
}
编译运行结果如下
Name is :Mohtashim company is TutorialsPoint age is 50
2.修改结构体实例的字段
添加 mut 关键字,让它变成可修改的。
范例
struct Employee {
name:String,
company:String,
age:u32
}
fn main() {
let mut emp1 = Employee {
company:String::from("TutorialsPoint"),
name:String::from("Mohtashim"),
age:50
};
emp1.age = 40;
println!("Name is :{} company is {} age is {}", emp1.name, emp1.company, emp1.age);
}
编译运行结果如下
Name is :Mohtashim company is TutorialsPoint age is 40
(三)结构体作为函数的参数
例子
//定义一个结构体
struct Employee {
name:String,
company:String,
age:u32
}
fn main() {
//初始化结构体
let emp1 = Employee {
company:String::from("TutorialsPoint"),
name:String::from("Mohtashim"),
age:50
};
let emp2 = Employee{
company:String::from("TutorialsPoint"),
name:String::from("Kannan"),
age:32
};
//将结构体作为参数传递给display
display(emp1);
display(emp2);
}
fn display( emp: Employee){
println!("Name is :{} company is {} age is {}", emp.name, emp.company, emp.age);
}
编译运行结果如下
Name is :Mohtashim company is TutorialsPoint age is 50
Name is :Kannan company is TutorialsPoint age is 32
(四)结构体实例作为函数的返回值
语法格式
struct My_struct {}
fn function_name([parameters]) -> My_struct {
// 其它的函数逻辑
return My_struct_instance;
}
范例
fn main() {
let emp1 = Employee{
company:String::from("TutorialsPoint"),
name:String::from("Mohtashim"),
age:50
};
let emp2 = Employee {
company:String::from("TutorialsPoint"),
name:String::from("Kannan"),
age:32
};
let elder = who_is_elder(emp1,emp2);
println!("elder is:");
display(elder);
}
//接受两个Employee的实例作为参数并返回年长的那个
fn who_is_elder (emp1:Employee,emp2:Employee)->Employee {
if emp1.age>emp2.age {
return emp1;
} else {
return emp2;
}
}
// 显示结构体的所有元素
fn display( emp: Employee) {
println!("Name is :{} company is {} age is {}",emp.name,emp.company,emp.age);
}
// 定义一个结构体
struct Employee {
name:String,
company:String,
age:u32
}
编译运行结果如下
elder is:
Name is :Mohtashim company is TutorialsPoint age is 50
关联函数是与一个类型相关联的函数。相当于成员函数。
如果关联函数的第一个参数名为 self,则此关联函数称为方法。
方法和函数的区别就是,方法是用来操作结构体实例的,而函数则不是。
为了方便,我们称方法为成员方法,关联函数我们称为成员函数。
(一)定义
1.成员方法
如果你学习过一些面向对象的语言,那你一定很清楚函数一般放在类定义里并在函数中用this表示所操作的实例。
结构体方法的第一个参数必须是 &self,不需指定类型,因为self是关键字。
与 C++不同的是,Rust中的结构体方法只能定义在结构体的外面。
使用 impl 关键字定义结构体,语法格式如下
struct My_struct {}
impl My_struct {
// 定义一个方法
fn method_name(&self[,other_parameters]) {
//方法的具体逻辑代码
}
}
结构体impl块可以写多次,效果相当于它们内容的拼接
结构体方法内部访问结构体字段
使用 self. 来访问结构体的元素。
例子
struct My_struct {
age: u32
}
impl My_struct {
//定义一个方法
fn method_name([other_parameters]) {
self.age = 28;
println!("{}",self.age);
//其它的具体逻辑代码
}
}
2.成员函数
成员函数没有 &self参数。
语法格式如下
impl Structure_Name {
fn method_name(param1: datatype, param2: datatype) -> return_type {
// 方法内部逻辑
}
}
例子
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn create(width: u32, height: u32) -> Rectangle {
Rectangle { width, height }
}
}
fn main() {
let rect = Rectangle::create(30, 50);
println!("{:?}", rect);
}
运行结果:
Rectangle { width: 30, height: 50 }
(二)调用
1.调用成员方法
方法可以使用方法调用操作符(.)来调用
语法格式为
My_struct.method_name([other_parameters])
注意,在调用结构体方法的时候不需要填写self,这个参数的传递Rust编译器会 偷偷的 帮我们完成。
实例
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!("rect1's area is {}", rect1.area());
}
输出结果:
rect1's area is 1500
2.调用成员函数
直接通过结构体名调用,而无需实例。
使用路径来调用
语法格式如下
structure_name::method_name(v1,v2)
范例
//声明结构体Point
struct Point {
x: i32,
y: i32,
}
impl Point {
fn get_instance(x: i32, y: i32) -> Point {
Point { x: x, y: y }
}
fn display(&self){
println!("x ={} y={}",self.x,self.y );
}
}
fn main(){
let p1 = Point::get_instance(10,20);
p1.display();
}
编译运行结果如下
x =10 y=20