首页 > 其他分享 >复合类型

复合类型

时间:2023-08-16 23:22:17浏览次数:31  
标签:String i32 复合 切片 字符串 let 类型 string

字符串和切片

切片

切片的作用是允许你引用集合中部分连续的元素序列,而不是引用整个集合。

例如:

let s = String::from("hello world");

let hello = &s[0..5];  // 切片 [0,5)  等效于&s[..5]
let world = &s[6..11];  // 切片 [6,11) 等效于&s[6..]
// 完整的s,&s[..]

注意,方括号中的数字是字节,如果字符是多字节的(如汉字),这时如果切片没有落在两个字符之间,程序就会崩溃(汉字是三个字节,切片0-2就会崩溃)

字符串的切片类型是 &str,i32数组的切片类型是 &[i32]

这样一段代码:let s = "Hello world!";, s 是个切片类型,实际上代码为:let s: &str = "Hello world!"

字符串

Rust中字符是 Unicode 类型。内存占用 从1 - 4 个字节空间。

Rust中常用的字符串类型有 str / String,str硬编码不可变,String可变。

// &str --> String
String::from("Hello world");
"hello world".to_string();

// String --> &str
&s;

操作字符串

let mut s = String::from("Hello ");
// 追加字符串
s.push_str("rust");
// 追加字符
s.push('!');
// 插入字符
s.insert(5, ',');
// 插入字符串
s.insert_str(6, " I like");

// 替换
// replace 适用于 String 和 &str,替换所有,返回一个新字符串,而不是操作原来的字符串
let new_string_replace = string_replace.replace("rust", "RUST");
// replacen 适用于 String 和 &str, 替换指定个数,返回一个新字符串,而不是操作原来的字符串
let new_string_replacen = string_replace.replacen("rust", "RUST", 1);
// replace_range 适用于 String,替换指定范围字符串,操作原来的字符串
string_replace_range.replace_range(7..8, "R");

// 删除
// 均是操作原来的字符串
// pop 删除并返回最后一个字符
let p1 = string_pop.pop();
// remove 删除并返回指定位置字符
string_remove.remove(0);
// truncate 删除指定位置到结尾
string_truncate.truncate(3);
// clear 清空字符串
string_clear.clear();

// 连接
// + += ,右面必须是字符串的切片引用类型,相当于调用std::string add(),返回一个新字符串
let result = string_append + &string_rust;
// format! 
let s = format!("{} {}!", s1, s2);

遍历字符串

// 以 unicode 字符方式遍历字符串
for c in "中国人".chars() {
    println!("{}", c);
}

元组

元组是由多种类型组合到一起形成的,因此它是复合类型,元组的长度是固定的,元组中元素的顺序也是固定的。

fn main() {
    let tup: (i32, f64, u8) = (500, 6.4, 1);
}

使用元组:

fn main() {
    let tup = (500, 6.4, 1);
    
	// 模式匹配
    let (x, y, z) = tup;
    println!("The value of y is: {}", y);
    
    // .
    let five_hundred = x.0;
    let six_point_four = x.1;
    
    // 函数
    let s1 = String::from("hello");
    let (s2, len) = calculate_length(s1);
}

fn calculate_length(s: String) -> (String, usize) {
    let length = s.len(); // len() 返回字符串的长度
    (s, length)
}

结构体

使用

结构体的定义:

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}

结构体的创建和使用:

// 每个都需要初始化,顺序可以打乱
let mut user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

// 访问字段,
// **必须要将结构体实例声明为可变的,才能修改其中的字段,Rust 不支持将某个结构体某个字段标记为可变。**
user1.email = String::from("anotheremail@example.com");

// 简化创建
fn build_user(email: String, username: String) -> User {
    User {
        email,
        username,
        active: true,
        sign_in_count: 1,
    }
}

// 更新
let user2 = User {
    email: String::from("another@example.com"),
    ..user1  // 注意 username 发生了所有权转移,不能再被user1使用
};

内存排列

struct File {
    name: String,
    data: Vec<u8>,
}

内存结构:

元组结构体

元组结构体的字段没有名称:

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);

使用的使用可以直接用 x,y,z / r,g,b

单元结构体

单元结构体没有任何字段和属性

struct AlwaysEqual;

let subject = AlwaysEqual;

// 我们不关心 AlwaysEqual 的字段数据,只关心它的行为,因此将它声明为单元结构体,然后再为它实现某个特征
impl SomeTrait for AlwaysEqual {

}

结构体的所有权

如果你想在结构体中使用一个引用,就必须加上生命周期,否则就会报错!

生命周期篇再写。

打印

  • 使用 #[derive(Debug)] 来打印结构体信息。

    println!("{:?}",struct);

    dbg!(&struct);

  • 也可以实现 Display 特征打印信息(类似 toString() 方法)

    println!("{}",struct);

枚举

使用:

可以向其他语言一样直接使用,也可以为其关联数据信息

// enum PokerSuit {
//   Clubs,
//   Spades,
//   Diamonds,
//   Hearts,
// }

enum PokerCard {
    Clubs(u8),
    Spades(u8),
    Diamonds(u8),
    Hearts(u8),
}

fn main() {
   let c1 = PokerCard::Spades(5);
   let c2 = PokerCard::Diamonds(13);
}

更为复杂的:

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let m1 = Message::Quit;
    let m2 = Message::Move{x:1,y:1};
    let m3 = Message::ChangeColor(255,255,0);
}

使用Option枚举处理空值

在rust中使用Option枚举来处理对象为空的情况(null):

enum Option<T> {
    Some(T),
    None,
}

使用的使用将值存入 Some<T> 中,这样在使用变量的时候因为不能直接使用 Option,所以需要将值取出来再用。而取出来的时候需要判断值不是Option::None才能用,相当于变相强制进行了判空操作,放置了空指针异常。

数组

在Rust中有两种数组,一种是长度固定吗,速度快的 array,一种是长度动态,性能较低的 vector。

array存储在栈上,vector存储在堆上。

array

使用:

fn main() {
    // 1.定义
    // let a: [i32; 5] = [1, 2, 3, 4, 5];  声明类型
    let a = [1, 2, 3, 4, 5];
    // 重复:5个3
    let a = [3; 5]; 
    // 非基础元素
    // let array = [String::from("rust is good!"); 8];  ×  不能深拷贝
    let array: [String; 8] = std::array::from_fn(|i| String::from("rust is good!"));
    
    // 2.访问
    let first = a[0]; // 获取a数组第一个元素
}

数组切片

  • 创建切片的代价非常小,因为切片只是针对底层数组的一个引用
  • 切片类型[T]拥有不固定的大小,而切片引用类型&[T]则具有固定的大小,因为 Rust 很多时候都需要固定大小数据类型,因此&[T]更有用,&str字符串切片也同理
let a: [i32; 5] = [1, 2, 3, 4, 5];

let slice: &[i32] = &a[1..3];  // 引用

assert_eq!(slice, &[2, 3]);

标签:String,i32,复合,切片,字符串,let,类型,string
From: https://www.cnblogs.com/heymeteor/p/17636470.html

相关文章

  • elasticsearch中的数据类型search_as_you_type及查看底层Lucene索引
    search_as_you_type字段类型用于自动补全,当用户输入搜索关键词的时候,还没输完就可以提示用户相关内容。as_you_type应该是说当你打字的时候。它会给索引里的这个类型的字段添加一些子字段_2gram_3gram和_index_prefix。_2gram的意思是,如果一个值是abcd,2gram就是abbccd,3gr......
  • astype方法转换类型
    astype方法转换类型 data=[['0','Y','N'],['1','Y','Y'],['2','N','Y'],['3','Y','Y'],['4','N','N'......
  • C# 的数据类型
    在C#中,变量主要分为三种类型:值类型,引用类型,指针类型1、值类型值类型变量可以直接分配给一个值,直接包含数据(如 int、char、float,它们分别存储数字、字符、浮点数)特点:当声明一个值类型时,系统分配内存来存储值C#中可用的值类型:Java中有8大基本类型,C#中都含有,就是bool与b......
  • GIC入门(一):中断类型,状态转换,中断路由,安全模型
    GIC是ARM的通用中断处理器,和ARMCortex-A和Cortex-R系列CPU搭配使用,M系列使用NVIC(nestedvectoredinterruptcontroller)。本篇文章介绍GICV3、V4的一些基本概念:中断类型,状态转换,中断路由,安全模型 1.InterrupttypesSPI:sharedphripheralinterrupt,可以设置为被所有PE处......
  • python类型标注self
    起因假设有如下代码,我想标注类方法的返回值为自己本身classQueue:def__init__(self):self.items=[]defenqueue(self,item)->Queue:self.items.append(item)returnself用Queue来标注返回值类型,但是呢,运行时Python会报错Traceb......
  • byte类型的数据进行扩大范围
    Java中的整型是有符号的。但是,如果你使用的值不可能是负值,并E实际需要额外一个比特,那么你可以使用将数值翻译成无符号类型的方法。例如,不用范围为-128127的byte类型值,你可能需要的范围为0255的值。你可以将数值存储在byte中,源于二进制运算的本质,某些操作,例如加和减可以工作。对于......
  • elasticsearch中的数据类型:flattened和join
    flattened:比如你有一个字段的值是一个json,这个json里面又有很多字段,你又不想一个一个的定义这些字段到mapping,就可以用flattened直接动手:创建索引:PUTperson{"mappings":{"properties":{"patient_name":{"type":"text"},&......
  • 自定义MarkupExtension的学习,以及WPF中Combobox绑定枚举类型
    我们上一期讲到ComBobox绑定数据,https://www.cnblogs.com/guchen33/p/17630808.html这次我们简单化一下,正常来讲WPF中绑定不了枚举的像这样//前台代码<ComboBoxItemsSource="{BindingMyEnum}"/>//后台VMpublicenumMyEnum{One,Two,Three,Fo......
  • ThingsKit物联网平台产品管理之设备类型
    直连设备直连设备可以直接发布订阅数据。v1/devices/me/telemetry网关设备网关设备等同于直连设备。v1/devices/me/telemetry网关子设备在使用网关MQTT协议时,需要先在ThingsKit平台上为网关和网关子设备绑定关系。对于MQTT网关子设备而言,上报上来的遥测数据,系统会自动创......
  • Python教程(9)——Python变量类型列表list的用法介绍
    (目录)在Python中,列表(list)是一种有序、可变的数据结构,用于存储多个元素。列表可以包含不同类型的元素,包括整数、浮点数、字符串等。实际上列表有点类似C++语言中的数组,但仅仅只是类似,和数组还是有点不一样的。列表非常适合利用顺序和位置定位某一元素,尤其是当元素的顺序或内容经常......