[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fother":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fother":1747,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fother":1773},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":13,"pinned":14,"draft":14,"body":15,"seo":1743,"stem":1744,"id":1745,"extension":1746},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fother","第十章：进阶特性与模式","Rust 的核心安全保证覆盖了绝大多数日常编程场景。但当你需要打破常规——无论是编写极致通用的抽象、与 C 库交互，还是内联优化——本章将带你进入 Rust 的深层能力：声明宏与过程宏、unsafe 的超能力与封装、高级类型系统技巧…","技能小册",[12],"rust","2023-12-29",false,{"type":16,"value":17,"toc":1699},"minimark",[18,22,31,36,39,47,54,136,139,201,204,232,235,238,279,286,309,312,405,423,427,437,439,445,504,507,510,513,545,548,552,559,602,605,629,639,643,660,664,667,674,680,700,712,719,727,736,748,752,763,766,781,829,832,835,838,917,928,932,935,976,980,987,1021,1039,1043,1050,1080,1083,1090,1166,1169,1173,1183,1189,1194,1274,1297,1304,1310,1336,1342,1353,1367,1413,1416,1422,1426,1429,1432,1435,1455,1461,1468,1482,1561,1571,1574,1577,1593,1598,1618,1625,1628,1631,1634,1695],[19,20,8],"h1",{"id":21},"第十章进阶特性与模式",[23,24,25,26,30],"p",{},"Rust 的核心安全保证覆盖了绝大多数日常编程场景。但当你需要打破常规——无论是编写极致通用的抽象、与 C 库交互，还是内联优化——本章将带你进入 Rust 的深层能力：声明宏与过程宏、",[27,28,29],"code",{},"unsafe"," 的超能力与封装、高级类型系统技巧、生命周期的高级用法、外部函数接口以及性能调优工具。这些特性让你在保留安全外壳的同时，可以触及系统编程的每一个角落。",[32,33,35],"h2",{"id":34},"_101-宏","10.1 宏",[23,37,38],{},"宏在 Rust 中不只是一堆替换规则，它们是一种编写 Rust 代码的代码，可以大幅减少重复、创造领域特定语言，并在编译期生成大量样板。",[40,41,43,44],"h3",{"id":42},"声明宏macro_rules","声明宏：",[27,45,46],{},"macro_rules!",[23,48,49,50,53],{},"声明宏基于模式匹配与重复语法。最熟悉的例子就是 ",[27,51,52],{},"vec!","：",[55,56,60],"pre",{"className":57,"code":58,"language":12,"meta":59,"style":59},"language-rust shiki shiki-themes material-theme-lighter github-light github-dark","#[macro_export]\nmacro_rules! vec {\n    ( $( $x:expr ),* ) => {\n        {\n            let mut temp_vec = Vec::new();\n            $(\n                temp_vec.push($x);\n            )*\n            temp_vec\n        }\n    };\n}\n","",[27,61,62,70,76,82,88,94,100,106,112,118,124,130],{"__ignoreMap":59},[63,64,67],"span",{"class":65,"line":66},"line",1,[63,68,69],{},"#[macro_export]\n",[63,71,73],{"class":65,"line":72},2,[63,74,75],{},"macro_rules! vec {\n",[63,77,79],{"class":65,"line":78},3,[63,80,81],{},"    ( $( $x:expr ),* ) => {\n",[63,83,85],{"class":65,"line":84},4,[63,86,87],{},"        {\n",[63,89,91],{"class":65,"line":90},5,[63,92,93],{},"            let mut temp_vec = Vec::new();\n",[63,95,97],{"class":65,"line":96},6,[63,98,99],{},"            $(\n",[63,101,103],{"class":65,"line":102},7,[63,104,105],{},"                temp_vec.push($x);\n",[63,107,109],{"class":65,"line":108},8,[63,110,111],{},"            )*\n",[63,113,115],{"class":65,"line":114},9,[63,116,117],{},"            temp_vec\n",[63,119,121],{"class":65,"line":120},10,[63,122,123],{},"        }\n",[63,125,127],{"class":65,"line":126},11,[63,128,129],{},"    };\n",[63,131,133],{"class":65,"line":132},12,[63,134,135],{},"}\n",[23,137,138],{},"核心语法要点：",[140,141,142,156,180,194],"ul",{},[143,144,145,148,149,148,152,155],"li",{},[27,146,147],{},"( ... )"," 或 ",[27,150,151],{},"[ ... ]",[27,153,154],{},"{ ... }"," 中书写匹配规则。",[143,157,158,161,162,165,166,169,170,169,173,169,176,179],{},[27,159,160],{},"$x:expr"," 捕获一个表达式，",[27,163,164],{},"expr"," 是片段分类符，还有 ",[27,167,168],{},"ident","、",[27,171,172],{},"ty",[27,174,175],{},"pat",[27,177,178],{},"literal"," 等。",[143,181,182,185,186,189,190,193],{},[27,183,184],{},"$( ... ),*"," 表示重复零次或多次，逗号为分隔符；",[27,187,188],{},"$( ... );*"," 用分号分隔，",[27,191,192],{},"$( ... )+"," 为一次或多次。",[143,195,196,197,200],{},"展开代码中 ",[27,198,199],{},"$()"," 包裹的重复部分会按捕获的次数展开。",[23,202,203],{},"另一个简单宏示例——计算指定表达式的对数并返回：",[55,205,207],{"className":57,"code":206,"language":12,"meta":59,"style":59},"macro_rules! log_warn {\n    ($($arg:tt)*) => {\n        eprintln!(\"[WARN] {}\", format!($($arg)*))\n    };\n}\n",[27,208,209,214,219,224,228],{"__ignoreMap":59},[63,210,211],{"class":65,"line":66},[63,212,213],{},"macro_rules! log_warn {\n",[63,215,216],{"class":65,"line":72},[63,217,218],{},"    ($($arg:tt)*) => {\n",[63,220,221],{"class":65,"line":78},[63,222,223],{},"        eprintln!(\"[WARN] {}\", format!($($arg)*))\n",[63,225,226],{"class":65,"line":84},[63,227,129],{},[63,229,230],{"class":65,"line":90},[63,231,135],{},[40,233,234],{"id":234},"过程宏",[23,236,237],{},"过程宏是在编译期运行 Rust 代码，对 token 流进行转换。它们分为三类：",[140,239,240,256,268],{},[143,241,242,248,249,252,253,255],{},[243,244,245],"strong",{},[27,246,247],{},"#[proc_macro]","：类似函数，接收 ",[27,250,251],{},"TokenStream","，返回 ",[27,254,251],{},"。",[143,257,258,263,264,267],{},[243,259,260],{},[27,261,262],{},"#[proc_macro_derive]","：与 ",[27,265,266],{},"#[derive(MyTrait)]"," 配合，自动为类型生成实现。",[143,269,270,275,276,255],{},[243,271,272],{},[27,273,274],{},"#[proc_macro_attribute]","：用于创建自定义属性，如 ",[27,277,278],{},"#[my_attr]",[23,280,281,282,285],{},"过程宏必须定义在一个特殊的 ",[27,283,284],{},"proc-macro = true"," 的 crate 中。常用的辅助库有：",[140,287,288,299],{},[143,289,290,295,296,298],{},[243,291,292],{},[27,293,294],{},"syn","：将 ",[27,297,251],{}," 解析为 AST。",[143,300,301,306,307,255],{},[243,302,303],{},[27,304,305],{},"quote","：将 Rust 语法树轻松转换回 ",[27,308,251],{},[23,310,311],{},"一个极简的 derive 宏示例：",[55,313,315],{"className":57,"code":314,"language":12,"meta":59,"style":59},"use proc_macro::TokenStream;\nuse quote::quote;\nuse syn;\n\n#[proc_macro_derive(Hello)]\npub fn hello_derive(input: TokenStream) -> TokenStream {\n    let ast = syn::parse(input).unwrap();\n    let name = &ast.ident;\n    let gen = quote! {\n        impl #name {\n            pub fn hello() {\n                println!(\"Hello from {}\", stringify!(#name));\n            }\n        }\n    };\n    gen.into()\n}\n",[27,316,317,322,327,332,338,343,348,353,358,363,368,373,378,384,389,394,400],{"__ignoreMap":59},[63,318,319],{"class":65,"line":66},[63,320,321],{},"use proc_macro::TokenStream;\n",[63,323,324],{"class":65,"line":72},[63,325,326],{},"use quote::quote;\n",[63,328,329],{"class":65,"line":78},[63,330,331],{},"use syn;\n",[63,333,334],{"class":65,"line":84},[63,335,337],{"emptyLinePlaceholder":336},true,"\n",[63,339,340],{"class":65,"line":90},[63,341,342],{},"#[proc_macro_derive(Hello)]\n",[63,344,345],{"class":65,"line":96},[63,346,347],{},"pub fn hello_derive(input: TokenStream) -> TokenStream {\n",[63,349,350],{"class":65,"line":102},[63,351,352],{},"    let ast = syn::parse(input).unwrap();\n",[63,354,355],{"class":65,"line":108},[63,356,357],{},"    let name = &ast.ident;\n",[63,359,360],{"class":65,"line":114},[63,361,362],{},"    let gen = quote! {\n",[63,364,365],{"class":65,"line":120},[63,366,367],{},"        impl #name {\n",[63,369,370],{"class":65,"line":126},[63,371,372],{},"            pub fn hello() {\n",[63,374,375],{"class":65,"line":132},[63,376,377],{},"                println!(\"Hello from {}\", stringify!(#name));\n",[63,379,381],{"class":65,"line":380},13,[63,382,383],{},"            }\n",[63,385,387],{"class":65,"line":386},14,[63,388,123],{},[63,390,392],{"class":65,"line":391},15,[63,393,129],{},[63,395,397],{"class":65,"line":396},16,[63,398,399],{},"    gen.into()\n",[63,401,403],{"class":65,"line":402},17,[63,404,135],{},[23,406,407,408,411,412,415,416,169,419,422],{},"使用 ",[27,409,410],{},"#[derive(Hello)]"," 后，类型即拥有 ",[27,413,414],{},"hello()"," 方法。过程宏是许多高级框架（如 ",[27,417,418],{},"serde",[27,420,421],{},"thiserror","）的基石。",[32,424,426],{"id":425},"_102-unsafe-rust","10.2 Unsafe Rust",[23,428,429,430,432,433,436],{},"尽管 Rust 的安全保证非常强大，但有些时候你需要直接与硬件、OS 交互或突破某些编译器限制。",[27,431,29],{}," 关键字并非关闭类型系统，而是开启额外的",[243,434,435],{},"超能力","，同时提醒程序员自行遵守安全契约。",[40,438,435],{"id":435},[23,440,441,442,444],{},"在 ",[27,443,29],{}," 块或函数中可以：",[446,447,448,462,471,479,494],"ol",{},[143,449,450,453,454,457,458,461],{},[243,451,452],{},"解引用裸指针","（",[27,455,456],{},"*const T"," \u002F ",[27,459,460],{},"*mut T","）。",[143,463,464,470],{},[243,465,466,467,469],{},"调用 ",[27,468,29],{}," 函数或方法","（包括 FFI）。",[143,472,473,453,476,461],{},[243,474,475],{},"访问或修改可变静态变量",[27,477,478],{},"static mut",[143,480,481,487,488,169,491,461],{},[243,482,483,484,486],{},"实现 ",[27,485,29],{}," trait","（如 ",[27,489,490],{},"Send",[27,492,493],{},"Sync",[143,495,496,503],{},[243,497,498,499,502],{},"访问 ",[27,500,501],{},"union"," 的字段","（联合体用于 C 兼容）。",[23,505,506],{},"这些操作必须由开发者手工保证内存安全，而非依赖借用检查器。",[40,508,509],{"id":509},"裸指针",[23,511,512],{},"裸指针与引用相似，但可绕过借用规则：可以自由复制、可为空、可指向无效地址。",[55,514,516],{"className":57,"code":515,"language":12,"meta":59,"style":59},"let mut x = 10;\nlet r: *mut i32 = &mut x;\nunsafe {\n    *r += 1;  \u002F\u002F 直接修改\n}\n",[27,517,518,523,528,533,541],{"__ignoreMap":59},[63,519,520],{"class":65,"line":66},[63,521,522],{},"let mut x = 10;\n",[63,524,525],{"class":65,"line":72},[63,526,527],{},"let r: *mut i32 = &mut x;\n",[63,529,530],{"class":65,"line":78},[63,531,532],{},"unsafe {\n",[63,534,535,538],{"class":65,"line":84},[63,536,537],{},"    *r += 1;",[63,539,540],{},"  \u002F\u002F 直接修改\n",[63,542,543],{"class":65,"line":90},[63,544,135],{},[23,546,547],{},"在 FFI 和性能关键代码中常见，但通常应封装在安全的抽象中。",[40,549,551],{"id":550},"外部函数接口ffi","外部函数接口（FFI）",[23,553,554,555,558],{},"通过 ",[27,556,557],{},"extern"," 块声明其他语言（通常是 C）的函数：",[55,560,562],{"className":57,"code":561,"language":12,"meta":59,"style":59},"extern \"C\" {\n    fn abs(input: i32) -> i32;\n}\nfn main() {\n    unsafe {\n        println!(\"abs(-3) = {}\", abs(-3));\n    }\n}\n",[27,563,564,569,574,578,583,588,593,598],{"__ignoreMap":59},[63,565,566],{"class":65,"line":66},[63,567,568],{},"extern \"C\" {\n",[63,570,571],{"class":65,"line":72},[63,572,573],{},"    fn abs(input: i32) -> i32;\n",[63,575,576],{"class":65,"line":78},[63,577,135],{},[63,579,580],{"class":65,"line":84},[63,581,582],{},"fn main() {\n",[63,584,585],{"class":65,"line":90},[63,586,587],{},"    unsafe {\n",[63,589,590],{"class":65,"line":96},[63,591,592],{},"        println!(\"abs(-3) = {}\", abs(-3));\n",[63,594,595],{"class":65,"line":102},[63,596,597],{},"    }\n",[63,599,600],{"class":65,"line":108},[63,601,135],{},[23,603,604],{},"反过来，也可以在 Rust 中编写可供 C 调用的函数：",[55,606,608],{"className":57,"code":607,"language":12,"meta":59,"style":59},"#[no_mangle]\npub extern \"C\" fn call_from_c() {\n    println!(\"Called from C!\");\n}\n",[27,609,610,615,620,625],{"__ignoreMap":59},[63,611,612],{"class":65,"line":66},[63,613,614],{},"#[no_mangle]\n",[63,616,617],{"class":65,"line":72},[63,618,619],{},"pub extern \"C\" fn call_from_c() {\n",[63,621,622],{"class":65,"line":78},[63,623,624],{},"    println!(\"Called from C!\");\n",[63,626,627],{"class":65,"line":84},[63,628,135],{},[23,630,631,634,635,638],{},[27,632,633],{},"extern \"C\""," 遵循 C 的调用约定，",[27,636,637],{},"#[no_mangle]"," 阻止函数名被改写。",[40,640,642],{"id":641},"unsafe-最小化原则与安全封装","unsafe 最小化原则与安全封装",[23,644,645,646,648,649,652,653,655,656,659],{},"编写 Rust 代码时，通常将 ",[27,647,29],{}," 代码封装在安全抽象之后。例如 ",[27,650,651],{},"Vec"," 内部大量使用裸指针，但向外暴露完全安全的 API。你应确保无论调用者怎样使用安全 API，都不会导致未定义行为。推荐在 ",[27,654,29],{}," 块旁添加 ",[27,657,658],{},"SAFETY"," 注释，说明遵守了哪些前置条件。",[32,661,663],{"id":662},"_103-高级类型","10.3 高级类型",[23,665,666],{},"Rust 的类型系统有若干细节，深入理解能让你写出更灵活、更高效的泛型代码。",[40,668,670,673],{"id":669},"sized-与动态大小类型dst",[27,671,672],{},"Sized"," 与动态大小类型（DST）",[23,675,676,677,679],{},"大部分类型在编译期大小固定（",[27,678,672],{},"），但某些类型的大小要到运行时才知道，称为 DST。典型的有：",[140,681,682,688,694],{},[143,683,684,687],{},[27,685,686],{},"str","（字符串切片）",[143,689,690,693],{},[27,691,692],{},"[T]","（切片）",[143,695,696,697],{},"动态 trait 对象 ",[27,698,699],{},"dyn Trait",[23,701,702,703,169,706,169,709,255],{},"DST 不能直接作为栈变量，必须放在指针之后，如 ",[27,704,705],{},"&str",[27,707,708],{},"Box\u003C[T]>",[27,710,711],{},"Arc\u003Cdyn Fn()>",[40,713,715,718],{"id":714},"sized-放宽限制",[27,716,717],{},"?Sized"," 放宽限制",[23,720,721,722,724,725,53],{},"泛型参数默认隐含 ",[27,723,672],{}," 约束。若要支持 DST，可显式使用 ",[27,726,717],{},[55,728,730],{"className":57,"code":729,"language":12,"meta":59,"style":59},"fn generic\u003CT: ?Sized>(t: &T) { ... }\n",[27,731,732],{"__ignoreMap":59},[63,733,734],{"class":65,"line":66},[63,735,729],{},[23,737,738,739,742,743,148,745,179],{},"这样 ",[27,740,741],{},"T"," 就可以是 ",[27,744,686],{},[27,746,747],{},"[u8]",[40,749,751],{"id":750},"零大小类型zst","零大小类型（ZST）",[23,753,754,755,758,759,762],{},"某些类型的实例不占任何空间，比如单元类型 ",[27,756,757],{},"()","、单元结构体、空数组 ",[27,760,761],{},"[u32; 0]"," 等。ZST 在编译期被优化掉，很适合用作标记或状态类型。",[40,764,765],{"id":765},"幻影类型参数",[23,767,768,769,772,773,776,777,780],{},"当泛型参数仅用于标记约束，而不在结构体字段中实际使用时，需用 ",[27,770,771],{},"PhantomData\u003CT>"," 告知编译器",[243,774,775],{},"拥有","或",[243,778,779],{},"使用","了该类型，避免编译错误：",[55,782,784],{"className":57,"code":783,"language":12,"meta":59,"style":59},"use std::marker::PhantomData;\n\nstruct Inches;\nstruct Centimeters;\nstruct Length\u003CT> {\n    value: f64,\n    _unit: PhantomData\u003CT>,\n}\nlet len_in: Length\u003CInches> = Length { value: 10.0, _unit: PhantomData };\n",[27,785,786,791,795,800,805,810,815,820,824],{"__ignoreMap":59},[63,787,788],{"class":65,"line":66},[63,789,790],{},"use std::marker::PhantomData;\n",[63,792,793],{"class":65,"line":72},[63,794,337],{"emptyLinePlaceholder":336},[63,796,797],{"class":65,"line":78},[63,798,799],{},"struct Inches;\n",[63,801,802],{"class":65,"line":84},[63,803,804],{},"struct Centimeters;\n",[63,806,807],{"class":65,"line":90},[63,808,809],{},"struct Length\u003CT> {\n",[63,811,812],{"class":65,"line":96},[63,813,814],{},"    value: f64,\n",[63,816,817],{"class":65,"line":102},[63,818,819],{},"    _unit: PhantomData\u003CT>,\n",[63,821,822],{"class":65,"line":108},[63,823,135],{},[63,825,826],{"class":65,"line":114},[63,827,828],{},"let len_in: Length\u003CInches> = Length { value: 10.0, _unit: PhantomData };\n",[23,830,831],{},"这能防止不同单位的长度互相赋值，且没有运行时成本。",[40,833,834],{"id":834},"类型状态模式",[23,836,837],{},"通过将状态编码为泛型参数，可将状态的合法转换交由编译器在编译期检查。比如一个构建器模式：",[55,839,841],{"className":57,"code":840,"language":12,"meta":59,"style":59},"struct Draft;\nstruct Published;\n\nstruct Post\u003CState> {\n    content: String,\n    _state: PhantomData\u003CState>,\n}\n\nimpl Post\u003CDraft> {\n    fn new() -> Self { ... }\n    fn publish(self) -> Post\u003CPublished> { ... }\n}\n\nimpl Post\u003CPublished> {\n    fn content(&self) -> &str { &self.content }\n}\n",[27,842,843,848,853,857,862,867,872,876,880,885,890,895,899,903,908,913],{"__ignoreMap":59},[63,844,845],{"class":65,"line":66},[63,846,847],{},"struct Draft;\n",[63,849,850],{"class":65,"line":72},[63,851,852],{},"struct Published;\n",[63,854,855],{"class":65,"line":78},[63,856,337],{"emptyLinePlaceholder":336},[63,858,859],{"class":65,"line":84},[63,860,861],{},"struct Post\u003CState> {\n",[63,863,864],{"class":65,"line":90},[63,865,866],{},"    content: String,\n",[63,868,869],{"class":65,"line":96},[63,870,871],{},"    _state: PhantomData\u003CState>,\n",[63,873,874],{"class":65,"line":102},[63,875,135],{},[63,877,878],{"class":65,"line":108},[63,879,337],{"emptyLinePlaceholder":336},[63,881,882],{"class":65,"line":114},[63,883,884],{},"impl Post\u003CDraft> {\n",[63,886,887],{"class":65,"line":120},[63,888,889],{},"    fn new() -> Self { ... }\n",[63,891,892],{"class":65,"line":126},[63,893,894],{},"    fn publish(self) -> Post\u003CPublished> { ... }\n",[63,896,897],{"class":65,"line":132},[63,898,135],{},[63,900,901],{"class":65,"line":380},[63,902,337],{"emptyLinePlaceholder":336},[63,904,905],{"class":65,"line":386},[63,906,907],{},"impl Post\u003CPublished> {\n",[63,909,910],{"class":65,"line":391},[63,911,912],{},"    fn content(&self) -> &str { &self.content }\n",[63,914,915],{"class":65,"line":396},[63,916,135],{},[23,918,919,920,923,924,927],{},"调用者无法在 ",[27,921,922],{},"Draft"," 状态调用 ",[27,925,926],{},"content","，状态转换由类型系统保证安全。",[32,929,931],{"id":930},"_104-高级生命周期与借用","10.4 高级生命周期与借用",[40,933,934],{"id":934},"子类型与变性",[23,936,937,938,453,941,944,945,948,949,952,953,956,957,960,961,963,964,966,967,969,970,963,973,975],{},"生命周期之间的关系服从子类型关系：如果 ",[27,939,940],{},"'a: 'b",[27,942,943],{},"'a"," 比 ",[27,946,947],{},"'b"," 长），那么 ",[27,950,951],{},"&'a T"," 是 ",[27,954,955],{},"&'b T"," 的子类型。Rust 的类型系统在处理复合类型时遵循",[243,958,959],{},"变性","规则：例如 ",[27,962,951],{}," 在 ",[27,965,943],{}," 上是协变，在 ",[27,968,741],{}," 上也是协变；而 ",[27,971,972],{},"&mut T",[27,974,741],{}," 上是不变。这些规则保证了安全的引用关系。",[40,977,979],{"id":978},"高阶生命周期hrtb","高阶生命周期（HRTB）",[23,981,982,983,986],{},"当函数的泛型参数是一个接收引用的闭包时，你会遇到“对于所有生命周期都成立”这样的场景。高阶生命周期用 ",[27,984,985],{},"for\u003C'a>"," 表示：",[55,988,990],{"className":57,"code":989,"language":12,"meta":59,"style":59},"fn apply\u003CF>(f: F)\nwhere\n    F: for\u003C'a> Fn(&'a str) -> &'a str,\n{\n    println!(\"{}\", f(\"hello\"));\n}\n",[27,991,992,997,1002,1007,1012,1017],{"__ignoreMap":59},[63,993,994],{"class":65,"line":66},[63,995,996],{},"fn apply\u003CF>(f: F)\n",[63,998,999],{"class":65,"line":72},[63,1000,1001],{},"where\n",[63,1003,1004],{"class":65,"line":78},[63,1005,1006],{},"    F: for\u003C'a> Fn(&'a str) -> &'a str,\n",[63,1008,1009],{"class":65,"line":84},[63,1010,1011],{},"{\n",[63,1013,1014],{"class":65,"line":90},[63,1015,1016],{},"    println!(\"{}\", f(\"hello\"));\n",[63,1018,1019],{"class":65,"line":96},[63,1020,135],{},[23,1022,1023,1024,1027,1028,1031,1032,1034,1035,1038],{},"这意味着闭包 ",[27,1025,1026],{},"F"," 必须能处理",[243,1029,1030],{},"任意","生命周期 ",[27,1033,943],{}," 的引用，并返回同一生命周期的引用。这通常用于 ",[27,1036,1037],{},"Fn"," 等闭包 trait 的 trait bound，在标准库的迭代器适配器中很常见。",[40,1040,1042],{"id":1041},"非词法作用域生命周期nll详解","非词法作用域生命周期（NLL）详解",[23,1044,1045,1046,1049],{},"Rust 1.31 之前，借用持续到所在词法作用域结束。NLL 使其持续到变量",[243,1047,1048],{},"最后一次使用","为止。这对于编写符合直觉的代码至关重要。示例：",[55,1051,1053],{"className":57,"code":1052,"language":12,"meta":59,"style":59},"let mut data = vec![1, 2, 3];\nlet r = &data;\nprintln!(\"{:?}\", r); \u002F\u002F r 最后一次使用\nlet s = &mut data;   \u002F\u002F 合法，因为 r 已不再存活\ns.push(4);\n",[27,1054,1055,1060,1065,1070,1075],{"__ignoreMap":59},[63,1056,1057],{"class":65,"line":66},[63,1058,1059],{},"let mut data = vec![1, 2, 3];\n",[63,1061,1062],{"class":65,"line":72},[63,1063,1064],{},"let r = &data;\n",[63,1066,1067],{"class":65,"line":78},[63,1068,1069],{},"println!(\"{:?}\", r); \u002F\u002F r 最后一次使用\n",[63,1071,1072],{"class":65,"line":84},[63,1073,1074],{},"let s = &mut data;   \u002F\u002F 合法，因为 r 已不再存活\n",[63,1076,1077],{"class":65,"line":90},[63,1078,1079],{},"s.push(4);\n",[40,1081,1082],{"id":1082},"借用分割",[23,1084,1085,1086,1089],{},"当方法借用了结构体的不同字段时，编译器会聪明地允许对结构体进行部分借用。调用 ",[27,1087,1088],{},"split_at_mut"," 之类的函数非常自然，因为 Rust 可以分辨出可变借用分别作用于不重叠的字段。",[55,1091,1093],{"className":57,"code":1092,"language":12,"meta":59,"style":59},"struct Point {\n    x: i32,\n    y: i32,\n}\nimpl Point {\n    fn set_x(&mut self, x: i32) {\n        self.x = x;\n    }\n    fn set_y(&mut self, y: i32) {\n        self.y = y;\n    }\n}\nlet mut p = Point { x: 1, y: 2 };\np.set_x(3);  \u002F\u002F 借用 x\np.set_y(4);  \u002F\u002F 借用 y，不冲突\n",[27,1094,1095,1100,1105,1110,1114,1119,1124,1129,1133,1138,1143,1147,1151,1156,1161],{"__ignoreMap":59},[63,1096,1097],{"class":65,"line":66},[63,1098,1099],{},"struct Point {\n",[63,1101,1102],{"class":65,"line":72},[63,1103,1104],{},"    x: i32,\n",[63,1106,1107],{"class":65,"line":78},[63,1108,1109],{},"    y: i32,\n",[63,1111,1112],{"class":65,"line":84},[63,1113,135],{},[63,1115,1116],{"class":65,"line":90},[63,1117,1118],{},"impl Point {\n",[63,1120,1121],{"class":65,"line":96},[63,1122,1123],{},"    fn set_x(&mut self, x: i32) {\n",[63,1125,1126],{"class":65,"line":102},[63,1127,1128],{},"        self.x = x;\n",[63,1130,1131],{"class":65,"line":108},[63,1132,597],{},[63,1134,1135],{"class":65,"line":114},[63,1136,1137],{},"    fn set_y(&mut self, y: i32) {\n",[63,1139,1140],{"class":65,"line":120},[63,1141,1142],{},"        self.y = y;\n",[63,1144,1145],{"class":65,"line":126},[63,1146,597],{},[63,1148,1149],{"class":65,"line":132},[63,1150,135],{},[63,1152,1153],{"class":65,"line":380},[63,1154,1155],{},"let mut p = Point { x: 1, y: 2 };\n",[63,1157,1158],{"class":65,"line":386},[63,1159,1160],{},"p.set_x(3);  \u002F\u002F 借用 x\n",[63,1162,1163],{"class":65,"line":391},[63,1164,1165],{},"p.set_y(4);  \u002F\u002F 借用 y，不冲突\n",[23,1167,1168],{},"这种精细度在组合不同字段时无需整体可变借用，极大提高了可用性。",[32,1170,1172],{"id":1171},"_105-ffi-与与-c-交互","10.5 FFI 与与 C 交互",[23,1174,1175,1176,1178,1179,1182],{},"与 C 的互操作是系统编程的常见需求，Rust 通过 ",[27,1177,557],{}," 块和 ",[27,1180,1181],{},"libc"," crate 提供直接支持。",[40,1184,1186,1188],{"id":1185},"libc-crate-与类型对应",[27,1187,1181],{}," crate 与类型对应",[23,1190,1191,1193],{},[27,1192,1181],{}," crate 提供了与 C 兼容的类型定义和平台常量。典型映射：",[1195,1196,1197,1210],"table",{},[1198,1199,1200],"thead",{},[1201,1202,1203,1207],"tr",{},[1204,1205,1206],"th",{},"Rust 类型",[1204,1208,1209],{},"C 类型",[1211,1212,1213,1227,1239,1250,1262],"tbody",{},[1201,1214,1215,1221],{},[1216,1217,1218],"td",{},[27,1219,1220],{},"i8",[1216,1222,1223,1226],{},[27,1224,1225],{},"char","（用于数值）",[1201,1228,1229,1234],{},[1216,1230,1231],{},[27,1232,1233],{},"c_int",[1216,1235,1236],{},[27,1237,1238],{},"int",[1201,1240,1241,1246],{},[1216,1242,1243],{},[27,1244,1245],{},"c_char",[1216,1247,1248],{},[27,1249,1225],{},[1201,1251,1252,1257],{},[1216,1253,1254],{},[27,1255,1256],{},"c_long",[1216,1258,1259],{},[27,1260,1261],{},"long",[1201,1263,1264,1269],{},[1216,1265,1266],{},[27,1267,1268],{},"c_void",[1216,1270,1271],{},[27,1272,1273],{},"void",[55,1275,1277],{"className":57,"code":1276,"language":12,"meta":59,"style":59},"use std::os::raw::c_int;\nextern \"C\" {\n    fn abs(input: c_int) -> c_int;\n}\n",[27,1278,1279,1284,1288,1293],{"__ignoreMap":59},[63,1280,1281],{"class":65,"line":66},[63,1282,1283],{},"use std::os::raw::c_int;\n",[63,1285,1286],{"class":65,"line":72},[63,1287,568],{},[63,1289,1290],{"class":65,"line":78},[63,1291,1292],{},"    fn abs(input: c_int) -> c_int;\n",[63,1294,1295],{"class":65,"line":84},[63,1296,135],{},[40,1298,1300,1303],{"id":1299},"link-与外部库",[27,1301,1302],{},"#[link]"," 与外部库",[23,1305,554,1306,1309],{},[27,1307,1308],{},"#[link(name = \"foo\")]"," 告知 Rust 链接特定的 C 库：",[55,1311,1313],{"className":57,"code":1312,"language":12,"meta":59,"style":59},"#[link(name = \"m\")] \u002F\u002F 数学库\nextern \"C\" {\n    fn sqrt(x: f64) -> f64;\n}\n",[27,1314,1315,1323,1327,1332],{"__ignoreMap":59},[63,1316,1317,1320],{"class":65,"line":66},[63,1318,1319],{},"#[link(name = \"m\")]",[63,1321,1322],{}," \u002F\u002F 数学库\n",[63,1324,1325],{"class":65,"line":72},[63,1326,568],{},[63,1328,1329],{"class":65,"line":78},[63,1330,1331],{},"    fn sqrt(x: f64) -> f64;\n",[63,1333,1334],{"class":65,"line":84},[63,1335,135],{},[23,1337,1338,1339,1341],{},"内部 ",[27,1340,557],{}," 块包含函数签名；实际的库在链接时被解析。",[40,1343,1345,1346,1349,1350],{"id":1344},"字符串转换cstring-与-cstr","字符串转换：",[27,1347,1348],{},"CString"," 与 ",[27,1351,1352],{},"CStr",[23,1354,1355,1356,1359,1360,1363,1364,1366],{},"Rust 使用 ",[27,1357,1358],{},"std::ffi::CString"," 表示拥有所有权的、符合 C 用法的字符串（以 null 结尾，无内部 null），对应 C 的 ",[27,1361,1362],{},"char*","；",[27,1365,1352],{}," 是对其的借用。",[55,1368,1370],{"className":57,"code":1369,"language":12,"meta":59,"style":59},"use std::ffi::CString;\nuse std::os::raw::c_char;\n\nextern \"C\" { fn puts(s: *const c_char) -> c_int; }\n\nlet c_string = CString::new(\"Hello from Rust\").unwrap();\nunsafe {\n    puts(c_string.as_ptr());\n}\n",[27,1371,1372,1377,1382,1386,1391,1395,1400,1404,1409],{"__ignoreMap":59},[63,1373,1374],{"class":65,"line":66},[63,1375,1376],{},"use std::ffi::CString;\n",[63,1378,1379],{"class":65,"line":72},[63,1380,1381],{},"use std::os::raw::c_char;\n",[63,1383,1384],{"class":65,"line":78},[63,1385,337],{"emptyLinePlaceholder":336},[63,1387,1388],{"class":65,"line":84},[63,1389,1390],{},"extern \"C\" { fn puts(s: *const c_char) -> c_int; }\n",[63,1392,1393],{"class":65,"line":90},[63,1394,337],{"emptyLinePlaceholder":336},[63,1396,1397],{"class":65,"line":96},[63,1398,1399],{},"let c_string = CString::new(\"Hello from Rust\").unwrap();\n",[63,1401,1402],{"class":65,"line":102},[63,1403,532],{},[63,1405,1406],{"class":65,"line":108},[63,1407,1408],{},"    puts(c_string.as_ptr());\n",[63,1410,1411],{"class":65,"line":114},[63,1412,135],{},[40,1414,1415],{"id":1415},"不安全与安全封装",[23,1417,1418,1419,1421],{},"FFI 总是位于 ",[27,1420,29],{}," 块中，最佳实践是为外部函数提供安全的 Rust 封装，检查所有参数、转换错误码、确保资源释放。",[32,1423,1425],{"id":1424},"_106-性能与内联","10.6 性能与内联",[23,1427,1428],{},"Rust 的零开销抽象承诺依靠编译器优化和开发者控制来实现。了解内联、profile 和检查汇编是调优性能的关键。",[40,1430,1431],{"id":1431},"内联属性",[23,1433,1434],{},"编译器会自主进行内联决策，但可通过属性微调：",[140,1436,1437,1443,1449],{},[143,1438,1439,1442],{},[27,1440,1441],{},"#[inline]"," 提示编译器应在跨 crate 调用的位置考虑内联。",[143,1444,1445,1448],{},[27,1446,1447],{},"#[inline(always)]"," 强制内联（需小心代码膨胀）。",[143,1450,1451,1454],{},[27,1452,1453],{},"#[inline(never)]"," 阻止内联。",[23,1456,1457,1458,1460],{},"通常只对小函数使用 ",[27,1459,1441],{},"，让 LLVM 与你的意图更好地协作。",[40,1462,1464,1465],{"id":1463},"profile-与基准测试criterion","profile 与基准测试：",[27,1466,1467],{},"criterion",[23,1469,1470,1477,1478,1481],{},[1471,1472,1476],"a",{"href":1473,"rel":1474},"https:\u002F\u002Fgithub.com\u002Fbheisler\u002Fcriterion.rs",[1475],"nofollow","Criterion.rs"," 是 Rust 生态标准的统计基准测试库。在 ",[27,1479,1480],{},"benches\u002F"," 目录编写基准：",[55,1483,1485],{"className":57,"code":1484,"language":12,"meta":59,"style":59},"use criterion::{black_box, criterion_group, criterion_main, Criterion};\n\nfn fibonacci(n: u64) -> u64 {\n    match n {\n        0 => 1,\n        1 => 1,\n        n => fibonacci(n-1) + fibonacci(n-2),\n    }\n}\n\nfn criterion_benchmark(c: &mut Criterion) {\n    c.bench_function(\"fib 20\", |b| b.iter(|| fibonacci(black_box(20))));\n}\n\ncriterion_group!(benches, criterion_benchmark);\ncriterion_main!(benches);\n",[27,1486,1487,1492,1496,1501,1506,1511,1516,1521,1525,1529,1533,1538,1543,1547,1551,1556],{"__ignoreMap":59},[63,1488,1489],{"class":65,"line":66},[63,1490,1491],{},"use criterion::{black_box, criterion_group, criterion_main, Criterion};\n",[63,1493,1494],{"class":65,"line":72},[63,1495,337],{"emptyLinePlaceholder":336},[63,1497,1498],{"class":65,"line":78},[63,1499,1500],{},"fn fibonacci(n: u64) -> u64 {\n",[63,1502,1503],{"class":65,"line":84},[63,1504,1505],{},"    match n {\n",[63,1507,1508],{"class":65,"line":90},[63,1509,1510],{},"        0 => 1,\n",[63,1512,1513],{"class":65,"line":96},[63,1514,1515],{},"        1 => 1,\n",[63,1517,1518],{"class":65,"line":102},[63,1519,1520],{},"        n => fibonacci(n-1) + fibonacci(n-2),\n",[63,1522,1523],{"class":65,"line":108},[63,1524,597],{},[63,1526,1527],{"class":65,"line":114},[63,1528,135],{},[63,1530,1531],{"class":65,"line":120},[63,1532,337],{"emptyLinePlaceholder":336},[63,1534,1535],{"class":65,"line":126},[63,1536,1537],{},"fn criterion_benchmark(c: &mut Criterion) {\n",[63,1539,1540],{"class":65,"line":132},[63,1541,1542],{},"    c.bench_function(\"fib 20\", |b| b.iter(|| fibonacci(black_box(20))));\n",[63,1544,1545],{"class":65,"line":380},[63,1546,135],{},[63,1548,1549],{"class":65,"line":386},[63,1550,337],{"emptyLinePlaceholder":336},[63,1552,1553],{"class":65,"line":391},[63,1554,1555],{},"criterion_group!(benches, criterion_benchmark);\n",[63,1557,1558],{"class":65,"line":396},[63,1559,1560],{},"criterion_main!(benches);\n",[23,1562,407,1563,1566,1567,1570],{},[27,1564,1565],{},"cargo bench"," 运行，获得统计结果。",[27,1568,1569],{},"black_box"," 防止编译器优化掉计算。",[40,1572,1573],{"id":1573},"零成本抽象验证",[23,1575,1576],{},"想确认高阶代码被优化为精简指令，可借助：",[140,1578,1579,1587],{},[143,1580,1581,1586],{},[243,1582,1583],{},[27,1584,1585],{},"cargo-asm","：查看函数的汇编输出。",[143,1588,1589,1592],{},[243,1590,1591],{},"Compiler Explorer (godbolt.org)","：在线查看 Rust 优化结果。",[23,1594,1595,1596,53],{},"示例使用 ",[27,1597,1585],{},[55,1599,1603],{"className":1600,"code":1601,"language":1602,"meta":59,"style":59},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","cargo asm my_crate::my_function\n","bash",[27,1604,1605],{"__ignoreMap":59},[63,1606,1607,1611,1615],{"class":65,"line":66},[63,1608,1610],{"class":1609},"sbgvK","cargo",[63,1612,1614],{"class":1613},"s_sjI"," asm",[63,1616,1617],{"class":1613}," my_crate::my_function\n",[23,1619,1620,1621,1624],{},"你会看到迭代器链被编译为与 ",[27,1622,1623],{},"for"," 循环完全一致的代码，没有额外开销。这种透明性是信任高层抽象的依据。",[23,1626,1627],{},"通过了解汇编，你可以验证是否发生了意外的动态分发或边界检查，并指导进一步优化。",[23,1629,1630],{},"至此，你已对 Rust 的宏系统、不安全超能力、高级类型技巧、生命周期深层规则、FFI 和性能调优有了全面认识。这些进阶知识让你能够在安全抽象和底层控制之间自如游走，构建出既高效又可靠的系统级软件。",[32,1632,1633],{"id":1633},"参考文献",[1195,1635,1636,1646],{},[1198,1637,1638],{},[1201,1639,1640,1643],{},[1204,1641,1642],{},"资料",[1204,1644,1645],{},"说明",[1211,1647,1648,1660,1673,1685],{},[1201,1649,1650,1657],{},[1216,1651,1652],{},[1471,1653,1656],{"href":1654,"rel":1655},"https:\u002F\u002Fdoc.rust-lang.org\u002Fbook\u002Fch19-06-macros.html",[1475],"Macros",[1216,1658,1659],{},"声明宏",[1201,1661,1662,1669],{},[1216,1663,1664],{},[1471,1665,1668],{"href":1666,"rel":1667},"https:\u002F\u002Fdoc.rust-lang.org\u002Fbook\u002Fch19-01-unsafe-rust.html",[1475],"Unsafe Rust",[1216,1670,1671],{},[27,1672,29],{},[1201,1674,1675,1682],{},[1216,1676,1677],{},[1471,1678,1681],{"href":1679,"rel":1680},"https:\u002F\u002Fdoc.rust-lang.org\u002Fnomicon\u002Fffi.html",[1475],"FFI",[1216,1683,1684],{},"Rustonomicon · FFI",[1201,1686,1687,1692],{},[1216,1688,1689],{},[1471,1690,1476],{"href":1473,"rel":1691},[1475],[1216,1693,1694],{},"基准测试",[1696,1697,1698],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":59,"searchDepth":72,"depth":72,"links":1700},[1701,1706,1712,1721,1727,1736,1742],{"id":34,"depth":72,"text":35,"children":1702},[1703,1705],{"id":42,"depth":78,"text":1704},"声明宏：macro_rules!",{"id":234,"depth":78,"text":234},{"id":425,"depth":72,"text":426,"children":1707},[1708,1709,1710,1711],{"id":435,"depth":78,"text":435},{"id":509,"depth":78,"text":509},{"id":550,"depth":78,"text":551},{"id":641,"depth":78,"text":642},{"id":662,"depth":72,"text":663,"children":1713},[1714,1716,1718,1719,1720],{"id":669,"depth":78,"text":1715},"Sized 与动态大小类型（DST）",{"id":714,"depth":78,"text":1717},"?Sized 放宽限制",{"id":750,"depth":78,"text":751},{"id":765,"depth":78,"text":765},{"id":834,"depth":78,"text":834},{"id":930,"depth":72,"text":931,"children":1722},[1723,1724,1725,1726],{"id":934,"depth":78,"text":934},{"id":978,"depth":78,"text":979},{"id":1041,"depth":78,"text":1042},{"id":1082,"depth":78,"text":1082},{"id":1171,"depth":72,"text":1172,"children":1728},[1729,1731,1733,1735],{"id":1185,"depth":78,"text":1730},"libc crate 与类型对应",{"id":1299,"depth":78,"text":1732},"#[link] 与外部库",{"id":1344,"depth":78,"text":1734},"字符串转换：CString 与 CStr",{"id":1415,"depth":78,"text":1415},{"id":1424,"depth":72,"text":1425,"children":1737},[1738,1739,1741],{"id":1431,"depth":78,"text":1431},{"id":1463,"depth":78,"text":1740},"profile 与基准测试：criterion",{"id":1573,"depth":78,"text":1573},{"id":1633,"depth":72,"text":1633},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fend\u002FRust\u002Fother","knowledge\u002Fknowledge\u002Fbooklet\u002Fend\u002FRust\u002Fother.md","md",{"items":1748},[1749,1753,1757,1761,1765,1769],{"path":1750,"title":1751,"description":1752,"category":10,"score":96},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fdocs","第八章：测试、文档与质量","Rust 将测试和文档视为语言的一等公民。通过内置的测试框架，你可以在项目里编写单元测试、集成测试以及随文档一起运行的示例测试，三者共用 cargo test 命令。配合 cargo doc 生成文档，形成了一套确保代码质量与可维护性…",{"path":1754,"title":1755,"description":1756,"category":10,"score":96},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Ft","泛型与 Trait","泛型和 trait 是 Rust 实现代码复用与多态的两大支柱。前置：Rust 基础。泛型让代码可以工作在多种类型上而不牺牲性能，trait 定义了类型间的共享行为，二者结合形成了零成本抽象的强大表达能力。本章将深入泛型定义、trai…",{"path":1758,"title":1759,"description":1760,"category":10,"score":96},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Ftype","第二章：基础语法与类型","Rust 的类型系统和语法设计处处体现着“安全”与“显式”的理念。这一章你将掌握变量绑定、基本类型、复合类型、函数定义以及所有基础控制流结构，它们是你写出任何 Rust 程序的基石。",{"path":1762,"title":1763,"description":1764,"category":10,"score":96},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fpackage","第七章：模块系统与包管理","Rust 的模块系统为代码组织、封装和复用提供了一套严谨但灵活的机制。包、crate、模块以及 use 路径相互配合，让你能够把项目拆解成清晰的功能单元，同时精确控制哪些对外可见。本章将带你系统掌握这些构建大型 Rust 项目所必需的…",{"path":1766,"title":1767,"description":1768,"category":10,"score":96},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Ferror","第五章：错误处理","Rust 将错误明确分为两类：不可恢复的错误与可恢复的错误。通过 panic! 处理前一种，Result 处理后一种，这让程序的错误路径不再是隐式的控制流，而是强类型、必须处理的代码分支。配合 Option 对缺失值的处理以及丰富的组…",{"path":1770,"title":1771,"description":1772,"category":10,"score":96},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fcore","第三章：所有权、借用与生命周期（核心）","所有权系统是 Rust 最独特、最核心的语言特性。它让 Rust 无需垃圾回收器就能保证内存安全，并在编译期消除数据竞争。本章你将深入理解所有权如何运转、引用和借用如何被检查、生命周期如何标注，以及常见智能指针如何扩展所有权模型。",{"series":1774,"title":12,"items":1775,"index":96,"prev":1801,"next":1802},"booklet\u002Fend\u002Frust",[1776,1780,1784,1786,1790,1792,1794,1795,1797,1799],{"path":1777,"title":1778,"date":1779,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fasync","第九章：并发与异步","2020-05-22",{"path":1781,"title":1782,"date":1783,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fbase","Rust 基础","2020-07-21",{"path":1770,"title":1771,"date":1785,"pinned":14},"2023-05-09",{"path":1787,"title":1788,"date":1789,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Frust\u002Fdata-type","第四章：复合数据类型","2021-02-24",{"path":1750,"title":1751,"date":1791,"pinned":14},"2026-01-11",{"path":1766,"title":1767,"date":1793,"pinned":14},"2023-11-03",{"path":7,"title":8,"date":13,"pinned":14},{"path":1762,"title":1763,"date":1796,"pinned":14},"2024-05-26",{"path":1754,"title":1755,"date":1798,"pinned":14},"2024-10-31",{"path":1758,"title":1759,"date":1800,"pinned":14},"2024-08-31",{"path":1766,"title":1767,"date":1793,"pinned":14},{"path":1762,"title":1763,"date":1796,"pinned":14}]