前言
阅读耗时2分钟,基础语法,重要的是后面的泛型以及生命周期,还有单元测试的编写
目录
一、切片
不持有所有权的数据类型
例如找某个数据在字符串下的下标
fn main() {
let mut s = String::from("Hello Rust!");
let wordIndex = find_test(&s);
println!("{} ", wordIndex);
}
fn find_test(s: &String) -> usize{
let bytes = s.as_bytes();
for(i, &item) in bytes.iter().enumerate(){
if( item == b' '){
return i;
}
}
s.len()
}
换成切片写法,返回字符串
fn main() {
let mut s = String::from("Hello Rust!");
let s2 = find_test2(&s);//这块借用成了 一个不可变引用
// s.clear(); //同一时刻不能存在可变和不可变的引用,可变引用才能清楚
println!("{} ", s2);
}
fn find_test2(s: &String) -> &str{
let bytes = s.as_bytes();
for(i, &item) in bytes.iter().enumerate(){
if( item == b' '){
return &s[0..i];
}
}
&s[..]
}
二、结构体
和C++ 一样,直接上例子
定义
struct User{
username: String,
email: String,
age: i32,
}
struct Rectangle{
width:u32,
length:u32,
}
使用
fn main() {
let user1 = User{
username:String::from("xxx"),
email: String::from("abc@163.com"),
age:20,
};
//user1.email = String::from("abc@qq.com");//访问报错,必须申明 可变才能修改
println!("email = {}", user1.email );
let user2 = User{
username:String::from("xxx"),
..user1
};
let rect = Rectangle{
width:50,
length : 30,
};
println!("Rectangle Area is {}", area(&rect));
}
fn area(rect: &Rectangle) -> u32{
rect.width * rect.length
}
struct Rectangle{
width:u32,
length:u32,
}
tuple struct
fn main() {
let balck = Color(0,1,0);
println!("color {}", balck.1);
}
struct Color(i32, i32,i32);
所有权
fn main() {
let user1 = User{
username:String::from("xxx"),
email: String::from("abc@163.com"),
age:20,
};
}
还是通过之前的例子说明,user1 实例持有内部所有属性的所有权,只有user1 是有效的,内部字段都是有效的,包括内部字段是引用
struct 方法
利用impl 为struct 添加方法,改造一下计算矩形面积示例
fn main() {
let rect = Rectangle{
width:50,
length : 30,
};
println!("Rectangle Area is {}", rect.area());
}
struct Rectangle{
width:u32,
length:u32,
}
impl Rectangle{
fn area(&self) -> u32{
self.width * self.length
}
}
方法的第一个参数都是&self 自身传入。毕竟要用到自身的属性,如果不想用自身属性,那么可以使用关联函数,如下
fn main(){
let r = Rectangle::square(20);
}
impl Rectangle{
fn area(&self) -> u32{
self.width * self.length
}
fn square(size: u32) -> Rectangle{
Rectangle { width: size, length:size }
}
}
特别的toString打印
我们在Java中,直接toString()复写,就能打印出所有实例属性,那么rust中怎么操作呢?
假如我们想打印出Rectangle 中的属性数据
fn main(){
let rect = Rectangle{
width:50,
length : 30,
};
println!("{:?}", rect);
println!("{:#?}", rect);
}
#[derive(Debug)]
struct Rectangle{
width:u32,
length:u32,
}
输出:
Rectangle { width: 50, length: 30 }
Rectangle {
width: 50,
length: 30,
}
结构体上加上 #[derive(Debug)] 标记,并且使用{:?} 模式或者 可以格式化的模式 {:#?}
三、枚举
定义
enum IpType{
V4,
V6,
}
enum IpTypeAndValue{
V4(u8, u8, u8, u8),
V6(String),
}
示例
fn main()
let v4 = IpType::V4;
route(v4);
let v4Value = IpTypeAndValue::V4(127, 0 , 0 ,1);
let v6Value = IpTypeAndValue::V6(String::from("::1"));
}
fn route(ip_type: IpType){
}
枚举方法
和 struct一样,也能添加方法
impl IpTypeAndValue {
fn call(&self){
println!("枚举 call调用");
}
}
Option枚举
为什么会有Option? 因为Rust中没有Null,不像c++中 有NULL和 nullptr
Option在标准库中已经定义好了
pub enum Option<T> {
/// No value.
#[lang = "None"]
#[stable(feature = "rust1", since = "1.0.0")]
None,
/// Some value of type `T`.
#[lang = "Some"]
#[stable(feature = "rust1", since = "1.0.0")]
Some(#[stable(feature = "rust1", since = "1.0.0")] T),
}
如何使用呢?
fn main() {
let some1 = Some(1);
let some2 = Some("Exception");
let none :Option<i32> = None;
if let Some(1) = some1{
println!("find");
}else{
println!("not find");
}
match some1{
Option::Some(i) => {
println!("option 中的值是 {}", i);
},
_ => {
println!("no value");
},
}
let temp = convert(some1);
}
//注意使用match时,需要穷举所有可能性
fn convert(x: Option<i32>) -> Option<i32>{
match x {
None => None,
Some(i) => Some(i+1),
}
}
fn convert2(x: Option<i32>) -> Option<i32>{
match x {
Some(i) => Some(i+1),
_ => None, //通配符,类似else
}
}
//输出
//find
//option 中的值是 1