{"id":22283762,"url":"https://github.com/veaba/learn-rust","last_synced_at":"2025-08-27T03:05:26.181Z","repository":{"id":104582198,"uuid":"174487619","full_name":"veaba/learn-rust","owner":"veaba","description":"learn rust, 40+ demos","archived":false,"fork":false,"pushed_at":"2022-10-27T14:03:08.000Z","size":755,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-30T17:39:40.362Z","etag":null,"topics":["cargo","learning-rust","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/veaba.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-08T07:13:44.000Z","updated_at":"2024-04-23T12:41:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"546272ab-a27b-4399-a66d-c7e3efd526a1","html_url":"https://github.com/veaba/learn-rust","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veaba%2Flearn-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veaba%2Flearn-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veaba%2Flearn-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veaba%2Flearn-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/veaba","download_url":"https://codeload.github.com/veaba/learn-rust/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245535441,"owners_count":20631294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cargo","learning-rust","rust"],"created_at":"2024-12-03T16:42:05.165Z","updated_at":"2025-03-25T19:51:39.713Z","avatar_url":"https://github.com/veaba.png","language":"Rust","readme":"# learn-rust  \n\n## Book\n- https://rust-lang.github.io/rustc-guide/about-this-guide.html rust官方指南\n- http://wiki.jikexueyuan.com/project/rust-primer/quickstart/primitive-type.html  极客学院的rust教程\n- https://doc.rust-lang.org/std/primitive.f64.html rust 函数库\n- https://doc.rust-lang.org/rust-by-example/index.html rust example\n- https://rust-lang.github.io/rfcs/ rust rfcs\n- https://kaisery.gitbooks.io/trpl-zh-cn/content/ 《Rust 程序设计语言》 中文版\n- https://rustwasm.github.io/book/ 《Rust 程序设计语言》 英文版\n- https://doc.rust-lang.org/stable/rust-by-example/ 通过例子来学习rust\n- https://crates.io/ rust 依赖包\n- TODO https://kaisery.github.io/trpl-zh-cn/ch02-00-guessing-game-tutorial.html 猜猜看游戏 \n- https://rustwiki.org/zh-CN/rust-by-example/std/result.html 中文，例子学习\n\n## 错误\n- ^^^ `std::result::Result\u003c_, _\u003e` cannot be formatted with the default formatter\n- //#[derive(Debug)]的//去掉时能自动为Student实现std::fmt::Debug特性。\n- only valid in field-less enums\n- `Employee` cannot be formatted with the default formatter\n- `not found in this scope`\n\n```text\npub fn arg_result(arg: String) -\u003e tuple {\n    |                                   ^^^^^ not found in this scope\nerror: aborting due to previous error\n```\n\n```rust\n// use\n\nlet ab = utils::arg_result(arg);\nprintln!(\"arg result==?,{}\", ab);\nprintln!(\"{:?}\", arg);\n\n\n// var  utils.rs\npub fn arg_result(arg: String) -\u003e tuple {\n    // return (\"a\", \"2\");\n    (\"a\",\"b\")\n}\n\n\n```\n- `Use of moved value`\n  - [分析文章](https://www.cnblogs.com/dhcn/p/12152116.html)\n    编译器说，我们新加入的行里用了“移动了的值”。\n\n    啥叫“移动了的值”呢？\n\n    说白了就是用过了的值，foo已经给第一个fn_a()用过了，到了第二个fn_a()的时候就是moved value了。然后就不让用了。\n\n    至于为什么要制定这样的规则，[解释]()\n\n    现在我们开始动手来解决这个问题。\n\n- `returns a value referencing data owned by the current function`\n查看例子[lifecycle/lifecycle.rs](lifecycle/lifecycle.rs)\n- `cannot return value referencing local variable \"temp_arg\"`\n查看例子[lifecycle/lifecycle.rs](lifecycle/lifecycle.rs)\n\n`explicit lifetime required in the type of `\n\n## 入门知识点\n- rust 是静态类型，必须知道类型，且不能随更改类型\n\n- 变量隐藏和复写\n```rust\nfn main(){\n\tlet x =5;\n    let x=x+1;\n    let x =x*2;\n}\n```\n\n- 倒数第二及以前的段落必须结尾加分号\n\n- 函数内部 最后一行如果不用return 的方式返回，就不能给该行使用分号\n\t- 表达式返回值\n```rust\nfn main(){\n    let x =five();\n    println!(\"{}\",x);\n}\n\n// 如果函数最后一行不带`return`且不带分号，则认为是一个`return`，可省去关键字`return`\nfn five()-\u003ei32{\n    5\n}\n```\n\n\n## 疑问\n\n### 1. 如何if == string？\n\n### 2. while循环和for循环的区别：\n\n\u003e 如果数组的索引长度在运行时增加，那么while循环显示错误，但在for循环的情况下不会发生这种情况。 因此，可以说for循环增加了代码的安全性并消除了错误的可能性。\n\n### 3. 为什么要加!\n\n### 4. 使用前，需要将变量声明，不存在js类似的变量提升\n\n### 5. i32表示多少 \n### 6. 不能打印长元组？？ 报错,WHY?\n```rust\nfn main(){\n   let too_long_tuple=(1,65,56,6,565,65,95,5,655,656,64,65,5,61,6,5656);\n   println!(\"too long tuple:{:?}\",too_long_tuple);\n}\n```\n### 7. rust 如何执行一段函数返回的代码，即函数返回值\n```rust\n\n/*\n* @pair 入参一个，内含两个元素，数据类型为(i32，bool)元组\n* @return 返回值为 数据类型为，也是个元组 (bool,i32)\n*/\nfn reverse(pair:(i32,bool))-\u003e(bool,i32){\n\tlet (integer,boolean)=pair;\n\t(boolean,integer)\n}\nfn main(){\n\tlet pair = (11,true);\n\tprintln!(\"{:?}\",reverse(pair));\t\n}\n\n```\n\n### 8. rust 如何计算一个函数加值的运算，涉及到 ：入参、返回值，类型\n\n```rust\nfn main(){\n\tprintln!(\"{}\",fool(999));\n}\nfn fool(num:i32)-\u003e(i32){\n\treturn num+999; // 或者num+999，不需要return\n}\n\n```\n\n### 9. 为什么要加一个\u0026?\n\n答案：表示引用\n\n```rust\nuse std::mem;\nfn analyze_slice(slice:\u0026[i32]){\n\tprintln!(\"第一个元素：{}\",slice[0]);\n\tprintln!(\"数组的长度：{}\",slice.len());\n}\n\nfn main(){\n\tlet xs:[i32;5]=[9898,9856,685659,66,9];\n\tanalyze_slice(\u0026xs)//为什么要加一个\u0026呢？\t\n}\n```\n\n\n### 10. match在函数中的作用\n\t- match 由分支(arms)构成，一个分支包含一个模式(pattern)\n\t- match的cmp方法会返回`Ordering:Greater`,`Ordering:Less`,`Ordering:Equal`\n```rust\nfn inspect(event:WebEvent){\n    // match干嘛的？\n    match event {\n        WebEvent::PageLoad=\u003eprintln!(\"page load\"),\n        WebEvent::PageUnload=\u003eprintln!(\"page unload\"),\n        WebEvent::Keypress(c)=\u003eprintln!(\"pressed '{}'.\",c),\n        WebEvent::Paste(s)=\u003eprintln!(\"pasted\\\"{}\\\".\",s),\n        WebEvent::Click {x,y}=\u003eprintln!(\"click at x={},y={}\",x,y)\n    }\n}\n```\n\n### 11. 怎么打印枚举\n```rust\nenum Point{\n\tx = 111\n}\nprintln!(\"{}\");\n\n```\n\n### 12. return 部分返回的尖括号？\n\n### 13. Ok(())是什么意义？\n\n\t- Result 风格，大写Ok,因为它是一个枚举enum\n\n\t- future中，使用小写ok方法【首选】\n\t\n### 14. 函数括号加问号？\n\n### 15. 怎么查看type 类型？\n\n### 16. String 转为真正的数字类型\n```text\nlet num:u32=guess.trim().parse().expect('xxx')\n\n```\n\n### 17. 如何取到键盘输入的值\n\u003e io::stdin().read_line(\u0026mut xx).expect(\"错误~~\") ，存到一个变量\n\n### 18. TODO 如何迭代/循环元组？\n```rust\nfn main(){\nlet long_tuple =(\n        1u8,2u16,3u32,4u64,\n        -1i8,-2i16,-3i32,-4i64,\n        0.1f32,0.2f64,'a',true);\n}\n```\n### 19.TODO，比如test()`?` 这个后面的问号是干嘛的？\n\n\n### 20. 问号是干嘛的？fs::write(\"foo.txt\",\"哈哈哈\")?;\n\n### 21. 数字转字符串\n\n\n### 22. 函数后面有个函数是干嘛？\n\n- 由于Rust中没有Exception异常处理的语法,\n- Rust只有panic报错, 并且panic不允许被保护, 因为没有提供 try 这种语法.\n- Rust的异常处理是通过 Result 的 Ok 和 Err 成员来传递和包裹错误信息.\n- 然而错误信息的处理一般都是要通过match来对类型进行比较, 所以很多时候\n- 代码比较冗余, 通过?符号来简化Ok和Err的判断.\n\n\n```rust \nuse actix_web::{web, App, HttpResponse, HttpServer};\n\n#[actix_rt::main]\nasync fn main() -\u003e std::io::Result\u003c()\u003e {\n    HttpServer::new(|| {\n        App::new().route(\"/\", web::get().to(|| HttpResponse::Ok()))\n    })\n    .bind(\"127.0.0.1:8088\")?  //What is that ?\n    .run()\n    .await\n}\n```\n\n### 23. 为什么这里会变更掉变量值的类型\n\n` use of moved value`\n\n![](static/images/why-change-the-var.png)\n\n可以：utils::arg_result(arg.clone())解决问题\n\n\n### 24. rust 的`impl`\n- `impl` 作为关键字定义参数类型\n- `impl` 关键字定义指定struct的实现代码，然后在这代码块中定义与struct相关的方法\n\n### 25. rust 中的方法和函数\n\n方法与函数非常相似\n\n- 方法：必须有与之关联的`Struct`，且第一个参数是`self`\n```rust\nstruct Style {\n    width: u32,\n    height: u32,\n}\n\nimpl Style {\n    fn area(\u0026self) -\u003e u32 {\n        self.width * self.height\n    }\n}\n\nfn main() {\n    let rect = Style {\n        width: 30,\n        height: 90,\n    };\n    println!(\"{:?}\", rect.area())\n}\n\n```\n### 26 文件调用别的文件的函数方法\n\n```rust\n//  a.rs\nuse crate::shared::QRErrorCorrectLevel::H;\n\n// b.rs\npub struct Code {\n    width: i32,\n    height: i32,\n    type_number: i32,\n    color_dark: String,\n    color_light: String,\n    correct_level: H,\n}\n\n// main.rs\nmod shared;\n```\n\n### 27. rust 如何实现类似 js 中的对象\n\n### 28. rust \u0026b\"\" ??\n\n```rust\nuse bytes::{Bytes}\n\nfn main(){\n\n    let b = Bytes::new();\n    println(\"{:?}\",\u0026b[..])\n}\n\n```\n\n看起来 bytes，声明是 b\"\", 需要 `\u0026x[..]` 展开，然后是是一个数组\n\n### 29. 引用 Reference\n\n两种引用类型：\n\n- 共享指针：`\u0026`\n- 可变指针：`\u0026mut`\n\n规则：\n\n- 引用的生命周期不能超过被引用内容\n- 可变引用不能存在别名\n\n\n\n### 30. 借用 Borrow\n\n### 31. Rust 生命周期\nRust 会通过分析引用对象的`声明周期`来防止引用一个不可用的对象。\n\n生命周期的主要目标是为了防止`悬空指针`\n\n```rust\n{\n    let r;\n    {\n        let x =5;\n        r = \u0026x; // 被销毁了\n    }\n    println!(\"r :{}\",r)\n}\n```\n外部作用域声明了变量`r`，内部作用域声明了变量`x`，在内部产生设置了`r` 为 `x`的引用，当内部区域终止时，尝试打印`r`，上述代码无法通过编译。\n\n查看例子[lifecycle/lifecycle.rs](lifecycle/lifecycle.rs)\n\n### 32. Vec\n\n### 33. rust 函数如何返回一个不定长的数组？\n\n\n```rust\n// error\npub fn arg_array(arg:String) -\u003e \u0026mut [T] {\n    [\"a\"]\n}\n\n// 其中一种方法\n\npub fn arg_array(arg: String) -\u003e Vec\u003c\u0026'static str\u003e {\n    println!(\"入参=\u003e{}\", arg);\n    let array = [\"das\", \"das\",\"dsad\"];\n    println!(\"len =\u003e{}\",array.len());\n    for i in 0..array.len(){\n        vec.push(array[i])\n    }\n    return vec;\n}\n\n```\n\n###  34. rust 结构体里有结构如何打印？\n\n```rust\nstruct MainModule {\n    user: String,\n    // TODO auto 1 2 3 4 5 6\n    worker_processes: u32,\n    event: EventModule,\n    // error_log: String,\n    // pid: String,\n    // worker_rlimit_nofile: u32,\n    // http: HttpModule,\n}\n\nstruct EventModule {\n    worker_connections: u32,\n}\n\nfn main(){\n    let config = MainModule {\n        user: String::from(\"www www\"),\n        worker_processes: 2\n    };\n    println!(\"==\u003e{:#?}\", config.event) // why can;t print this?\n}\n```\n\n### 35. 类似这种结构，怎么打印Object 返回？\n\n```rust\n\nfn main() {\n    let object = json_to_struct();\n    println!(\"{:#?}\", object) // TestStruct` cannot be formatted using `{:?}`\n}\n\n\nfn json_to_struct() -\u003e Result\u003c()\u003e {\n    let json = r#\"\n        {\n            \"name\":\"asjdsak\",\n            \"age\":30,\n            \"type\":true\n        }\n    \"#;\n    let v: Value = serde_json::from_str(json)?;\n    println!(\"==\u003e{:?}\", v);\n    Ok(())\n    // TODO 如何返回v\n}\n\n```\n\n改动如下：\n\n```rust\nuse serde_json::{Result,Value};\nfn main() {\n    let object = json_to_struct();\n    println!(\"{:#?}\", object) // TestStruct` cannot be formatted using `{:?}`\n}\n\n\nfn json_to_struct() -\u003e Result\u003cValue\u003e {\n    let json = r#\"\n        {\n            \"name\":\"asjdsak\",\n            \"age\":30,\n            \"type\":true\n        }\n    \"#;\n    let v: Value = serde_json::from_str(json)?;\n    println!(\"==\u003e{:?}\", v);\n    Ok(v)\n}\n\n```\n\n二次改动\n\n```rust\n\nuse serde_json::{Result,Value};\nfn main() {\n    let object = json_to_struct().unwrap();\n    println!(\"{:#?}\", object); // TestStruct` cannot be formatted using `{:?}`\n    // println!(\"{:#?}\", object) // TestStruct` cannot be formatted using `{:?}`\n    // println!(\"name==\u003e{:#?}\", object.name);\n    println!(\"=dsadd=\u003e{}\", object[\"name\"]);\n}\n\n\nfn json_to_struct() -\u003eResult\u003cValue\u003e {\n    let json = r#\"\n        {\n            \"name\":\"asjdsak\",\n            \"age\":30,\n            \"type\":true\n        }\n    \"#;\n    let v: Value = serde_json::from_str(json)?;\n    println!(\"name===\u003e{}\",v[\"name\"]);\n    println!(\"==\u003e{:?}\", v);\n    Ok(v)\n}\n```\n\n### 35. json字符串转struct\n```rust\nextern crate rustc_serialize;\n\nuse rustc_serialize::json;\n\n#[derive(RustcDecodable, RustcEncodable)]\n#[derive(Debug)]\nstruct Profile {\n    name: String,\n    age: u8,\n    phones: Vec\u003cString\u003e,\n}\n\nfn main() {\n    let json_str = r#\"\n    {\n        \"name\":\"veaba\",\n        \"age\":26,\n        \"phones\":[\n            \"110\",\n            \"120\",\n            \"119\"\n        ]\n    }\n    \"#;\n    let profile: Profile = json::decode(\u0026json_str).unwrap();\n    println!(\"json to struct==\u003e{:#?}\", profile);\n}\n\n```\n### 36. struct转json字符串\n```rust\nextern crate rustc_serialize;\n\nuse rustc_serialize::json;\n\n#[derive(RustcDecodable, RustcEncodable)]\n#[derive(Debug)]\nstruct Profile {\n    name: String,\n    age: u8,\n    phones: Vec\u003cString\u003e,\n}\n\nfn main() {\n    let profile = Profile {\n        name: \"Jobs\".to_string(),\n        age: 99,\n        // phones: vec![\"110\", \"120\", \"199\", \"144\"],\n        phones: vec![\"110\".to_string(), \"120\".to_string(), \"199\".to_string(), \"144\".to_string()],\n    };\n    let encode = json::encode(\u0026profile).unwrap();\n    println!(\"struct to json==\u003e{}\", encode);\n}\n\n```\n### 37. struct 打印\n- 必须要加`#[derive(Debug)]`，否则无法使用 {:#?}打印struct\n- [src/struct/struct.rs](src/struct/struct.rs)\n\n\n### 38. struct 嵌套struct 如何转为json?\n```rust\nextern crate rustc_serialize;\n\nuse rustc_serialize::json;\n\n// Struct Parent\n#[derive(RustcDecodable, RustcEncodable)]\n#[derive(Debug)]\nstruct Parent {\n    name: String,\n    age: u8,\n    children: Children,\n}\n\n// Struct Children\n#[derive(RustcDecodable, RustcEncodable)]\n#[derive(Debug)]\nstruct Children {\n    name: String,\n    age: u8,\n    school: String,\n}\n\nfn main() {\n    let person = Parent {\n        name: \"Li\".to_string(),\n        age: 35,\n        children: Children {\n            name: \"Li's son\".to_string(),\n            age: 8,\n            school: \"primary\".to_string(),\n        },\n    };\n    println!(\"no children==\u003e{:#?}\", person); // 可以打印出来person\n\n    let to_json_str = json::encode(\u0026person).unwrap();\n    println!(\"json str==\u003e{}\", to_json_str);\n}\n\n\n```\n### 39. struct 转普通字符串\n也只能参考struct 转 json 字符串\n\n### 40. 可省略的struct\n\n### 41. 禁用无效代码检查\n\n\u003e #[allow(dead_code)]\n\n### 42. 匿名函数 TODO\n\nRust 使用闭包(`closure`) 来创建匿名函数\n\n```rust\nlet num=5;\nlet plus_num= |x:i32| x +num;\n```\n闭包`plus_num`借用了它的作用域中的`let` 绑定`num`，如想让闭包获取所有权，可以使用`move`关键字：\n\n```rust\nlet mut num=5;\n{\n    let mut add_num=move |x:i32| num+=x; //  闭包通过move 获取num所有权\n    add_num(5)\n}\n```\n\n### 43. 如何合并多个结构？\n\n```rust\nfn get_merge_config() {\n    let default_config = get_default_config();\n    let outside_config= get_outside_config();\n    let merge_config=ConfigModule{\n        default_config, // TODO ??\n        ..outside_config\n    };\n    println!(\"default config===\u003e{:#?}\", default_config);\n    return merge_config;\n}\n\n```\n\n### 44. 如何简写if 或操作\n\n```rust\n// TODO 如何简写一下代码？\nfn main() {\n    let a = String::from(\"aa\");\n    let b = String::from(\"bb\");\n    // let c: String = a | b;\n    let c;\n    if a.len() \u003e 0 {\n        c = a\n    } else {\n        c = b\n    }\n\n    println!(\"{}\", c);\n}\n\n```\n## structures 结构\n\n\nrust 通过自定义类型主要通过以下两个关键形成：\n- struct 声明一个结构\n- enum   声明一个枚举\n\n常量可以通过`const` `static`  关键字声明\n\n\t- const x = 99; 不合适。x推荐大写\n\t- const X=8;错误，X虽然大写，但需要声明数据类型\n\t- const X:u32=999 √\n\t- const mut X:u32=99  常量不接受可变量修饰符\n\n结构：\n- 元组结构，基本上是命名为元组的。\n- 经典的C结构\n- 无字段的单元结构对于泛型很有用\n\n\n- rust 的结构和解构\n```rust\nstruct Pair(i32,f32);\nstruct Person\u003c'a\u003e {\n    name: \u0026'a str,\n    //这是啥子？\n    age: u8,\n}\n fn main(){\n \t  let pair =Pair(99,99.9);\n \t  let Pair{x,y}=pair; //todo ??\n \t  println!(\"{:?}\\n{:?}\",x,y);\n \t  \n \t   let name = \"Jogel\";\n      let age = 27;\n      let jogel = Person { name, age };\n      \n      println!(\"{:?}\",jogel);\n }\n```    \n\n- 如何跨文件使用use    \n```rust\n\nenum Status{\n    Rich,\n    Poor\n}\nenum Work{\n    Google,\n    Microsoft,\n}\n\nuse Status::{Poor,Rich};\n\nuse Work::*;\n\n```\n\n## 定时器\n\n```rust\nuse std::thread;\nuse std::time::Duration;\n\nfn main() {\n    let mut x = 1;\n    while x \u003c 10 {\n        println!(\"{},{}\",x,\"哈哈哈哈\");\n        x += 1;\n        thread::sleep(Duration::from_millis(1000));\n    }\n    println!(\"{},{}\",x,\"哦哦哦\");\n}\n\n```\n## 内存和分配\n\n![堆栈](./static/images/stack-heap.png);\n\n- 堆栈存储器\n\t- 循环放置\n\t- 相反顺序移除\n\t- 遵从`后进先出`，进电梯 原则\n\t- 始终 首先删除最后插入的数据\n\t- `堆栈内存`有组织的内存，比`堆内存`更快\n\t- 访问内存的方式\n\t- 编译时数据大小未知，则`堆内存`用于存储内容\n\n- 堆内存\n\t- `堆内存`是有组织的内存\t\n\t- os 在`堆内存`中找到一个空的空格并返回一个指针，这叫 `在对上分配`\n\n![内存图片](./static/images/memory.png);\n\n- 第一步\n\t- 向量v1与值 1 2 3 '666'绑定，四个部分组成\n\t- 指向存储器中指向存储在内存的数据的指针 长度和向量的容量\n\t- 这部分存储在堆栈中，二数据存储在堆内存中\n\n![one](./static/images/one.png);\n\n- 第二步\n\t- `v1` 向量分配给向量`v2`\n\t- 指针，长度、容量将复制到堆栈中\n\t- 但不会讲数据复制到堆内存中 \n\t- \n\t- `v1`、`v2` 都超出范围时，两者都会尝试释放内存\n\t- 这会导致双重空闲内存，从而使得内存损坏~\n\t\n![two](./static/images/two.png);\n\n- 第三步\n\t- rust 避免了第二步的内存问题\n\t- rust没有复制分配的内存，则认为`v1`向量不再有效\n\t- 当 `v1`超出范围时，它不需要释放`v1`的内存\n\t\n![three](./static/images/three.png);\n\n```rust\nfn main(){\n\tlet v1= vec![1,2,3,\"666\"];\n    let v2 = v2;\n}\n\n```\n\n### 特征复制\n- 复制特征是特殊的注释\n- 放在存储堆栈上的整数类型上\n- 如果类型使用了复制特征，则复制之后还可以使用旧变量\n- 复制类型\n\t- 所有整数类型，如 `u32`\n\t- 布尔类型 `bool`:`true`, `false`\n\t- 所有浮动类型，如`f64`\n\t- 字符类型，如 `char`\n\n\n\n### 所有权和函数\n\n## 所有权（ownership）【重点】\n\n### 管理计算机内存的方式\n- 垃圾回收机制\n\t- javascript\n\t- java\n- 手动分配和释放内存\n\t- C语言\n- 所有权系统管理内存\n\t- Rust\n\n\n### 堆栈知识\n\n编译器在编译时会根据一系列的规则进行检查，runtime，ownership 所有权系统的任何功能不会减慢程序\n\n- [阮一峰：汇编语言入门教程](http://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html)\n\n- Heap（堆）：程序运行时产生，用户去申请的,存储值\n\t- 缺乏组织性\n\t- 大小未知\n\t- 手动请求和分配一块区域存储数，返回地址的指针：这个过程叫：在堆上分配内存\n- Stack（栈）：push、pop 等相关，函数运行时而临时占用的内存区域。后进先出（叠盘子）\n\n- 访问堆上的数据比访问栈上的数据慢，因为必须通过指针来访问\n\n- 调用函数，传递函数的值（可能是堆上数据的指针）和函数局部变量被压入栈中，当函数结束时，这些值被移除栈。\n### 关于rust 所有权的描述\n\n\nrust的所有权操作，属于新的概念。\n\n\n\n\n\n## 常识\n\n|name|desc||\n|---|---|---|\n|.rs|rust文件后缀||\n|Cargo.lock|||\n|Cargo.toml|||\n|xxx.iml|||\n|src目录|源码||\n|target目录|||\n|mnt i| i是可以更改变量，可变变量||\n|双引号|给字符/对象||\n|str|String::from(\"a string\")||\n|char|`a`，单引号是一个单字符，超出则编译错误 `let char = 'a'`||\n|\u0026str|`abd`，双引号括住是多个字符 `let a=\"你好\"`||\n|return None|||\n|return true|||\n|return false|||\n|return Err(err)|||\n|impl|||\n|符号整数|i开头||\n|无符号整数|u开头，不是负号||\n|#[derive(Debug)]|||\n|#[allow(dead_code)]|||\n|{:?}|打印数组、元组||\n|match|rust关键字提供匹配模式，类似C的 `switch`|参考https://doc.rust-lang.org/rust-by-example/flow_control/match.html|\n|_|下划线|_=\u003eprint!(\"xx\"),类似如果下划线在match中，类似switch 的default:|\n||||\n\n### 定义/结论\n- rust 变量默认不可改变，如需改变，则需要let mut bar=\"hello world\"\n- `let mut foo = String::new()` new 是String类型的关联函数，针对类型实现的，常称：静态方法\n- `new` 创建类型实例的惯用函数名\n- Result 类型是枚举，枚举(enums)，它的值被称为枚举的成员(variants):`ok`,`Err`。\n\t- ok 表示成功\n\t- Error 表示失败\n- io::Result，的实例拥有expect方法,`return` 的是一个 输入的字节数`usize`\n- rust标准库中尚未包含随机数功能，rust团队提供了 `rand` crate\n- `std::cmp::Ordering`类型，`Ordering`也是一个枚举，成员是`Less`(小于),`Greater`(大于),`Equal`(等于),比较两个值的三种结果\n- //#[derive(Debug)]的//去掉时能自动为Student实现std::fmt::Debug特性。\n- use 枚举名称::*，自动列出枚举名称的名称，少写几次枚举名称,直接写成员\n```text\n\tenum Work{\n        Google,\n        Microsoft,\n        Alibaba=999\n    }\n   use Work::*;\n   let work = Google;\n   let worker =Microsoft;\n   let taobao =Alibaba;//??\n\n```\n- rust 使用 snake case 风格，所有字母都小写并使用下划线分割\n- rust 函数声明提升，无论声明在调用之前或之后\n- rust 函数的参数必须有类型fn test(arg1:i32,arg2:u64)\n- rust 是一门基于表达式的语言(expression-based)\n- rust 无法使用`x=y=6`\n### 常量和变量的区别\n\n- let 变量\n\t- let x =6 不可变的变量\n\t- let mut x=6 自动推断类型，且可变\n- const 常量，大写\n\t- const x = 99; 不合适。x推荐大写\n\t- const X=8;错误，X虽然大写，但需要声明数据类型\n\t- const mut X:u32=99  常量不接受可变量修饰符\n\t- const X:u32=999 √\n\t\n\t\n### 隐藏,shadowing\t\n\n重复声明的方式来达到变量替换的目的，后者会替换前面的变量\n\n```rust\nfn main(){\n\tlet mut x = 666;\n\tlet x =999;\n\tlet mut x = 888;//此处的mut 是多余了 \n}\n\n```\n\n## install\n### version\n\u003e rustc --version\n### update 更新\n\u003e rustup update\n### uninstall 下载\n\u003e rustup self uninstall\n\n## demo\n### 处理一次猜测\n- [处理一次猜测](https://kaisery.github.io/trpl-zh-cn/ch02-00-guessing-game-tutorial.html)\n```rust\nuse std::io;\nfn main(){\n    println!(\"hello world\");\n    let mut guess =String::new(); //?干嘛的，空字符串\n    println!(\"请输入：{}\",guess);\n\n    io::stdin().read_line(\u0026mut guess)\n        .expect(\"读取行失败\");\n    println!(\"你猜的，{}\",guess);\n}\n\n```\n### 猜到对数字\n\n```toml\n[package]\nname = \"learn-rust\"\nversion = \"0.1.0\"\nauthors = [\"veaba\"]\nedition = \"2018\"\n\n[dependencies]\nrand=\"0.3.14\"\n\n```\n\n```rust\n\n/**\n@desc 步骤分析：\n    1、生成一个1-100的随机数\n    2、键盘输入一值\n    3、loop循环\n    4、比较大小\n\n*/\nuse std::io;\nuse rand::Rng;\nuse std::cmp::{Ordering,Ord};\n\nfn main() {\n\n    let code = rand::thread_rng().gen_range(1,101);\n    println!(\"code:{}\",code);\n\n\n    loop {\n        println!(\"======== 请输入你的字符 ========\");\n        let mut key=String::new();//生成一个类型为String的实例\n        io::stdin().read_line(\u0026mut key)\n            .expect(\"输入错误~\");\n        println!(\"你输入的：{}\",key);\n\n        // rust 允许用一个新值来隐藏(shadow)guess之前的值：常用于转换值类型之类的场景，\n        // 这种用法，允许复用guess便利店个名称，而不是创建两个不同的变量\n        // 详见：https://kaisery.github.io/trpl-zh-cn/ch03-00-common-programming-concepts.html\n        let key:u32=match key.trim().parse(){\n            Ok(num)=\u003enum,\n            Err(_)=\u003e{\n                println!(\"字符类型不对\");\n                continue\n            }\n        };\n\n        // key 和code 没办法对比,请改为CMP-\u003ecmp\n        match key.CMP(\u0026code) {\n            Ordering::Less=\u003eprintln!(\"太小了\"),\n            Ordering::Greater=\u003eprintln!(\"太大了\"),\n            Ordering::Equal=\u003e{\n                println!(\"猜中了，biubiu\");\n                break;\n            }\n        }\n\n    }\n\n}\n\n\n```\n\n## rustup\n\n## cargo\n\n## 第一个程序\n\n```rust\nfn main(){\n    print!(\"Hello,world!\");\n}\n```\n\n\n执行命令\n\u003e rustc hello.rs \n\n会生成` hello.exe`、`hello.pdb`，windows 下运行hello.exe才会运行\n\n## 函数\n\n|函数|解释|demo|\n|---|---|---|\n|format!()|格式化文本写入字符串||\n|print!|类似format!，但打印到控制台||\n|println!()类似print!但会添加新的一行|||\n|eprint!|类型format!，打印为标准错误||\n|eprintln!()类似eprint，但会添加新的一行|||\n||||\n||||\n||||\n\n\n```rust\n\n// -\u003e指返回\nfn add_one(x:i32)-\u003ei32{\n\tx+1\n}\n\n// todo 问号是干嘛的？fs::write(\"foo.txt\",\"哈哈哈\")?;\n\n\n// let _ = fs::write(\"foo.txt\", \"哈哈哈\");\n\n```\n\n### 函数发散,不会返回\n\n\n## 系统/全局函数或方法\n\n### print!()  \n- print!(双引号)，且只能是字符串\n\n```rust\nfn main(){\n    let a=9;\n    if  a==9 {\n        print!(\"aaa\");\n    }\n}\n```\n\n### println!()\n\n```rust\nprintln!(\"{}\",\"xxx\");\nprintln!(\"{:?}\",xxx);\n\n```\n### .to_owned()\n### .iter()\n### match  类似 `switch`\n```rust\nfn main(){\n\tlet number=1;\n    println!(\"the number:{}\",number);\n    // prime\n    match number {\n        1=\u003eprintln!(\"One\"),\n        2=\u003eprintln!(\"Two\"),\n        3|4|5|6|7|11=\u003eprintln!(\"匹配的数字\"),\n        12...19=\u003eprintln!(\"A ten哇\"),\n        // 不是特殊的\n        _=\u003eprintln!(\"default\"),\n    }\n    let boolean =true;\n    let binary =match boolean\n        {\n            false=\u003e0,\n            true=\u003e1\n        };\n    println!(\"{}-{}\",boolean,binary);\n}\n\n```\n\n\n## if判断语句\n```rust\nfn main(){\n    let a=9;\n    if  a==8 {\n        println!(\"aaa\");\n    }\n    else if a\u003e8 {\n        println!(\"bbb\");\n    }\n    else{\n        println!(\"ccc\");\n    }\n}\n```\n## if in a let语句\n\n## 错误处理error\n- https://doc.rust-lang.org/error-index.html#E0308  rust编译错误索引\n\n\u003e expected integer, found char\n\n\u003e too many characters in char literal  表示只能是单个字符！！a或者b，不能ab\n\n\u003e String::from(\"S/\\q\\t\\nI}POYY\u003cM?\u003e?M\u003eNM\u003eM\u003cJKLKL:KLII/\\dh\") \\d这里有问题\n\n\n## 循环\n### loop 循环\n- 需要mnt 声明变量，\n- 无法使用i++ 自增加1，而是i+=1\n- break 跳出loop\n```rust\nfn main(){\n\tlet mut i =1;\n    loop {\n        println!(\"{}\",i);\n        if i==10{\n            break\n        }\n        i+=1\n    }\n}\n\n```\n### for循环\n\n- 循环数组\n```rust\n// 循环数组\nfn main(){\n\tlet res =[\"mango\",\"apple\",\"banana\",\"litchi\",\"watermelon\"];\n    for i in res.iter() { //iter()方法\n            println!(\"{}\",i)\n    }\n}\n```\n\n- 循环对象\n```rust\n//TODO 循环对象\n```\n### while循环\n- 索引不正确，循环有问题\n- 每次迭代前进行条件检查，速度慢\n- 如果外部引发条件变化，则可能会引发死循环的异常\n```rust\nfn main(){\n\tlet mut i=0;\n    while i\u003c=10 {\n        println!(\"{}\",i);\n        i+=1\n    }\n}\n```\n## 字符串 string\n\nrust 有两种主要的字符串类型 `\u0026str` 和`String` \n\n### `\u0026str` 字符串片段(string slices)\n\n### `\u0026'static str` 字符串常量 \n\n```rust\n\n// \u0026'static str 的返回值\nfn main(){\n    println!(\"一个函数返回一个字符串：{}\",return_a_string());\n}\n\nfn return_a_string()-\u003e(\u0026'static str){\n    let str = \"哇哈哈哈\";\n    return  str\n}\n\n```\n## 数组\n\n- 数组每个元素的类型必须相同\n- 不可减少长度或者增加长度\n\n### 访问方式 和js 一样 arr[1]\n\n## 数组的函数/方法\n\n\n## vector 可伸缩的数组\n- 标准库提供的一个允许增长和缩小长度的类似数组的集合类型\n\n\n## 所有权\n\n- 代码块拥有资源时，被称为所有权。\n- 代码块创建一个包含资源的对象。\n- 当控件到达末尾时，对象将被销毁，资源将被释放\n- Rust中，每个值都有一个与之关联的变量，并成为其所有者\n- 一次只能有一个所有者\n- 当所有者超出范围是，与其关联的值将被销毁\n\n\u003e a被回收，编译直接报错\n```rust\n// \nfn main(){\n\tlet a =20;\n    let b = a;\n    println!(\"{}\",a)\n}\n```\n\n\u003e但是 下面这样就不会被回收~~ TODO ？why？\n```rust\nfn main1(){\n\tlet a =20;\n    let b = a;\n    println!(\"{}\",b);\n    println!(\"{}\",a)\n}\n```\n\n\n### 所有权和函数\n```rust\nfn main(){\n\tlet s =String::from(\"SDUSAJDOISAJ IUJODSJAI \");//啥意思？\n    take_ownership(s);\n    let ch ='a';\n    move_copy(ch);\n    println!(\"main:{}\",ch)\n}\nfn take_ownership(str:String){\n    println!(\"take_ownership:{}\",str)\n}\nfn move_copy(c:char){\n    println!(\"move_copy:{}\",c)\n}\n```\n- \n\n## 字符\n```rust\nfn main(){\n\tlet ch = 'a';\n    //let tt = 'abad';//为啥这里会报错，因为char 类型只能是一个字符\n    move_copy(ch);\n    move_copy(tt);\n}\n\t\nfn move_copy(str:String){\n\tprintln!(\"{}\",str)\n}\n\n```\n\n### 存放任意字符，斜杠之类的\n\u003e \\d \\q都有问题\n\n\u003elet s =String::from(\"S/\\q\\t\\nI}POYY\u003cM?\u003e?M\u003eNM\u003eM\u003cJKLKL:KLII//\\dh\");\n\n## 字符串函数/方法\n\n### len() 取长度\n\n```rust\nfn main(){\n\tlet x = 999;\n\tprintln!(\"{}\",x.len()); //错误\n\tlet y =\"66\";\n\tprintln!(\"{}\",y.len());\n}\n\n```\n### trim() 移除首尾字符\n\n```rust\nfn main(){\n\tlet str1 = \"\\n 444\";\n\tprintln!(\"{}\",str1.trim());\n}\n\n```\n### .parse() 转为数字类型，并且会返回一个枚举，含有两个成员，ok和 err类型\n\n### .expect('msg')一般处理异常抛出的结果\n\n## fs \n\n```rust\nuse std::fs;\nfn write_file() -\u003e std::io::Result\u003c()\u003e {\n    fs::write(\"foo.txt\",\"哈哈哈\")?;\n    Ok(())\n}\n\n\nfn main() {\n    println!(\"hello world\");\n    let _ = write_file();\n}\n\n\n```\n\n## 数据类型\n\n|类型 |值  |\n|----|----|\n|布尔类型|`true` `false`|\n|字符类型|单个Unicode类型，存储4个字节|\n|数值类型-符号整数|`i8` `i16` `i32` `i64` `isize`|  \n|数值类型-无符号整数|`u8` `u16` `u32` `u64` `usize`|\n|数值类型-浮点数|`f32` `f64`|\n|字符串类型-底层不定长类型|`str`|\n|字符串类型-字符串切片|`\u0026str`，静态分配，固定大小，不可变|\n|字符串类型-堆分配字符串|`String`，可变|\n|数组|固定大小，且元素都同类型，`[T;N]`|\n|切片|引用一个数组的部分数据，并且不需要拷贝,`\u0026[T]`|\n|元组|固定大小的有序列表，元素都有自己的类型，通过解构或者索引来获取值|\n|指针|最底层的裸指针,`*const T` `*mut T`,但解引用它们是不安全的，必须放到`unsafe`块里|\n|函数|具有函数类型的变量实质上是一个函数指针|\n|元类型|即`()`，其唯一值也是`()`|\n\n\n### 标量类型\n\n\n- `整型`。没有小数部分的数字，默认`i32`\n\nrust中的整型\n\n|长度|有符号|无符号(负数)|-(2\u003csub\u003en-1\u003c/sub\u003e -1)|\n|----|-----|-----|----|\n|8-bit|`i8`|`u8`||\n|16-bit|`i16`|`u16`||\n|32-bit|`i32`|`u32`||\n|64-bit|`i64`|`u64`||\n|arch|`isize`|`usize`||\n|||||\n\n`isize`和`usize` 类型依赖计算机架构，64位是64位，32位是32位\n\nrust中的整型字面值\n\n|数字字面值| 例子 |\n|----     |---- |\n|`Decimal`|`98_222`|\n|`Hex`|`0xff`|\n|`Octal`|`0o77` |\n|`Binary`|`0b1111_0000`|\n|`byte` (`u8` only)|b`A`|\n\n**整型溢出**：`u8` 放到0-255值，修改为`256`，被称为`整型溢出`(idnteger overflow)\n\n在 release 构建中，Rust 不检测溢出，相反会进行一种被称为 “two’s complement wrapping” 的操作。简而言之，256 变成 0，257 变成 1，依此类推。依赖溢出被认为是一种错误，即便可能出现这种行为。如果你确实需要这种行为，标准库中有一个类型显式提供此功能，Wrapping。\n\n\n\n- `浮点型`。带小数点的数字，有两个原生的浮点数类型`f32`、`f64`，默认`f64`。IEEE-754标准\n\t- `f32` 单精度浮点数\n\t- `f64` 双精度浮点数\n```rust\nfn  main(){\n\tlet x = 2.0; // f64\n\tlet y:f32= 3.2; //f32\n\n}\n```\n- `布尔型`。bool\n\t- true\n\t- false\n- `字符类`。\n\t- `char`代表Unicode,单个字符，中文或者其他语言的单字\n\n### 复合类型\n- tuple `(a,b,c,d)`\n- array `[a,b,c,d]`\n\n\n\n\t\n### 基本类型\n\n|类型|最小值|最大值|值|描述|所属组|\n|---|---|---|---|---|---|\n|array||||1||\n|bool||||||\n|char||||||\n|f32||||||\n|f64||||||\n|fn||||||\n|i8||||||\n|i16||||||\n|i32||||||\n|i64||||||\n|i128||||||\n|isize||||||\n|never||||||\n|pointer||||||\n|reference||||||\n|slice||||||\n|str||||||\n|tuple||||||\n|u8||||||\n|u16||||||\n|u32||||||\n|u64||||||\n|u128||||||\n|unit||||||\n|usize||||||\n\n\n\u003e https://doc.rust-lang.org/nightly/std/primitive.i8.html\n\n### 数字转为其他类型\n\n## rustup\n\nCommand                                                     | Description\n----------------------------------------------------------- | ------------------------------------------------------------\n`rustup default nightly`                                    | Set the default toolchain to the latest nightly\n`rustup target list`                                        | List all available targets for the active toolchain\n`rustup target add arm-linux-androideabi`                   | Install the Android target\n`rustup target remove arm-linux-androideabi`                | Remove the Android target\n`rustup run nightly rustc foo.rs`                           | Run the nightly regardless of the active toolchain\n`rustc +nightly foo.rs`                                     | Shorthand way to run a nightly compiler\n`rustup run nightly bash`                                   | Run a shell configured for the nightly compiler\n`rustup default stable-msvc`                                | On Windows, use the MSVC toolchain instead of GNU\n`rustup override set nightly-2015-04-01`                    | For the current directory, use a nightly from a specific date\n`rustup toolchain link my-toolchain \"C:\\RustInstallation\"`  | Install a custom toolchain by symlinking an existing installation\n`rustup show`                                               | Show which toolchain will be used in the current directory\n`rustup toolchain uninstall nightly`                        | Uninstall a given toolchain\n`rustup toolchain help`                                     | Show the `help` page for a subcommand (like `toolchain`)\n`rustup man cargo`                                          | \\(*Unix only*\\) View the man page for a given command (like `cargo`)\n\n\n## Cargo\n- https://rustlang-cn.org/office/rust/cargo/getting-started/installation.html\n### 安装Cargo\n\u003e curl https://sh.rustup.rs -sSf | sh\n\n如果顺利则：\n\u003e Rust is installed now. Great!\n\n### Cargo 第一步\n创建项目：\n\u003e cargo new helloworld\n\nbuild\n\u003ecargo build\n\n运行\n\u003e./target/debug/helloworld\n\ncargo run \n\u003ecargo run \n\ncargo doc --open 生成并打开一个文档，构建所有本地依赖提供的文档。帅！\n\u003ecargo doc --open\n### cargo 指南\n为什么会有cargo：\n- 引入两个带有各种程序包信息的元数据文件\n- 获取和构建项目依赖\n- 正确的构建参数调用rustc 和其他构建工具\n- 引入惯例使得rust程序包开发管理更加容易\n\n已存的cargo项目\n\n```cmd\ngit clone xx \ncd xx\ncargo build\n```\n\n一个cargo依赖如何添加\n\n```toml\n[dependencies]\ntime=\"0.1.12\"\n```\n\ncargo build 会获取新的依赖以及依赖的依赖，一并编译。并且更新Cargo.lock文件\n\n\ncargo update 更新依赖\n\ncargo 项目结构：\n```mk\n.\n├── Cargo.lock 具体依赖信息，cargo维护，不应该手动修改，可防止.gitignore文件\n├── Cargo.toml 广义上秒数项目的依赖文件，开发者编写\n├── benches 性能评估\n│   └── large-input.rs\n├── examples 示例目录\n│   └── simple.rs\n├── src 源码\n│   ├── bin\n│   │   └── another_executable.rs\n│   ├── lib.rs 库文件\n│   └── main.rs 默认可执行文件源代码\n└── tests 单元测试\n    └── some-integration-tests.rs\n```\n\n### cargo toml 清单文件\n\n```toml\n[package]\nname = \"hello_world\"\nversion = \"0.1.0\"\nauthors = [\"Your Name \u003cyou@example.com\u003e\"]\n\n[dependencies]\n# 指定依赖仓库\nrand = { git = \"https://github.com/rust-lang-nursery/rand.git\" }\n\n# 解决指定版本，没多卵用。\nrand = { git = \"https://github.com/rust-lang-nursery/rand.git\", rev = \"9f35b8e\" }\n```\ncargo update   更新所有依赖\n\ncargo update -p rand 仅更新rand\n\n### cargo test\n- `src` 目录下每个文件中的 `tests/`目录,单元测试\n- `test/`目录是集成风格的测试\n- `cargo test` 会运行额外的检查\n- 参考文档https://doc.rust-lang.org/book/testing.html\n\n 可执行指定参数测试，将测试名称含有foo的所有测试\n\u003e carto test foo\n\n### cargo 持续集成\n#### Travis CI 测试项目\n- 测试所有三个发布通道\n- 任何nightly构建中断将不会使整体构建失败\n- 参考 Travic CI Rust documentation https://docs.travis-ci.com/user/languages/rust/\n```yml\nlanguage:rust\nrust:\n    - stable\n    - beta\n    - nightly\nmatrix:\n    allow_failures:\n        - rust :nightly\n```\n\n#### GitLab CI\n\n- stable 通道 和 nightly 通道测试\n- 任何nightly构建中断将不会使整体构建失败\n- Gitlab CI  https://docs.gitlab.com/ce/ci/yaml/README.html\n```yml\nstages:\n    - build\nrust-latest:\n    stage:build\n    image:rust:latest\n    script:\n        - cargo build --verbose\n        - cargo test --verbose\n\nrust-nightly:\n    statge:build\n    image:rustlang/rust:nightly\n    script:\n        - cargo build --verbose\n        - cargo test --verbose\n    allow_failure:true\n```\n\n#### build.sr.ht\n- 确保将`\u003cyour repo\u003e`和`\u003cyour project\u003e`改变为要克隆和已克隆的目录。\n- 将会在stable和nightly通道测试和构建文档\n- 但是任何nightly构建中断将不会使整体构建失败\n- 参考builds.sr.ht documentation https://man.sr.ht/builds.sr.ht/\n```yml\nimage: archlinux\npackages:\n  - rustup\nsources:\n  - \u003cyour repo\u003e\ntasks:\n  - setup: |\n      rustup toolchain install nightly stable\n      cd \u003cyour project\u003e/\n      rustup run stable cargo fetch\n  - stable: |\n      rustup default stable\n      cd \u003cyour project\u003e/\n      cargo build --verbose\n      cargo test --verbose\n  - nightly: |\n      rustup default nightly\n      cd \u003cyour project\u003e/\n      cargo build --verbose ||:\n      cargo test --verbose  ||:\n  - docs: |\n      cd \u003cyour project\u003e/\n      rustup run stable cargo doc --no-deps\n      rustup run nightly cargo doc --no-deps ||:\n```\n\n\n#### cargo构建缓存\n- 同一个工作区所有项目之间，共享构建信息\n- 第三方工具sscache https://github.com/mozilla/sccache ，可以得到不共享效果\n- 参考 https://rustlang-cn.org/office/rust/cargo/guide/build-cache.html\n\n### cargo 依赖指定\n- 更多详细信息 https://rustlang-cn.org/office/rust/cargo/reference/specifying-dependencies.html\n\n```toml\n[dependencies]\nrand = { git = \"https://github.com/rust-lang-nursery/rand\" }\n\n# 指定分支\n[dependencies]\nrand = { git = \"https://github.com/rust-lang-nursery/rand\", branch = \"next\" }\n\n# 路径依赖指定\n[dependencies]\nhello_utils = { path = \"hello_utils\" }\n\n# 发布cargo箱子\n[dependencies]\nhello_utils = { path = \"hello_utils\", version = \"0.1.0\" }\n\n```\n\n### cargo 清单格式 TODO\n- https://rustlang-cn.org/office/rust/cargo/reference/manifest.html \n- [package]\n- [profile]\n\n### cargo 环境变量 TODO\n- https://rustlang-cn.org/office/rust/cargo/reference/environment-variables.html\n\n### cargo 构建脚本 \n- https://rustlang-cn.org/office/rust/cargo/reference/build-scripts.html\n\n### cargo 发布依赖到crates.io\n\n### cargo 词汇表\n- https://rustlang-cn.org/office/rust/cargo/appendix/glossary.html\n\n### cargo 错误\n\u003e Blocking waiting for file lock on the registry index\n\n解决： rm -rf ~/.cargo/registry/index/*\n\n## rust redis\n- https://crates.io/crates/redis\n- https://docs.rs/redis/0.11.0-beta.2/redis/\n\n## rust mongo\n- https://crates.io/crates/mongodb\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveaba%2Flearn-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fveaba%2Flearn-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveaba%2Flearn-rust/lists"}