Rust入门(一)_开发环境配置及格式化

配置开发环境

安装rust

因为我准备使用RustRover开发,所以选择在windows下配置rust环境。

在 Windows 上,前往官网 https://www.rust-lang.org/install.html 安装 Rust。

在这里插入图片描述
在这里插入图片描述

打开按流程安装就好

在这里插入图片描述

安装过程的某个步骤,会被提示要安装 Visual Studio,按要求安装就行。

安装好以后打开终端用rustc --verson检查一下

如果安装完成但是终端识别不到rustc指令,就重启一下终端或者手动配置系统环境变量再重启终端。

出现这样的画面就是安装好了

在这里插入图片描述

安装RustRover

去官网下载https://www.jetbrains.com/rust/,因为RustRover的个人非商用版免费,所以也不需要找破解版,正常使用就行。
安装及常见问题细节建议参照这篇博客
https://blog.csdn.net/tg928600774/article/details/133134741

教程

我使用的教程是这两个

Rust中文手册(更对新手友好一些)
https://kaisery.github.io/trpl-zh-cn/title-page.html

通过例子学Rust
https://rustwiki.org/zh-CN/rust-by-example/hello/print/fmt.html

rustc和cargo

rustc

Rust 源文件总是以 .rs 扩展名结尾。而rustc是rust的官方编译器,效果类似gcc吧。

main.rs

fn main() {
    println!("Hello, world!");
}
> rustc main.rs
> .\main
Hello, world!

cargo

cargo是rust的系统构建和包管理器
详见https://kaisery.github.io/trpl-zh-cn/ch01-03-hello-cargo.html

格式化

格式化输出

打印操作由 std::fmt 模块里面所定义的一系列宏来处理

std::fmt 包含多种 trait(特质)来控制文字显示,其中重要的两种 trait 的基本形式如下:

fmt::Debug:使用 {:?} 标记。格式化文本以供调试使用。
fmt::Display:使用 {} 标记。以更优雅和友好的风格来格式化文本。

fmt::Display

fmt::Display 采用 {} 标记。
下面是常见用法示例:

fn main(){
    // 通常情况下,`{}` 会被任意变量内容所替换。
    // 变量内容会转化成字符串。
    println!("{} days",31);

    // 不加后缀的话,31 就自动成为 i32 类型。
    // 你可以添加后缀来改变 31 的类型(例如使用 31i64 声明 31 为 i64 类型)。

    // 用变量替换字符串有多种写法。
    // 比如可以使用位置参数。
    println!("{0},this is {1}. {1},this is {0}","Alice","Bob");

    // 可以使用命名参数。
    println!("{a},{b},{c}",a="A",b="B",c="C");

    // 可以在 `:` 后面指定特殊的格式。
    println!("{} of {:b} people know binary, the other half don't", 1, 2);

    // 你可以按指定宽度来右对齐文本。
    // 下面语句输出 "|     1|",5 个空格后面连着 1。
    println!("|{number:>width$}|", number=1, width=6);

    // 你可以在数字左边补 0。下面语句输出 "000001"。
    println!("{number:>0width$}", number=1, width=6);

}

填充输出语句

    // 你可以在数字左边补 0。下面语句输出 "000001"。
    println!("{number:>0width$}", number=1, width=6);

在 Rust 的格式化语法中,0 是一个特殊的填充标记,用于指定当输出内容长度不足指定宽度时的填充字符。如果尝试将 0 换成其他数字(比如 1、2 等),会导致编译错误,这是由 Rust 格式化语法的规则决定的。

如果想使用 0 以外的字符(比如字母、符号或其他数字)作为填充符,需要在宽度前直接指定该字符,且该字符必须是非数字(因为数字会被解析为宽度的一部分)。

例如用*填充
println!("{number:>*width$}", number=1, width=6); // 输出:*****1

控制浮点数位数

    let pi = 3.1415926;
    println!("Pi is roughly {0:.1$}",pi,3)

注意用{:}指定特殊格式时,如果用到格式化语句中的参数,后面要加$

fmt::Debug

所有的类型(就是数据结构),若想用 std::fmt 的格式化打印,都要求实现至少一个可打印的 traits。仅有一些类型提供了自动实现,比如 std 库中的类型。所有其他类型都必须手动实现。

fmt::Debug 这个 trait 使这项工作变得相当简单。所有类型都能推导(derive,即自动创建)fmt::Debug 的实现。(但是 fmt::Display 需要手动实现)

说人话就是,想要对数据结构进行格式化打印,大多数情况下都必须手动为具体类型编写 trait 所要求的方法代码,使该类型具备 trait 定义的能力。但是fmt::Debug这个trait,就可以通过#[derive(Debug)] 注解,让编译器自动生成 Debug 的实现,进行输出。

模块,trait,结构体和实现(impl)的关系

结构体
是“具体实体”,用来封装数据。比如现实中的 “狗”“猫” 是具体的动物,在代码中可以用结构体表示它们的属性(名字、年龄等)。

例:
// 结构体:表示"狗"这个实体,包含它的属性
struct Dog {
name: String,
age: u32,
}

// 结构体:表示"猫"这个实体
struct Cat {
name: String,
age: u32,
}


Trait
可以理解为 “行为规范 / 技能”,定义能做什么(方法声明),但不规定具体怎么做。比如 “会叫” 是一种行为,狗和猫都有这个行为,但具体叫的方式不同(汪汪 vs 喵喵)。

例:
// Trait:定义"会叫"这个行为规范(只声明方法,不实现)
trait Speak {
fn speak(&self); // 所有实现这个trait的实体,都必须有"叫"的方法
}


实现(impl)
给结构体 “绑定具体行为” 的过程。也就是为结构体实现 trait 中定义的方法(告诉编译器 “这个实体具体怎么完成这个行为”),或者给结构体添加它自己独有的方法。

例:
// 为Dog实现Speak trait:具体定义"狗怎么叫"
impl Speak for Dog {
fn speak(&self) {
println!(“{}(狗)汪汪叫!”, self.name); // 具体实现
}
}
// 为Cat实现Speak trait:具体定义"猫怎么叫"
impl Speak for Cat {
fn speak(&self) {
println!(“{}(猫)喵喵叫!”, self.name); // 具体实现
}
}
// 还可以给结构体添加独有的方法(不依赖trait)
impl Dog {
fn wag_tail(&self) { // 狗独有的"摇尾巴"方法
println!(“{}摇了摇尾巴~”, self.name);
}
}


模块(Module)
可以理解为 “分类文件夹”,用来组织相关的代码(结构体、trait、实现等),避免命名混乱。比如把所有动物相关的代码放在一个animal模块里,方便管理。


#![allow(unused)]
fn main() {
// 这个结构体不能使用 `fmt::Display` 或 `fmt::Debug` 来进行打印。
struct UnPrintable(i32);

// `derive` 属性会自动创建所需的实现,使这个 `struct` 能使用 `fmt::Debug` 打印。
#[derive(Debug)]
struct DebugPrintable(i32);
}

尽管使用fmt::Debug可以方便快捷地查看程序输出,但会牺牲掉很大一部分显示效果,Rust也为fmt::Debug提供了{:#?}改善部分显示效果,如果希望控制程序输出的显示效果,还是需要手动实现,并使用fmt::Display

示例代码:

#[derive(Debug)]
struct Person<'a>{
    name:&'a str,
    age:u8
}

fn main(){

    let name = "Peter";
    let age = 27;
    let peter = Person{name ,age };

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

}

输出:

Person { name: "Peter", age: 27 }

改用{:#?}

println!("{:#?}",peter);

输出:

Person {
    name: "Peter",
    age: 27,
}

格式化和安全

我们已经看到,格式化的方式是通过格式字符串来指定的。

格式化的功能是通过 trait 实现的,每种参数类型都对应一种 trait。最常见的格式化 trait 就是 Display,它可以处理参数类型为未指定的情况,比如 {}

在Rust中,格式化字符串和格式化字符串的参数一一对应,避免了非法读写的格式化字符串漏洞风险。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值