首页 > 其他分享 >Rust简易入门(二)

Rust简易入门(二)

时间:2024-03-30 16:46:23浏览次数:22  
标签:入门 self number 简易 let fn str println Rust

Rust内存管理模型

img

"Stop the world'"是与垃圾回收(Garbage Collection)相关的术语,它指的是在进行垃圾回收时系统暂停程序的运行。这个术语主要用于描述一种全局性的暂停,即所有应用线程都被停止,以便垃圾回收器能够安全地进行工作。这种全局性的停止会导致一些潜在的问题,特别是对于需要低延迟和高性能的应用程序。

C/C++内存错误大全

  1. 内存泄漏

  2. 悬空指针

  3. 重复释放

  4. 数组越界

  5. 野指针

  6. 使用已经释放的内存

  7. 堆栈溢出

  8. 不匹配的new/delete malloc/free


Rust

  1. 所有权机制

  2. 借用(Borrowing)

  • 不可变引用

  • 可变引用

  1. 生命周期

  2. 引用计数

// 唯一输入和唯一输出不需要标注生命周期
fn first_world(s: &str) -> &str{
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate(){
        if item == b' '{
            return &s[0..i]
        }
    }
    &s[..]
}

fn main(){
    let s = "hello world";
    println!("{}", first_world(s))
}

String 和 &str

String是一个堆分配的可变字符串类型,具有所有权

pub struct String { vec:Vec<u8>, }

&str是指字符串切片引用,是在栈上分配的,不具备所有权
不可变引用,指向存储在其他地方的UTF-8编码的字符串数据
由指针和长度构成

Struct中属性使用String

  • 如果不使用显式声明生命周期无法使用&str

  • 不只是麻烦,还有更多的隐患

函数参数推荐使用&str(如果不想交出所有权)

  • &str为参数,可以传递&str和&String

  • &String为参数,只能传递&String不能传递&str

struct Person<'a>{
    name: &'a str,
    color: String,
    age: i32,
}

// &str &string
fn print(data: &str) {
    println!("{data}");
}

// 只能传&string
fn print_string_borrow(data: &String){
    println!("{data}");
}

fn main(){
    let name = String::from("Value C++");
    // String::from
    // to_string()
    // to_owned()
    let course = "Rust".to_string();
    let new_name = name.replace("C++", "CPP");
    println!("{name} {course} {new_name}");
    let rust = "\x52\x75\x73\x74";  // ascii
    println!("{rust}");
    
    let color = "yellow".to_string();
    let name = "111";
    let people = Person{
        name: name,
        color: color,
        age: 18,
    };
    
    // func
    let value = "value".to_string();
    print(&value);
    print("data");
    print_string_borrow(&value);
    
}

枚举与匹配模式

枚举(enums)是一种用户自定义的数据类型,用于表示具有一组离散可能值的变量

  • 每种可能值都称为"variant"(变体)

  • 枚举名::变体名

枚举的好处

  • 可以使你的代码更严谨、更易读

  • More robust programs

枚举内嵌类型

enum shape{
    Circle(f64),
    Rectangle(f64, f64),
}

常见的枚举类型

pub enum Option<T>{
    None,
    Some<T>,
}

pub enum Result<T, E>{
    Ok<T>,
    Err(E),
}

匹配模式

  1. match关键字实现

  2. 必须覆盖所有的变体

  3. 可以使用_、..=、三元(if)等来进行匹配

match number {
    0 => println!("Zero"),
    1|2 => println!("One or Two"),
    3..=9 => println!("From Three to Nine"),
    n if n % 2 == 0 => println!("Even number"),
    _ => println!("Other"), 
}
enum Color {
    Red,
    Yellow,
    Green,
}

fn print_color(my_color: Color){
    match my_color {
        Color::Red => println!("Red"),
        Color::Yellow => println!("Yellow"),
        Color::Green => println!("Green"),
    }
}

enum BuildingLocation {
    Number(i32),
    Name(String),
    Unknown,
}

impl BuildingLocation {
    fn print_location(&self){
        match self {
            BuildingLocation::Number(c) => println!("Building Number {c}"),
            BuildingLocation::Name(s) => println!("Building Name {s}"),
            BuildingLocation::Unknown => println!("unknown"),
        }
    }
}

fn main(){
    let a = Color::Red;
    print_color(a);
    let house = BuildingLocation::Name("111".to_string());
    house.print_location();
}

结构体、方法、关联函数、关联变量

  1. 结构体

结构体是一种用户定义的数据类型,用于创建自定义的数据结构

struct Point { x: i32, y: i32, }

每条数据 (x 和 y) 称为属性(字段field)
通过点(.)来访问结构体中的属性

  1. 结构体中的方法

这里的方法是指,通过实例调用(&self、&mut self、self)

impl Point { fn distance(&self, other:&Point) → f64 { let dx (self.x - other.x) as f64; let dy (self.y - other.y) as f64; (dx * dx + dy *dy).sqrt() } }

  1. 结构体中的关联函数

关联函数是与类型相关联的函数,调用时为结构体名::函数名

impl Point{ fn new(x: u32, y: u32) → Self { Point {x, y} } }

  1. 结构体中的关联变量

这里的关联变量是指,和结构体类型相关的变量,也可以在特质或是枚举中
impl Point { const PI: f64 = 3.14 }
调用时使用 Point::PI

enum Flavor{
    Spicy,
    Sweet,
    Fruity,
}

struct Drink{
    flavor: Flavor,
    price: f64,
}

impl Drink {
    // 关联变量
    const MAX_PRICE: f64 = 10.0;
    
    // 方法
    fn buy(&self){
        if self.price > Self::MAX_PRICE {
            println!("I am poor");
            return ;
        }
        println!("buy it");
    }
    
    // 关联函数
    fn new(price: f64) -> Self {
        Drink {
            flavor: Flavor::Fruity,
            price,
        }
    }
}

fn print_drink(drink: Drink){
    match drink.flavor {
        Flavor::Fruity => println!("fruity"),
        Flavor::Spicy => println!("spicy"),
        Flavor::Sweet => println!("sweet"),
    }
    println!("{}", drink.price);
}

fn main(){
    let sweet = Drink {
        flavor: Flavor::Sweet,
        price: 6.0
    };
    println!("{}", sweet.price);
    
    let sweet = Drink::new(16.0);
    sweet.buy();
}

Ownership与结构体

  1. Each value in Rust has an owner

  2. There can only be one owner at a time

  3. Values are automatical ly dropped when the owner goes out of scope

每当将值从一个位置传递到另一个位置时,borrow checker都会重新评估所有权。

  1. Immutable Borrow使用不可变的借用,值的所有权仍归发送方所有,接收方直接接收对该值的引用,而不是该值的副本。但是,他们不能使用该引用来修改它指向的值,编译器不允许这样做。释放资源的责任仍由发送方承担。仅当发件人本身超出范围时,才会删除该值

  2. Mutable Borrow使用可变的借用所有权和删除值的责任也由发送者承担。但是接收方能够通过他们接收的引用来修改该值。

  3. Move这是所有权从一个地点转移到另一个地点。borrow checker关于释放该值的决定将由该值的接收者(而不是发送者)通知。由于所有权已从发送方转移到接收方,因此发送方在将引用移动到另一个上下文后不能再使用该引用,发送方在移动后对vlaue的任何使用都会导致错误。

结构体中关联函数的参数

img

struct Counter {
    number: i32,
}

impl Counter {
    fn new(number: i32) -> Self {
        Self { number }
    }

    // 不可变借用
    fn get_number(&self) -> i32 {
        self.number
    }

    // 不可变借用
    fn add(&mut self, increment: i32) {
        self.number += increment;
    }

    // move
    fn give_up(self) {
        println!("{}", self.number);
    }
    
    // move
    fn combine(c1: Self, c2: Self) -> Self {
        Self{
            number: c1.number + c2.number,
        }
    }
}

fn main() {
    let mut c1 = Counter::new(0);
    println!("{}", c1.get_number());
    c1.add(2);
    println!("{}", c1.get_number());
}

堆与栈、Copy与Move

stack

  1. 堆栈将按照获取值的顺序存储值,并以相反的顺序删除值

  2. 操作高效,函数作用域就是在栈上

  3. 堆栈上存储的所有数据都必须具有已知的固定大小数据

heap

  1. 堆的规律性较差,当你把一些东西放到你请求的堆上时,你请求,请求空间,
    并返回一个指针,这是该位置的地址

  2. 长度不确定

Box

Box是一个智能指针,它提供对堆分配内存的所有权。它允许你将数据存储在堆上而不是栈上,并且在复制或移动时保持对数据的唯一拥有权。使用Box可以避免一些内存管理问题,如悬垂指针和重复释放。

  1. 所有权转移

  2. 释放内存

  3. 解引用

  4. 构建递归数据结构

struct Point {
    x: i32,
    y: i32,
}

fn main(){
    let box_point = Box::new(Point{x:10, y:20});
    println!("x:{}, y:{}", box_point.x, box_point.y);
    
    let mut box_point = Box::new(32);
    *box_point += 10;
    println!("{}", box_point);
}

Copy与Clone

Move:所有权转移
Clone:深拷贝
Copy:Copy是在CIone的基础建立的marker trait(Rust中最类似继承的关系)

  1. trait(特质)是一种定义共享行为的机制。Clone也是特质

  2. marker trait是一个没有任何方法的trait,它主要用于向编译器传递某些信息,以改变类型的默认行为

标签:入门,self,number,简易,let,fn,str,println,Rust
From: https://www.cnblogs.com/moguw/p/18105693

相关文章

  • Rust简易入门(三)
    Rust的流程控制主要包括条件语句(if、else、elseif)、循环语句(for、while)和跳转语句(break、continue、return)。这些语句使程序员能够根据特定的条件或循环执行代码块,从而实现各种复杂的逻辑控制。例如,if语句允许程序员根据条件执行代码,而for和while循环则用于重复执行代码块,直到满......
  • 数学入门——均值不等式 学习笔记
    数学入门——均值不等式学习笔记简化形式若\(a,b>0\),则:\[\dfrac{2}{\dfrac{1}{a}+\dfrac{1}{b}}\le\sqrt[2]{ab}\le\dfrac{a+b}{2}\le\sqrt[2]{\dfrac{a^2+b^2}{2}}\]理解方式:https://www.bilibili.com/video/BV1Nf4y1G7xV基本形式若\(a,b>0\),则:\[\dfrac{n}{\dfrac{......
  • 天体力学——天体运动入门 学习笔记
    天体力学——天体运动入门学习笔记一、开普勒三大定律开普勒第一定律(椭圆定律、轨道定律)行星绕太阳的轨迹是椭圆轨道,太阳在椭圆的一个焦点上。开普勒第二定律(等面积定律)在相等时间内,行星与太阳的连线扫过的面积相等。结论:近日点速度较大,远日点速度较小。开普勒第三定律(周......
  • Rust简易入门(一)
    Rust!Rust!Rust!变量与不可变性在Rust中,变量使用let关键字进行声明Rust支持类型推导,也可以显示指定变量类型变量名采用蛇形命名法,枚举结构体采用帕斯卡命名法,没有使用的变量采用前置下划线_以消除警告强制类型转换关键词as打印变量println!("val:{}",x);print......
  • Vue+OpenLayers7入门到实战:OpenLayers涂鸦手绘线条、圆形和多边形,涂鸦线条自动收尾连
    返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7入门到实战前言本章介绍如何使用OpenLayers7在地图上进行绘制图形的功能,上一章中《Vue+OpenLayers7入门到实战:OpenLayers图形绘制功能,OpenLayers实现在地图上绘制线段、圆形和多边形》我们已经讲过多种图形的绘制,本章主要......
  • python入门教程(非常详细),从零基础入门到精通,看完这一篇就够了
    前言本文罗列了了python零基础入门到精通的详细教程,内容均以知识目录的形式展开。01.python由来与发展介绍02.项目开发流程第一章markdown编辑器01.markdown基本语法02.Typora简介与安装03.Windows上gitee+Typora设置图床04.macOS上gitee+Typora设置图床第二章计......
  • 嵌入式开发学习笔记1——keil软件入门
    学习笔记(2024.3.30)引言从对几个问题的思考入手:1、keil是什么?干什么用的?有什么优点?2、keil从哪里下载?怎么安装?3、keil学习路线图怎么比较合理?学习的顺序?4、怎么快速用起来?1、keil是什么?干什么用的?有什么优点?keil软件介绍Keil是一款单片机开发环境,主要研发8051微控制器......
  • Kubernetes超详细教程,一篇文章帮助你从零开始学习k8s,从入门到实战
    k8s概述k8sgithub地址:https://github.com/kubernetes/kubernetes官方文档:https://kubernetes.io/zh-cn/docs/home/k8s,全程是kubernetes,这个名字源于希腊语,意为"舵手"或"飞行员”k8s这个缩写是因为k和s之间有八个字符Google在2014年开源了k8s项目,k8s是一个......
  • SVG XML 格式定义图形入门介绍
    SVGSVGmeansScalableVectorGraphics.SVG使用XML格式定义图形SVG图像在放大或改变尺寸的情况下其图形质量不会有所损失SVG是万维网联盟的标准HelloWorldUseSVGinhtmlandyoucansee:LinktotheSVGfileYoucanuse<a>tagtolinktothes......
  • 1.java openCV4.x 入门-环境搭建
    专栏简介......