这篇博客是rust入门篇下
45. 生命周期注释
// 生命周期
// 下面代码不能通过编译
// longer 函数取 s1 和 s2 两个字符串切片中较长的一个返回其引用值
// 返回值引用可能会返回过期的引用
// fn longer(s1: &str, s2: &str) -> &str {
// if s2.len() > s1.len() {
// s2
// } else {
// s1
// }
// }
// 生命周期注释
// &i32 // 常规引用
// &'a i32 // 含有生命周期注释的引用
// &'a mut i32 // 可变型含有生命周期注释的引用
fn longer<'a>(s1:&'a str, s2:&'a str)->&'a str{
if s2.len()>s1.len(){
s2
} else {
s1
}
}
fn main(){
let r;
{
let s1 = "rust";
let s2 = "ecmascript";
r = longer(s1, s2);
println!("{} is longer", r);
}
}
46. 生命周期2
结构体中使用字符串切片引用
// 结构体中使用字符串切片引用
fn main(){
struct Str<'a>{
content: &'a str
}
let s = Str{
content: "string_slice"
};
println!("s.content={}", s.content);
}
47. 泛型 特性 和 生命周期的综合例子
// 泛型、特性与生命周期 一起来
use std::fmt::Display;
fn longest_with_an_announcement<'a, T>(x: &'a str, y: &'a str, ann: T)-> &'a str where T: Display{
println!("Announcement! {}", ann);
if x.len() > y.len(){
x
} else{
y
}
}
fn main(){
let r = longest_with_an_announcement("abcd", "efg", "hello");
println!("longest {}", r);
}
48. 接收命令行参数
// 接收命令行参数
fn main(){
let args = std::env::args();
println!("{:?}", args);
// Args { inner: ["target\\debug\\greeting.exe"] }
// 遍历
for arg in args{
// target\debug\greeting.exe
println!("{}", arg);
}
}
49. 从命令行传入字符串
// 命令行输入输入一些字母 IO流
use std::io::stdin;
fn main(){
let mut str_buf = String::new();
// 从命令行输入一些字符
stdin().read_line(&mut str_buf).expect("failed to read line");
println!("your input line is \n{}", str_buf);
}
50. 从文件读入
// 从文件读取字符
use std::fs;
fn main(){
let text = fs::read_to_string("d:/hello.txt").unwrap();
println!("{}", text);
}
51. 读取文件
整个文件一次性读取
// 从文件读取字符
use std::fs;
fn main(){
let content = fs::read("D:/text.txt").unwrap();
println!("{:?}", content);
}
52. IO流
// 流读取
use std::fs::{self, File};
use std::io::prelude::*;
fn main(){
let mut buffer = [0u8; 5];
let mut file = fs::File::open("d:/text.txt").unwrap();
file.read(&mut buffer).unwrap();
println!("{:?}", buffer);
file.read(&mut buffer).unwrap();
println!("{:?}", buffer);
}
53. 文件写入
use std::fs;
fn main(){
// 文件写入
fs::write("d:/text.txt", "FROM RUST PROGRAM").unwrap();
}
54. 文件末尾追加字符
use std::io::prelude::*;
use std::fs::OpenOptions;
fn main()->std::io::Result<()>{
let mut file = OpenOptions::new().append(true).open("d:/text.txt")?;
file.write(b" APPEND WORD");
Ok(())
}
55. 读写方式打开文件
use std::io::prelude::*;
use std::fs::OpenOptions;
fn main()->std::io::Result<()>{
let mut file = OpenOptions::new().read(true).write(true).open("d:/text.txt")?;
file.write(b"COVER")?;
Ok(())
}
56. 集合一
集合的创建
// 集合创建
fn main(){
let vector: Vec<i32> = Vec::new(); // 创建类型为 i32 的空向量
let vector = vec![1, 2, 4, 8]; // 通过数组创建向量
}
57. 向集合添加元素
使用push添加元素
// push 添加 元素
fn main(){
let mut vector = vec![1, 2, 4, 8];
vector.push(16);
vector.push(32);
vector.push(64);
println!("{:?}", vector);
}
58. 在集合末尾添加一个集合
// append 添加集合
fn main(){
let mut v1:Vec<i32> = vec![1, 2, 4, 8];
let mut v2:Vec<i32> = vec![16, 32, 64];
v1.append(&mut v2);
println!("{:?}", v1);
}
59. 集合遍历和取元素
fn main(){
let mut v = vec![1, 2, 4, 8];
// 相对安全的取值方法
println!("{}", match v.get(0) {
Some(value)=>value.to_string(),
None=>"None".to_string()
});
// 下标取值
let v = vec![1, 2, 4, 8];
println!("{}", v[1]);
// 遍历
let v = vec![100, 32, 57];
for i in &v{
println!("{}", i);
}
}
60. string字符串操作
fn main(){
// 新建字符串
let string = String::new();
// 基础类型转成字符串
let ont = 1.to_string();
let float = 1.3.to_string();
let slice = "slice".to_string();
// 包含 UTF-8 字符的字符串
let hello = String::from("السلام عليكم");
let hello = String::from("Dobrý den");
let hello = String::from("Hello");
let hello = String::from("שָׁלוֹם");
let hello = String::from("नमस्ते");
let hello = String::from("こんにちは");
let hello = String::from("안녕하세요");
let hello = String::from("你好");
let hello = String::from("Olá");
let hello = String::from("Здравствуйте");
let hello = String::from("Hola");
// 字符串追加
let mut s = String::from("run");
s.push_str("oob");
s.push_str("!");
// + 拼接字符串
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2;
// 使用format!宏
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{}-{}-{}", s1, s2, s3);
let s = "hello";
let len = s.len();
// 中文字符长度
let s = "你好";
let len = s.len(); // 6 中文utf-8编码,一个字长3个字节
println!("{}", len);
// 中文字符正确长度
let s = "你好";
let len = s.chars().count(); // 2
println!("{}", len);
// 字符串遍历
let s = String::from("hello中文");
for c in s.chars(){
println!("{}", c);
}
// 取单个字符
let s = String::from("EN中文");
let a = s.chars().nth(2); // Some('中')
println!("{:?}", a);
// 按索引截取字符串 不推荐 遇到中文有问题
let s = String::from("EN中文");
let sub = &s[0..2]; // EN
// let sub = &s[0..3]; // 报错了
println!("{}", sub);
}
61. hashmap
use std::collections::HashMap;
fn main(){
// 映射表操作
let mut map = HashMap::new();
map.insert("color", "red");
map.insert("size", "10 m^2");
println!("{}", map.get("color").unwrap());
// 遍历映射表操作
for p in map.iter(){
println!("{:?}", p);
/*
("color", "red")
("size", "10 m^2")
*/
}
// 先判断key是否存在,然后才安全插入
map.entry("color").or_insert("red");
let mut map = HashMap::new();
map.insert(1, "a");
// 在已经确定有某个键的情况下直接修改对应的值
if let Some(x) = map.get_mut(&1){
*x = "b";
}
for p in map.iter(){
println!("{:?}", p);
}
// (1, "b")
}
62. 面向对象
second.rs
pub struct ClassName{
field: i32,
}
impl ClassName{
pub fn new(value: i32)->ClassName{
ClassName{
field: value
}
}
pub fn public_method(&self){
println!("from public method");
self.private_method();
}
fn private_method(&self){
println!("from private method");
}
}
main.rs
mod second;
use second::ClassName;
fn main(){
let object = ClassName::new(1024);
object.public_method();
}
63. 并发编程1
use std::thread;
use std::time::Duration;
fn spawn_function(){
for i in 0..5{
println!("spawned thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
}
fn main(){
thread::spawn(spawn_function);
for i in 0..3{
println!("main thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
}
64. 并发编程2 匿名函数
use std::thread;
use std::time::Duration;
fn main(){
// 闭包是可以保存进变量或作为参数传递给其他函数的匿名函数。闭包相当于 Rust 中的 Lambda 表达式,格式如下:
/**
|参数1, 参数2, ...| -> 返回值类型 {
// 函数体
}
*/
thread::spawn(||{
for i in 0..5 {
println!("spawned thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
});
for i in 0..3 {
println!("main thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
}
65. 匿名函数与参数传递
fn main(){
// 匿名函数与参数传递
let inc = |num: i32|->i32{
num + 1
};
println!("inc(5) = {}", inc(5));
let inc = |num|{
num + 1
};
println!("inc(5) = {}", inc(5));
}
66. 守护线程
use std::thread;
use std::time::Duration;
// join 方法可以使子线程运行结束后再停止运行程序。
fn main(){
let handle = thread::spawn(||{
for i in 0..5{
println!("spawned thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
});
for i in 0..3{
println!("main thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
handle.join().unwrap();
/*
main thread print 0
spawned thread print 0
main thread print 1
spawned thread print 1
spawned thread print 2
main thread print 2
spawned thread print 3
spawned thread print 4
*/
}
67. 使用move进行所有权迁移
使用move让子线程访问主线程变量
use std::thread;
fn main() {
let s = "hello";
let handle = thread::spawn(move || {
println!("{}", s);
});
handle.join().unwrap();
}
68. 主线程与子线程之间的消息收发
// 消息传递
use std::thread;
use std::sync::mpsc;
fn main(){
let (tx, rx) = mpsc::channel();
thread::spawn(move||{
let val = String::from("hi");
tx.send(val).unwrap();
});
let received = rx.recv().unwrap();
println!("Got: {}", received);
}