第5ç« å¼ç¨
# 第5ç« å¼ç¨
åºä¸è½å¸¦æ¥æ°çéå¶ã ââ马å ·米åï¼Mark Millerï¼
å°ç®å为æ¢ï¼æä»¬è§è¿çæææéç±»åââç®åçå æéBox<T>ï¼ä»¥åStringåVecå¼å
é¨çæéââ齿¯æ¥ææææçæéï¼å½ææè
è¢«ä¸¢å¼æ¶ï¼è¢«æåç对象ä¹ä¼éä¹è¢«ä¸¢å¼ãRustè¿æä¸ç§éæ¥ææææçæéç±»åï¼ç§°ä¸ºå¼ç¨ï¼referenceï¼ï¼å®å¯¹ææå对象ççå½å¨ææ²¡æå½±åã
äºå®ä¸ï¼æ 嵿°æ°ç¸åï¼å¼ç¨ççå½å¨æç»ä¸è½é¿äºå®ææåç对象ãä½ å¿ é¡»å¨ä»£ç ä¸æç¡®è¡¨æï¼ä»»ä½å¼ç¨é½ä¸å¯è½æ¯å®æåçå¼ççå½å¨ææ´é¿ã为äºå¼ºè°è¿ä¸ç¹ï¼Rustå°å建对æä¸ªå¼çå¼ç¨ç§°ä¸ºåç¨ï¼borrowingï¼è¯¥å¼ï¼ä½ åçä¸è¥¿ï¼æç»å¿ é¡»å½è¿ç»ææè ã
å¦æä½ å¨è¯»å°âä½ å¿ é¡»å¨ä»£ç ä¸æç¡®è¡¨æâè¿å¥è¯æ¶å¿é产çäºä¸ä¸æçï¼é£ä½ å¹¶ä¸å¤åãå¼ç¨æ¬èº«å¹¶æ²¡æä»ä¹ç¹å«ä¹å¤ââå¨åºå±ï¼å®ä»¬åªæ¯å°åãä½ç¡®ä¿å¼ç¨å®å ¨çè§å对Rustæ¥è¯´æ¯å ¨æ°çï¼å¨ç ç©¶æ§è¯è¨ä¹å¤ï¼ä½ ä¹å仿ªè§è¿ç±»ä¼¼çè§åãè½ç¶è¿äºè§åæ¯Rust䏿龿æ¡çé¨åï¼ä½å®ä»¬è½å¨ç¼è¯æ¶é²æ¢å¤§éç»å ¸çæ¥å¸¸é误ï¼èä¸å¯¹å¤çº¿ç¨ç¼ç¨ä¹ææå¤§ç帮å©ï¼ä¸ä¼äº§çè¿è¡æ¶æ§è½æèãè¿å次ä½ç°äºRustç大èå°è¯ã
卿¬ç« ä¸ï¼æä»¬å°æ·±å ¥æ¢è®¨å¼ç¨å¨Rustä¸çå·¥ä½åçï¼å±ç¤ºå¼ç¨ã彿°åç¨æ·èªå®ä¹ç±»åå¦ä½é½å å«çå½å¨æä¿¡æ¯ï¼ä»¥ç¡®ä¿å®ä»¬è¢«å®å ¨ä½¿ç¨ï¼å¹¶ä¸¾ä¾è¯´æè¿äºæªæ½å¨ç¼è¯æ¶å°±è½é²æ¢çä¸äºå¸¸è§é误类åï¼èä¸ä¸ä¼å¸¦æ¥è¿è¡æ¶æ§è½æå¤±ã
# å¼çå¼ç¨
ä¾å¦ï¼å设æä»¬è¦æå»ºä¸ä¸ªæèºå¤å ´æ¶ææäººææ§çèºæ¯å®¶åå ¶èåä½åçè¡¨æ ¼ãRustçæ ååºå å«åå¸è¡¨ç±»åï¼æä»¥æä»¬å¯ä»¥è¿æ ·å®ä¹æä»¬çç±»åï¼
use std::collections::HashMap;
type Table = HashMap<String, Vec<String>>;
2
3
æ¢å¥è¯è¯´ï¼è¿æ¯ä¸ä¸ªå°String弿 å°å°Vec<String>å¼çåå¸è¡¨ï¼æèºæ¯å®¶çååæ å°å°ä»ä»¬ä½åçååå表ãä½ å¯ä»¥ä½¿ç¨for循ç¯éåHashMapçæ¡ç®ï¼æä»¥æä»¬å¯ä»¥ç¼åä¸ä¸ªå½æ°æ¥æå°Tableï¼
fn show(table: Table) {
for (artist, works) in table {
println!("works by {}:", artist);
for work in works {
println!(" {}", work);
}
}
}
2
3
4
5
6
7
8
æå»ºåæå°è¡¨æ ¼å¾ç®åï¼
fn main() {
let mut table = Table::new();
table.insert("Gesualdo".to_string(),
vec!["many madrigals".to_string(),
"Tenebrae Responsoria".to_string()]);
table.insert("Caravaggio".to_string(),
vec!["The Musicians".to_string(),
"The Calling of St. Matthew".to_string()]);
table.insert("Cellini".to_string(),
vec!["Perseus with the head of Medusa".to_string(),
"a salt cellar".to_string()]);
show(table);
}
2
3
4
5
6
7
8
9
10
11
12
13
ä¸åé½è¿è¡æ£å¸¸ï¼
$ cargo run
Running `/home/jimb/rust/book/fragments/target/debug/fragments`
works by Gesualdo:
many madrigals
Tenebrae Responsoria
works by Cellini:
Perseus with the head of Medusa
a salt cellar
works by Caravaggio:
The Musicians
The Calling of St. Matthew
$
2
3
4
5
6
7
8
9
10
11
12
使¯ï¼å¦æä½ 读è¿åä¸ç« å
³äºç§»å¨ï¼moveï¼çé¨åï¼è¿ä¸ªshow彿°çå®ä¹åºè¯¥ä¼è®©ä½ 产çä¸äºçé®ãç¹å«è¦æ³¨æçæ¯ï¼HashMap䏿¯Copyç±»åââå®ä¸å¯è½æ¯ï¼å ä¸ºå®æ¥æä¸ä¸ªå¨æåé
ç表ãæä»¥å½ç¨åºè°ç¨show(table)æ¶ï¼æ´ä¸ªç»æä¼è¢«ç§»å¨å°å½æ°ä¸ï¼ä½¿å¾åétableæªåå§åãï¼èä¸å®éåå
容çé¡ºåºæ¯ä¸ç¡®å®çï¼æä»¥å¦æä½ å¾å°ç顺åºä¸åï¼ä¹ä¸ç¨æ
å¿ãï¼å¦æè°ç¨ä»£ç ç°å¨è¯å¾ä½¿ç¨tableï¼å°±ä¼éå°é®é¢ï¼
...
show(table);
assert_eq!(table["Gesualdo"][0], "many madrigals");
2
3
Rust伿¥é说tableä¸å¯ç¨äºï¼
error: borrow of moved value: `table`
|
20 | let mut table = Table::new();
| --------- move occurs because `table` has type
| `HashMap<String, Vec<String>>`,
| which does not implement the `Copy` trait
...
31 | show(table);
| ----- value moved here
^^^^^ value borrowed here after move
32 | assert_eq!(table["Gesualdo"][0], "many madrigals");
2
3
4
5
6
7
8
9
10
11
å®é
ä¸ï¼å¦ææä»¬æ¥çshow彿°çå®ä¹ï¼å¤å±çfor循ç¯ä¼è·ååå¸è¡¨çæææå¹¶å®å
¨æ¶èå®ï¼å
å±çfor循ç¯ä¼å¯¹æ¯ä¸ªåéååæ ·çæä½ãï¼æä»¬ä¹åå¨âèªç±ãå¹³çãåç±âçä¾åä¸è§è¿è¿ç§è¡ä¸ºãï¼ç±äºç§»å¨è¯ä¹ï¼move semanticsï¼ï¼æä»¬ä»
ä»
ä¸ºäºæå°è¿ä¸ªç»æï¼å°±æå®å®å
¨ç ´åäºãå¤è°¢äºï¼Rustï¼
æ£ç¡®çå¤çæ¹å¼æ¯ä½¿ç¨å¼ç¨ãå¼ç¨å è®¸ä½ è®¿é®ä¸ä¸ªå¼ï¼èä¸ä¼å½±åå ¶æææãå¼ç¨æä¸¤ç§ç±»åï¼
- å
±äº«å¼ç¨ï¼shared referenceï¼å
è®¸ä½ è¯»åä½ä¸è½ä¿®æ¹å®ææåçå¼ãä¸è¿ï¼ä½ å¯ä»¥åæ¶æ¥æä»»æå¤ä¸ªæååä¸ç¹å®å¼çå
±äº«å¼ç¨ã表达å¼
&eä¼çæå¯¹eå¼çå ±äº«å¼ç¨ï¼å¦æeçç±»åæ¯Tï¼é£ä¹&eçç±»åå°±æ¯&Tï¼è¯»ä½âref Tâãå ±äº«å¼ç¨æ¯Copyç±»åã - å¦æä½ æä¸ä¸ªæåæä¸ªå¼çå¯åå¼ç¨ï¼mutable referenceï¼ï¼é£ä¹ä½ æ¢å¯ä»¥è¯»åä¹å¯ä»¥ä¿®æ¹è¿ä¸ªå¼ãç¶èï¼å¨å䏿¶å»ï¼ä½ ä¸è½æä»»ä½å
¶ä»ç±»åçå¼ç¨æå该å¼ã表达å¼
&mut eä¼çæå¯¹eå¼çå¯åå¼ç¨ï¼å®çç±»ååä½&mut Tï¼è¯»ä½âref mute Tâãå¯åå¼ç¨ä¸æ¯Copyç±»åã
ä½ å¯ä»¥æå
±äº«å¼ç¨åå¯åå¼ç¨ä¹é´çåºå«ï¼ç使¯ä¸ç§å¨ç¼è¯æ¶å¼ºå¶å®æ½å¤è¯»è
æååè
è§åï¼multiple readers or single writer ruleï¼çæ¹å¼ãå®é
ä¸ï¼è¿æ¡è§åä¸ä»
éç¨äºå¼ç¨ï¼å®ä¹éç¨äºè¢«åç¨å¼çææè
ãåªè¦æå¯¹æä¸ªå¼çå
±äº«å¼ç¨ï¼å³ä½¿æ¯å®çææè
ä¹ä¸è½ä¿®æ¹å®ï¼è¿ä¸ªå¼è¢«éå®äºãå¨show彿°ä½¿ç¨tableæ¶ï¼æ²¡æäººè½ä¿®æ¹å®ãåæ ·å°ï¼å¦ææä¸ä¸ªå¯åå¼ç¨æåæä¸ªå¼ï¼é£ä¹å®å¯¹è¯¥å¼æ¥æç¬å è®¿é®æï¼å¨å¯åå¼ç¨æ¶å¤±ä¹åï¼ä½ æ ¹æ¬æ æ³ä½¿ç¨ææè
ãäºå®è¯æï¼å°å
±äº«åå¯åå®å
¨åå¼å¯¹å
åå®å
¨è³å
³éè¦ï¼æ¬ç« å颿们伿¢è®¨å
¶ä¸çåå ã
卿们ç示ä¾ä¸ï¼æå°å½æ°ä¸éè¦ä¿®æ¹è¡¨æ ¼ï¼åªéè¦è¯»åå ¶å 容ãæä»¥è°ç¨è åºè¯¥è½å¤åå®ä¼ éè¡¨æ ¼çå ±äº«å¼ç¨ï¼å¦ä¸æç¤ºï¼
show(&table);
å¼ç¨æ¯éæ¥ææææçæéï¼æä»¥tableåéä»ç¶æ¯æ´ä¸ªç»æçææè
ï¼show彿°åªæ¯åç¨äºå®ä¸ä¼å¿ãèªç¶å°ï¼æä»¬éè¦è°æ´show彿°çå®ä¹æ¥å¹é
ï¼ä¸è¿ä½ å¾ä»ç»çæè½åç°å
¶ä¸çå·®å¼ï¼
fn show(table: &Table) {
for (artist, works) in table {
println!("works by {}:", artist);
for work in works {
println!(" {}", work);
}
}
}
2
3
4
5
6
7
8
show彿°åæ°tableçç±»åä»Tableåæäº&Tableï¼æä»¬ç°å¨ä¸æ¯æå¼ä¼ éè¡¨æ ¼ï¼ä»èå°æææç§»å¨å°å½æ°ä¸ï¼ï¼èæ¯ä¼ éä¸ä¸ªå
±äº«å¼ç¨ãè¿æ¯å¯ä¸çææ¬ååãä½å½æä»¬æ§è¡å½æ°ä½æ¶ï¼ä¼æä»ä¹ä¸åå¢ï¼
æä»¬åæ¥çå¤å±for循ç¯è·åäºHashMapçæææå¹¶æ¶èäºå®ï¼è卿°çæ¬ä¸ï¼å®æ¥æ¶çæ¯å¯¹HashMapçå
±äº«å¼ç¨ãéå对HashMapçå
±äº«å¼ç¨ä¼çæå¯¹æ¯ä¸ªæ¡ç®çé®åå¼çå
±äº«å¼ç¨ï¼artistä»Stringåæäº&Stringï¼worksä»Vec<String>åæäº&Vec<String>ã
å
å±å¾ªç¯ä¹æç±»ä¼¼çååãéå对åéçå
±äº«å¼ç¨ä¼çæå¯¹å
¶å
ç´ çå
±äº«å¼ç¨ï¼æä»¥workç°å¨æ¯&Stringãå¨è¿ä¸ªå½æ°ä¸ï¼ä»»ä½å°æ¹é½æ²¡æåçæææç转移ï¼åªæ¯å¨ä¼ ééæ¥ææææçå¼ç¨ã
ç°å¨ï¼å¦ææä»¬æ³ç¼åä¸ä¸ªå½æ°ï¼å¯¹æ¯ä¸ªèºæ¯å®¶çä½åè¿è¡åæ¯æåºï¼å ±äº«å¼ç¨å°±ä¸å¤äºï¼å ä¸ºå ±äº«å¼ç¨ä¸å 许修æ¹ãç¸åï¼æåºå½æ°éè¦æ¥æ¶è¡¨æ ¼çå¯åå¼ç¨ï¼
fn sort_works(table: &mut Table) {
for (_, works) in table {
works.sort();
}
}
2
3
4
5
并䏿们éè¦ä¼ éä¸ä¸ªå¯åå¼ç¨ï¼
sort_works(&mut table);
è¿ä¸ªå¯ååç¨èµäºäºsort_works彿°è¯»ååä¿®æ¹æä»¬çç»æçè½åï¼è¿æ¯åéçsortæ¹æ³æè¦æ±çã
彿们以å°å¼çæææç§»å¨å°å½æ°ä¸çæ¹å¼å°å¼ä¼ éç»å½æ°æ¶ï¼æä»¬è¯´æä»¬æ¯æå¼ä¼ éï¼passed by valueï¼ã妿æä»¬ä¼ éç»å½æ°çæ¯å¼çå¼ç¨ï¼æä»¬å°±è¯´æä»¬æ¯æå¼ç¨ä¼ éï¼passed by referenceï¼ãä¾å¦ï¼æä»¬éè¿å°show彿°ä¿®æ¹ä¸ºæå¼ç¨æ¥æ¶è¡¨æ ¼ï¼è䏿¯æå¼æ¥æ¶ï¼ä»èä¿®å¤äºè¿ä¸ªå½æ°ã许å¤è¯è¨é½æè¿ç§åºåï¼ä½å¨Rustä¸å°¤ä¸ºéè¦ï¼å ä¸ºå®æç¡®è¯´æäºææææ¯å¦ä½åå°å½±åçã
# 使ç¨å¼ç¨
åé¢ç示ä¾å±ç¤ºäºå¼ç¨çä¸ç§å ¸åç¨æ³ï¼å è®¸å½æ°å¨ä¸è·åæææçæ åµä¸è®¿é®ææä½ä¸ä¸ªç»æä½ãä½å¼ç¨ççµæ´»æ§ä¸æ¢äºæ¤ï¼æä»¥è®©æä»¬éè¿ä¸äºç¤ºä¾æ¥æ´è¯¦ç»å°äºè§£å ¶å·¥ä½åçã
# Rustå¼ç¨ä¸C++å¼ç¨ç对æ¯
å¦æä½ çæC++ä¸çå¼ç¨ï¼å®ä»¬åRustå¼ç¨ç¡®å®æä¸äºå ±åä¹å¤ãæéè¦çæ¯ï¼å¨æºå¨å±é¢ï¼å®ä»¬æ¬è´¨ä¸é½æ¯å°åãä½å¨å®é 使ç¨ä¸ï¼Rustçå¼ç¨ç»äººçæè§å¤§ä¸ç¸åã
å¨C++ä¸ï¼å¼ç¨éè¿éå¼è½¬æ¢å建ï¼å¹¶ä¸ä¹ä¼éå¼è§£å¼ç¨ï¼
// C++ code!
int x = 10;
int &r = x; // initialization creates reference implicitly
assert(r == 10); // implicitly dereference r to see x's value
r = 20; // stores 20 in x, r itself still points to x
2
3
4
5
å¨Rustä¸ï¼å¼ç¨éè¿&è¿ç®ç¬¦æ¾å¼å建ï¼éè¿*è¿ç®ç¬¦æ¾å¼è§£å¼ç¨ï¼
// Back to Rust code from this point onward.
let x = 10;
let r = &x; // &x is a shared reference to x
assert!(*r == 10); // explicitly dereference r
2
3
4
è¦å建å¯åå¼ç¨ï¼ä½¿ç¨&mutè¿ç®ç¬¦ï¼
let mut y = 32;
let m = &mut y; // &mut y is a mutable reference to y
*m += 32; // explicitly dereference m to set y's value
assert!(*m == 64); // and to see y's new value
2
3
4
ä½ä½ å¯è½è¿è®°å¾ï¼å¨ä¿®å¤show彿°ï¼ä½¿å
¶æå¼ç¨èéæå¼æ¥æ¶èºæ¯å®¶è¡¨æ ¼æ¶ï¼æä»¬ä»æªä½¿ç¨è¿*è¿ç®ç¬¦ãè¿æ¯ä¸ºä»ä¹å¢ï¼
ç±äºå¼ç¨å¨Rustä¸ä½¿ç¨é常广æ³ï¼å¨å¿
è¦æ¶ï¼.è¿ç®ç¬¦ä¼éå¼è§£å¼ç¨å
¶å·¦æä½æ°ï¼
struct Anime { name: &'static str, bechdel_pass: bool };
let aria = Anime { name: "Aria: The Animation", bechdel_pass: true };
let anime_ref = &aria;
assert_eq!(anime_ref.name, "Aria: The Animation");
// Equivalent to the above, but with the dereference written out:
assert_eq!((*anime_ref).name, "Aria: The Animation");
2
3
4
5
6
show彿°ä¸ä½¿ç¨çprintln!å®å±å¼åç代ç ä¼ä½¿ç¨.è¿ç®ç¬¦ï¼æä»¥å®ä¹å©ç¨äºè¿ç§éå¼è§£å¼ç¨ã
å¨è¿è¡æ¹æ³è°ç¨æ¶ï¼å¦æéè¦ï¼.è¿ç®ç¬¦è¿å¯ä»¥éå¼åç¨å
¶å·¦æä½æ°çå¼ç¨ãä¾å¦ï¼Vecçsortæ¹æ³æ¥æ¶ä¸ä¸ªæååéçå¯åå¼ç¨ï¼æä»¥ä¸é¢è¿ä¸¤ä¸ªè°ç¨æ¯çæçï¼
let mut v = vec![1973, 1968];
v.sort(); // implicitly borrows a mutable reference to v
(&mut v).sort(); // equivalent, but more verbose
2
3
ç®èè¨ä¹ï¼C++å¨å¼ç¨åå·¦å¼ï¼å³å¼ç¨å
åä½ç½®ç表达å¼ï¼ä¹é´è¿è¡éå¼è½¬æ¢ï¼è¿äºè½¬æ¢ä¼å¨éè¦çä»»ä½å°æ¹åºç°ï¼èå¨Rustä¸ï¼ä½ 使ç¨&å*è¿ç®ç¬¦æ¥å建åéµå¾ªå¼ç¨ï¼ä¸è¿.è¿ç®ç¬¦æ¯ä¸ªä¾å¤ï¼å®ä¼éå¼åç¨åè§£å¼ç¨ã
# å¼ç¨èµå¼
å°ä¸ä¸ªå¼ç¨èµç»ä¸ä¸ªåéï¼ä¼ä½¿è¯¥åéæåæ°çä½ç½®ï¼
let x = 10;
let y = 20;
let mut r = &x;
if b { r = &y; }
assert!(*r == 10 || *r == 20);
2
3
4
5
å¼ç¨ræåæåxãä½å¦æb为trueï¼ä»£ç ä¼ä½¿å®æåyï¼å¦å¾5-1æç¤ºã
å¾5-1 å¼ç¨rç°å¨æåyèéx
è¿ç§è¡ä¸ºå¯è½çèµ·æ¥å¤ªè¿ææ¾ï¼ä¸å¼ä¸æï¼å½ç¶rç°å¨æåyäºï¼å 为æä»¬æ&yèµç»äºå®ã使们æåºè¿ä¸ç¹ï¼æ¯å 为C++å¼ç¨çè¡ä¸ºæªç¶ä¸åï¼å¦åæè¿°ï¼å¨C++ä¸ç»å¼ç¨èµå¼ï¼æ¯å°å¼åå¨å°å®ææåç对象ä¸ã䏿¦C++å¼ç¨è¢«åå§åï¼å°±æ æ³è®©å®æåå
¶ä»ä»»ä½ä¸è¥¿ã
# å¼ç¨çå¼ç¨
Rustå 许åå¨å¼ç¨çå¼ç¨ï¼
struct Point { x: i32, y: i32 }
let point = Point { x: 1000, y: 729 };
let r: &Point = &point;
let rr: &&Point = &r;
let rrr: &&&Point = &rr;
2
3
4
5
ï¼ä¸ºäºæ¸
æ°èµ·è§ï¼æä»¬ååºäºå¼ç¨ç±»åï¼ä½ä½ ä¹å¯ä»¥çç¥ï¼è¿éçç±»åRusté½è½èªè¡æ¨æãï¼.è¿ç®ç¬¦ä¼æ²¿çæéæ°éçå¼ç¨æ¾å°ç®æ ï¼
assert_eq!(rrr.y, 729);
å¨å
åä¸ï¼è¿äºå¼ç¨çæåå¦å¾5-2æç¤ºã
å¾5-2 å¼ç¨çå¼ç¨é¾
æä»¥è¡¨è¾¾å¼rrr.yï¼æ ¹æ®rrrçç±»åï¼å®é
ä¸è¦éåä¸å±å¼ç¨æè½æ¾å°Pointï¼ç¶åè·åå
¶yåæ®µçå¼ã
# æ¯è¾å¼ç¨
å.è¿ç®ç¬¦ä¸æ ·ï¼Rustçæ¯è¾è¿ç®ç¬¦ä¹ä¼âç©¿éâä»»ææ°éçå¼ç¨ï¼
let x = 10;
let y = 10;
let rx = &x;
let ry = &y;
let rrx = ℞
let rry = &ry;
assert!(rrx <= rry);
assert!(rrx == rry);
2
3
4
5
6
7
8
è¿éçæåä¸ä¸ªæè¨ä¼æåï¼å°½ç®¡rrxårryæåä¸åçå¼ï¼å³rxåryï¼ï¼å 为==è¿ç®ç¬¦ä¼æ²¿çææå¼ç¨ï¼å¯¹å®ä»¬æç»æåçç®æ xåyè¿è¡æ¯è¾ãè¿å 乿»æ¯ä½ æ³è¦çè¡ä¸ºï¼å°¤å
¶æ¯å¨ç¼åæ³å彿°æ¶ãå¦æä½ ç¡®å®æ³ç¥é两个å¼ç¨æ¯å¦æååä¸åå
åï¼å¯ä»¥ä½¿ç¨std::ptr::eqï¼å®ä¼æå¼ç¨å½ä½å°åè¿è¡æ¯è¾ï¼
assert!(rx == ry); // their referents are equal
assert!( !std::ptr::eq(rx, ry)); // but occupy different addresses
2
注æï¼æ¯è¾çæä½æ°å¿ é¡»å ·æå®å ¨ç¸åçç±»åï¼å æ¬å¼ç¨ï¼
assert!(rx == rrx); // error: type mismatch: `&i32` vs `&&i32`
assert!(rx == *rrx); // this is okay
2
# å¼ç¨æ°¸è¿ä¸ä¸ºç©º
Rustå¼ç¨æ°¸è¿ä¸ä¼ä¸ºç©ºã宿²¡æä¸Cè¯è¨çNULLæC++çnullptrç±»ä¼¼çæ¦å¿µãå¼ç¨æ²¡æé»è®¤çåå§å¼ï¼å¨åé被åå§åä¹åï¼ä½ ä¸è½ä½¿ç¨å®ï¼æ 论å
¶ç±»åæ¯ä»ä¹ï¼ï¼å¹¶ä¸Rustä¸ä¼å°æ´æ°è½¬æ¢ä¸ºå¼ç¨ï¼å¨ä¸å®å
¨ä»£ç ä¹å¤ï¼ï¼æä»¥ä½ æ æ³å°é¶è½¬æ¢ä¸ºå¼ç¨ã
CåC++代ç ç»å¸¸ä½¿ç¨ç©ºæéæ¥è¡¨ç¤ºå¼ç缺失ï¼ä¾å¦ï¼malloc彿°è¦ä¹è¿åä¸ä¸ªæåæ°å
ååçæéï¼å¦ææ²¡æè¶³å¤çå
åæ¥æ»¡è¶³è¯·æ±ï¼åè¿ånullptrãå¨Rustä¸ï¼å¦æä½ éè¦ä¸ä¸ªæ¢å¯ä»¥æ¯æåæä¸ªä¸è¥¿çå¼ç¨ï¼ä¹å¯ä»¥ä»ä¹é½ä¸æ¯çå¼ï¼å¯ä»¥ä½¿ç¨Option<&T>ç±»åã卿ºå¨å±é¢ï¼Rustå°None表示为ä¸ä¸ªç©ºæéï¼èSome(r)ï¼å
¶ä¸ræ¯ä¸ä¸ª&Tå¼ï¼è¡¨ç¤ºä¸ºéé¶å°åï¼æä»¥Option<&T>ä¸CæC++ä¸çå¯ç©ºæé䏿 ·é«æï¼è䏿´å®å
¨ï¼å®çç±»åè¦æ±ä½ å¨ä½¿ç¨å®ä¹åæ£æ¥å®æ¯å¦ä¸ºNoneã
# åç¨ä»»æè¡¨è¾¾å¼çå¼ç¨
CåC++åªå
è®¸ä½ å¯¹ç¹å®ç±»åç表达å¼ä½¿ç¨&è¿ç®ç¬¦ï¼èRustå
è®¸ä½ åç¨ä»»ä½ç±»å表达å¼çå¼çå¼ç¨ï¼
fn factorial(n: usize) -> usize {
(1..n + 1).product()
}
let r = &factorial(6);
// ç®æ¯è¿ç®ç¬¦å¯ä»¥ç©¿éä¸å±å¼ç¨ã
assert_eq!(r + &1009, 1729);
2
3
4
5
6
å¨è¿ç§æ åµä¸ï¼Ruståªæ¯å建ä¸ä¸ªå¿åå鿥ä¿å表达å¼çå¼ï¼å¹¶è®©å¼ç¨æå该åéãè¿ä¸ªå¿ååéççå½å¨æåå³äºä½ 对å¼ç¨çä½¿ç¨æ¹å¼ï¼
- å¦æä½ å¨
letè¯å¥ä¸ç«å³å°å¼ç¨èµç»ä¸ä¸ªåéï¼æè è®©å®æä¸ºæä¸ªæ£å¨è¢«ç«å³èµå¼çç»æä½ææ°ç»çä¸é¨åï¼ï¼é£ä¹Rustä¼è®©è¿ä¸ªå¿ååéççå½å¨æä¸letåå§åçåéççå½å¨æä¸æ ·é¿ãå¨åé¢çä¾åä¸ï¼Rustä¼ä¸ºrææåçå¯¹è±¡è¿æ ·åã - å¦åï¼å¿ååéççå½å¨ææç»å°å
å«å®çè¯å¥ç»æã卿们çä¾åä¸ï¼ä¸ºä¿å
1009èå建çå¿ååéåªæç»å°assert_eq!è¯å¥ç»æã
å¦æä½ ä¹ æ¯äºCæC++ï¼è¿å¬èµ·æ¥å¯è½å®¹æåºéãä½è¯·è®°ä½ï¼Rustæ°¸è¿ä¸ä¼è®©ä½ ç¼åä¼äº§çæ¬ç©ºå¼ç¨ï¼dangling referenceï¼ç代ç ã妿å¼ç¨å¯è½å¨å¿ååéççå½å¨æä¹å¤è¢«ä½¿ç¨ï¼Rustæ»ä¼å¨ç¼è¯æ¶åä½ æ¥åè¿ä¸ªé®é¢ãç¶åä½ å¯ä»¥ä¿®æ¹ä»£ç ï¼å°è¢«å¼ç¨ç对象ä¿åå¨ä¸ä¸ªå ·æéå½çå½å¨æçå½ååéä¸ã
# åçå¼ç¨åç¹å¾å¯¹è±¡å¼ç¨
å°ç®å为æ¢ï¼æä»¬å±ç¤ºçå¼ç¨é½æ¯ç®åçå°åãç¶èï¼Rustè¿å æ¬ä¸¤ç§èæéï¼fat pointerï¼ï¼å®ä»¬æ¯ååå¼ï¼æ¢å å«æä¸ªå¼çå°åï¼ä¹å å«ä½¿ç¨è¯¥å¼æéçä¸äºé¢å¤ä¿¡æ¯ã
åçå¼ç¨æ¯ä¸ç§èæéï¼å®æºå¸¦åççèµ·å§å°ååé¿åº¦ãæä»¬å¨ç¬¬3ç« è¯¦ç»ä»ç»äºåçã
Rustçå¦ä¸ç§èæéæ¯ç¹å¾å¯¹è±¡ï¼trait objectï¼ï¼å®æ¯å¯¹å®ç°äºæä¸ªç¹å¾ç对象çå¼ç¨ãç¹å¾å¯¹è±¡æºå¸¦ä¸ä¸ªå¼çå°åï¼ä»¥åä¸ä¸ªæåéç¨äºè¯¥å¼çç¹å¾å®ç°çæéï¼ç¨äºè°ç¨ç¹å¾çæ¹æ³ãæä»¬å°å¨âç¹å¾å¯¹è±¡âé¨å详ç»ä»ç»ç¹å¾å¯¹è±¡ã
é¤äºæºå¸¦è¿äºé¢å¤çæ°æ®ï¼åçå¼ç¨åç¹å¾å¯¹è±¡å¼ç¨çè¡ä¸ºä¸æä»¬å¨æ¬ç« ä¸å±ç¤ºçå ¶ä»ç±»åçå¼ç¨ä¸æ ·ï¼å®ä»¬ä¸æ¥æææåç对象ï¼å ¶çå½å¨æä¸è½é¿äºææåç对象ï¼å®ä»¬å¯ä»¥æ¯å¯åçæå ±äº«çï¼çç ã
# å¼ç¨å®å ¨
å°ç®å为æ¢ï¼æä»¬æä»ç»çå¼ç¨çèµ·æ¥ä¸CæC++ä¸çæ®éæéé常ç¸ä¼¼ãä½é£äºæéæ¯ä¸å®å ¨çï¼Rustæ¯å¦ä½æ§å¶å ¶å¼ç¨çå¢ï¼æè®¸ï¼è§å¯è¿äºè§åå®é ä½ç¨çæä½³æ¹å¼å°±æ¯å°è¯å»æç ´å®ä»¬ã
为äºéè¿°åºæ¬æ¦å¿µï¼æä»¬å°ä»æç®åçæ åµå¼å§ï¼å±ç¤ºRustå¦ä½ç¡®ä¿å¨åä¸ªå½æ°ä½å æ£ç¡®ä½¿ç¨å¼ç¨ãç¶åï¼æä»¬ä¼æ¢è®¨å¨å½æ°ä¹é´ä¼ éå¼ç¨ä»¥åå°å¼ç¨åå¨å¨æ°æ®ç»æä¸çæ åµãè¿éè¦ä¸ºç¸å ³å½æ°åæ°æ®ç±»åèµäºçå½å¨æåæ°ï¼lifetime parameterï¼ï¼æä»¬å°å¯¹æ¤è¿è¡è§£éãæåï¼æä»¬ä¼ä»ç»Rustæä¾çä¸äºç®å常è§ä½¿ç¨æ¨¡å¼çå¿«æ·æ¹å¼ã卿´ä¸ªè¿ç¨ä¸ï¼æä»¬å°å±ç¤ºRustå¦ä½æåºä»£ç ä¸çé误ï¼å¹¶ä¸é常è¿ä¼ç»åºè§£å³æ¹æ¡ã
# åç¨å±é¨åé
è¿æ¯ä¸ä¸ªéå¸¸ææ¾çä¾åãä½ ä¸è½åç¨å¯¹å±é¨åéçå¼ç¨ï¼å¹¶å°å ¶å¸¦åºè¯¥åéçä½ç¨åï¼
{
let r;
{
let x = 1;
r = &x;
}
assert_eq!(*r, 1); // bad: reads memory `x` used to occupy
}
2
3
4
5
6
7
8
Rustç¼è¯å¨ä¼æç»è¿ä¸ªç¨åºï¼å¹¶ç»åºè¯¦ç»çé误信æ¯ï¼
error: `x` does not live long enough
--> references_dangling.rs:8:5
|
7 | r = &x;
| ^^ borrowed value does not live long enough
8 | }
- `x` dropped here while still borrowed
9 | assert_eq!(*r, 1); // bad: reads memory `x` used to occupy
10 | }
2
3
4
5
6
7
8
9
Rustçæ¥éä¿¡æ¯è¡¨æï¼xççå½å¨æåªæç»å°å
å±ä»£ç åç»æï¼èå¼ç¨ççå½å¨æå´æç»å°å¤å±ä»£ç åç»æï¼è¿ä½¿å¾è¯¥å¼ç¨æä¸ºä¸ä¸ªæ¬ç©ºæéï¼dangling pointerï¼ï¼è¿æ¯ä¸å
许çã
è½ç¶äººç±»è¯»è ä¸ç¼å°±è½çåºè¿ä¸ªç¨åºæ¯é误çï¼ä½äºè§£Rustæ¯å¦ä½å¾åºè¿ä¸ªç»è®ºçè¿æ¯å¾æä»·å¼çãå³ä½¿æ¯è¿ä¸ªç®åçä¾åï¼ä¹å±ç¤ºäºRustç¨äºæ£æ¥æ´å¤æä»£ç çé»è¾æ¹æ³ã
Rustä¼å°è¯ä¸ºç¨åºä¸çæ¯ä¸ªå¼ç¨ç±»ååé ä¸ä¸ªæ»¡è¶³å ¶ä½¿ç¨æ¹å¼ææ½å 约æççå½å¨æï¼lifetimeï¼ãçå½å¨ææ¯æç¨åºä¸ä¸æ®µå¼ç¨å¯ä»¥å®å ¨ä½¿ç¨çæ¶é´æ®µï¼å¯ä»¥æ¯ä¸æ¡è¯å¥ãä¸ä¸ªè¡¨è¾¾å¼ãæä¸ªåéçä½ç¨åççã
çå½å¨æå®å ¨æ¯Rustå¨ç¼è¯æ¶èæåºæ¥çæ¦å¿µãå¨è¿è¡æ¶ï¼å¼ç¨ä» ä» æ¯ä¸ä¸ªå°åï¼å®ççå½å¨ææ¯å ¶ç±»åçä¸é¨åï¼å¨è¿è¡æ¶æ²¡æå®é 表示ã
å¨è¿ä¸ªä¾åä¸ï¼æä¸ä¸ªçå½å¨æçå
³ç³»éè¦æä»¬æ¢³çæ¸
æ¥ãåéråx齿åèªççå½å¨æï¼ä»å®ä»¬è¢«åå§åçä½ç½®å¼å§ï¼ä¸ç´å°ç¼è¯å¨è½å¤è¯æå®ä»¬ä¸å被使ç¨çä½ç½®ç»æã第ä¸ä¸ªçå½å¨æå±äºå¼ç¨ç±»åï¼å³æä»¬åç¨æåxå¹¶åå¨å¨rä¸çå¼ç¨çç±»åã
æä¸ä¸ªçº¦æåºè¯¥å¾å®¹æçè§£ï¼å¦æä½ æä¸ä¸ªåéxï¼é£ä¹å¯¹xçå¼ç¨ççå½å¨æä¸å®ä¸è½è¶
è¿xæ¬èº«ççå½å¨æï¼å¦å¾5-3æç¤ºã
å¾5-3 &xå
许ççå½å¨æèå´
å¨xè¶
åºä½ç¨åä¹åï¼è¯¥å¼ç¨å°±ä¼æä¸ºä¸ä¸ªæ¬ç©ºæéãæä»¬è¯´åéççå½å¨æå¿
é¡»å
嫿å
å´ä»å®é£éåç¨çå¼ç¨ççå½å¨æã
è¿æå¦ä¸ç§çº¦æï¼å¦æä½ å°ä¸ä¸ªå¼ç¨åå¨å¨åérä¸ï¼é£ä¹è¿ä¸ªå¼ç¨çç±»åå¨åérçæ´ä¸ªçå½å¨æå
ï¼ä»åå§åå°æå䏿¬¡ä½¿ç¨ï¼é½å¿
é¡»æ¯ææçï¼å¦å¾5-4æç¤ºã
å¾5-4 åå¨å¨rä¸çå¼ç¨å
许ççå½å¨æèå´
妿å¼ç¨ççå½å¨æè³å°ä¸è½ååéççå½å¨æä¸æ ·é¿ï¼é£ä¹å¨æä¸ªæ¶å»rå°±ä¼æä¸ºä¸ä¸ªæ¬ç©ºæéãæä»¬è¯´å¼ç¨ççå½å¨æå¿
é¡»å
嫿å
å´åéççå½å¨æã
第ä¸ç§çº¦æéå¶äºå¼ç¨çå½å¨æçæå¤§èå´ï¼è第äºç§çº¦æéå¶äºå
¶æå°èå´ãRuståªæ¯å°è¯ä¸ºæ¯ä¸ªå¼ç¨æ¾å°ä¸ä¸ªæ»¡è¶³ææè¿äºçº¦æççå½å¨æãç¶èï¼å¨æä»¬çä¾åä¸ï¼å¹¶ä¸åå¨è¿æ ·ççå½å¨æï¼å¦å¾5-5æç¤ºã
å¾5-5 对çå½å¨ææçç¾çº¦æçå¼ç¨
ç°å¨è®©æä»¬æ¥çä¸ä¸ªè½å¤æ£å¸¸è¿è¡çä¸åä¾åãæä»¬æåæ ·ç±»åç约æï¼å¼ç¨ççå½å¨æå¿
é¡»å
å«å¨xççå½å¨æå
ï¼ä½åè¦å®å
¨å
å´rççå½å¨æãä¸è¿å 为ç°å¨rççå½å¨ææ´çäºï¼æä»¥åå¨ä¸ä¸ªæ»¡è¶³è¿äºçº¦æççå½å¨æï¼å¦å¾5-6æç¤ºã
å¾5-6 çå½å¨æå
å´rçä½ç¨åä¸å¨xçä½ç¨åå
çå¼ç¨
å½ä½ åç¨å¯¹æä¸ªæ´å¤§æ°æ®ç»æçä¸é¨åï¼æ¯å¦åéä¸çä¸ä¸ªå ç´ )çå¼ç¨æ¶ï¼è¿äºè§ååæ ·èªç¶éç¨ï¼
let v = vec![1, 2, 3];
let r = &v[1];
2
ç±äºvæ¥æè¿ä¸ªåéï¼èå鿥æå
¶å
ç´ ï¼æä»¥vççå½å¨æå¿
é¡»å
å´&v[1]å¼ç¨ç±»åççå½å¨æãåæ ·å°ï¼å¦æä½ å°ä¸ä¸ªå¼ç¨åå¨å¨æä¸ªæ°æ®ç»æä¸ï¼è¯¥å¼ç¨ççå½å¨æå¿
é¡»å
å´è¿ä¸ªæ°æ®ç»æççå½å¨æãä¾å¦ï¼å¦æä½ æå»ºä¸ä¸ªå¼ç¨åéï¼ææè¿äºå¼ç¨ççå½å¨æé½å¿
é¡»å
å´æ¥æè¯¥åéçåéççå½å¨æã
è¿å°±æ¯Rust对ææä»£ç 使ç¨çå¤çè¿ç¨çæ ¸å¿ãå¼å ¥æ´å¤çè¯è¨ç¹æ§ï¼ä¾å¦æ°æ®ç»æå彿°è°ç¨ï¼ä¼å¸¦æ¥æ°ç±»åç约æï¼ä½åºæ¬å忝ç¸åçï¼é¦å ï¼çè§£ç¨åºä½¿ç¨å¼ç¨çæ¹å¼æäº§çç约æï¼ç¶åï¼æ¾å°æ»¡è¶³è¿äºçº¦æççå½å¨æãè¿ä¸CåC++ç¨åºåèªè¡éµå¾ªçè¿ç¨å¹¶æ²¡æå¤ªå¤§ä¸åï¼ä¸åä¹å¤å¨äºï¼Rustäºè§£è¿äºè§åå¹¶ä¼å¼ºå¶æ§è¡ã
# 彿°åæ°æ¥æ¶å¼ç¨
彿们å°å¼ç¨ä¼ éç»å½æ°æ¶ï¼Rustæ¯å¦ä½ç¡®ä¿å½æ°å®å
¨ä½¿ç¨å®çå¢ï¼å设æä»¬æä¸ä¸ªå½æ°fï¼å®æ¥æ¶ä¸ä¸ªå¼ç¨å¹¶å°å
¶åå¨å¨å
¨å±åéä¸ãæä»¬éè¦å¯¹ä»£ç åä¸äºä¿®æ¹ï¼ä¸é¢æ¯åæ¥å°è¯ï¼
// è¿æ®µä»£ç æå 个é®é¢ï¼æ æ³ç¼è¯ã
static mut STASH: &i32;
fn f(p: &i32) { STASH = p; }
2
3
Rustä¸ä¸å ¨å±åéçä»·çæ¯éæåéï¼staticï¼ï¼å®æ¯ç¨åºå¯å¨æ¶å建ï¼ä¸ç´æç»å°ç¨åºç»æçå¼ãï¼ä¸å ¶ä»ä»»ä½å£°æä¸æ ·ï¼Rustçæ¨¡åç³»ç»æ§å¶çéæåéçå¯è§èå´ï¼æä»¥å®ä»¬åªæ¯å¨çå½å¨æä¸æ¯âå ¨å±çâï¼èéå¨å¯è§æ§ä¸ãï¼æä»¬ä¼å¨ç¬¬8ç« ä»ç»éæåéï¼ç®åæä»¬åªæåºä¸è¿°ä»£ç æªéµå¾ªçå æ¡è§åï¼
- æ¯ä¸ªéæåéé½å¿ 须被åå§åã
- å¯åéæåéæ¬è´¨ä¸æ¯çº¿ç¨ä¸å®å ¨çï¼æ¯ç«ï¼ä»»ä½çº¿ç¨å¨ä»»ä½æ¶åé½å¯ä»¥è®¿é®éæåéï¼ï¼å³ä½¿å¨å线ç¨ç¨åºä¸ï¼å®ä»¬ä¹å¯è½ä¼åå°å ¶ä»ç±»åçéå ¥é®é¢çå½±åãåºäºè¿äºåå ï¼ä½ åªè½å¨ä¸å®å ¨åï¼unsafe blockï¼å 访é®å¯åéæåéãå¨è¿ä¸ªä¾åä¸ï¼æä»¬ä¸å ³å¿è¿äºç¹å®é®é¢ï¼æä»¥æä»¬ç´æ¥æ·»å ä¸ä¸ªä¸å®å ¨åï¼ç»§ç»å¾ä¸è¿è¡ã
ä¿®æ¹åï¼ä»£ç å¦ä¸ï¼
static mut STASH: &i32 = &128;
fn f(p: &i32) { // ä»ç¶ä¸å¤å¥½
unsafe {
STASH = p;
}
}
2
3
4
5
6
å·®ä¸å¤äºã为äºåç°å©ä½çé®é¢ï¼æä»¬éè¦ååºä¸äºRustè´´å¿å°è®©æä»¬çç¥çå
容ãè¿éåçf彿°ç¾åå®é
䏿¯ä¸é¢è¿ç§åæ³çç®åï¼
fn f<'a>(p: &'a i32) { ... }
è¿éï¼çå½å¨æ'aï¼è¯»ä½âtick Aâï¼æ¯f彿°ççå½å¨æåæ°ï¼lifetime parameterï¼ãä½ å¯ä»¥å°<'a>读ä½â对äºä»»æçå½å¨æ'aâï¼æä»¥å½æä»¬åæfn f<'a>(p: &'a i32)æ¶ï¼æä»¬å®ä¹çæ¯ä¸ä¸ªæ¥æ¶æåi32ä¸å
·æä»»æç»å®çå½å¨æ'açå¼ç¨ç彿°ã
ç±äºæä»¬å¿
é¡»å
许'a为任æçå½å¨æï¼é£ä¹å½å®æ¯å¯è½çæççå½å¨æï¼å³ä»
å
å´å¯¹fçè°ç¨ççå½å¨æï¼æ¶ï¼ä¹åºè¯¥è½æ£å¸¸å·¥ä½ãä½è¿æ ·ä¸æ¥ï¼ä¸é¢è¿ä¸ªèµå¼å°±ä¼äº§çé®é¢ï¼
STASH = p;
å 为STASHççå½å¨æè´¯ç©¿ç¨åºçæ´ä¸ªæ§è¡è¿ç¨ï¼å®æä¿åçå¼ç¨ç±»åççå½å¨æä¹å¿
é¡»ä¸ä¹ç¸åï¼Rustå°è¿ç§çå½å¨æç§°ä¸º'staticçå½å¨æã使¯på¼ç¨ççå½å¨ææ¯æä¸ª'aï¼åªè¦å®å
å´å¯¹fçè°ç¨ï¼'aå¯ä»¥æ¯ä»»æçå½å¨æãæä»¥ï¼Rustæç»æä»¬ç代ç ï¼
error: explicit lifetime required in the type of `p`
|
---- help: add explicit lifetime `'static`
| to the type of `p`: `&'static i32`
5 | fn f(p: &i32) { // still not good enough
6 | unsafe {
7 | STASH = p;
| ^ lifetime `'static` required
2
3
4
5
6
7
8
æ¤æ¶å¾ææ¾ï¼æä»¬ç彿°ä¸è½æ¥åä»»æå¼ç¨ä½ä¸ºåæ°ã使£å¦Rustæåºçï¼å®åºè¯¥è½å¤æ¥åå
·æ'staticçå½å¨æçå¼ç¨ï¼å°è¿æ ·çå¼ç¨åå¨å¨STASHä¸ä¸ä¼äº§çæ¬ç©ºæéãå®é
ä¸ï¼ä¸é¢ç代ç ç¼è¯å®å
¨æ²¡é®é¢ï¼
static mut STASH: &i32 = &10;
fn f(p: &'static i32) {
unsafe {
STASH = p;
}
}
2
3
4
5
6
è¿ä¸æ¬¡ï¼fçç¾åæç¡®è¡¨ç¤ºpå¿
é¡»æ¯å
·æ'staticçå½å¨æçå¼ç¨ï¼æä»¥å°å
¶åå¨å¨STASHä¸ä¸åæé®é¢ãæä»¬åªè½å°fåºç¨äºæåå
¶ä»éæåéçå¼ç¨ï¼ä½æ 论å¦ä½ï¼è¿æ¯å¯ä¸å¯ä»¥ç¡®ä¿ä¸ä¼è®©STASHæä¸ºæ¬ç©ºæéçåæ³ãæä»¥æä»¬å¯ä»¥è¿æ ·åï¼
static WORTH_POINTING_AT: i32 = 1000;
f(&WORTH_POINTING_AT);
2
å 为WORTH_POINTING_ATæ¯ä¸ä¸ªéæåéï¼&WORTH_POINTING_ATçç±»åæ¯&'static i32ï¼å°å
¶ä¼ éç»fæ¯å®å
¨çã
ä¸è¿ï¼åè¿å¤´æ¥æ³¨æä¸ä¸ï¼å¨æä»¬éæ¥ä¿®æ¹ä»£ç 使å
¶æ£ç¡®çè¿ç¨ä¸ï¼f彿°çç¾ååçäºä»ä¹ååï¼æåçf(p: &i32)æç»åæäºf(p: &'static i32)ãæ¢å¥è¯è¯´ï¼å¦æä¸å¨å½æ°ç¾åä¸ä½ç°åºæå¾ï¼æä»¬å°±æ æ³ååºä¸ä¸ªå°å¼ç¨åå¨å¨å
¨å±åéä¸ç彿°ãå¨Rustä¸ï¼å½æ°çç¾åæ»æ¯ä¼åæ åºå½æ°ä½çè¡ä¸ºã
ç¸åï¼å¦ææä»¬çå°ä¸ä¸ªå½æ°ç¾ååg(p: &i32)ï¼æè
宿´ååºçå½å¨æçg<'a>(p: &'a i32)ï¼ï¼æä»¬å°±å¯ä»¥å¤æå®ä¸ä¼å°åæ°påå¨å¨ä»»ä½çå½å¨æè¶
è¿è°ç¨çå°æ¹ãæ 鿥çgçå®ä¹ï¼ä»
ä»ç¾åå°±è½ç¥ég对å
¶åæ°è½åä»ä¹ãä¸è½åä»ä¹ãå½ä½ è¯å¾ç¡®å®å¯¹è¯¥å½æ°è°ç¨çå®å
¨æ§æ¶ï¼è¿ä¸ç¹é常æç¨ã
# å彿°ä¼ éå¼ç¨
æ¢ç¶æä»¬å·²ç»äºè§£äºå½æ°ç¾åä¸å ¶å½æ°ä½çå ³ç³»ï¼ç°å¨æ¥ççå®ä¸å½æ°è°ç¨è ä¹é´çèç³»ãåè®¾ä½ æä»¥ä¸ä»£ç ï¼
// è¿æ®µä»£ç å¯ä»¥å徿´ç®æ´ï¼fn g(p: &i32)ï¼
// ä½ç®åæä»¬æçå½å¨æååºæ¥ã
fn g<'a>(p: &'a i32) { ... }
let x = 10;
g(&x);
2
3
4
5
ä»
ä»gçç¾åï¼Rustå°±ç¥éå®ä¸ä¼å°påå¨å¨ä»»ä½çå½å¨æå¯è½è¶
è¿è°ç¨çå°æ¹ï¼ä»»ä½å
å´è°ç¨ççå½å¨æé½å¿
é¡»éç¨äº'aãæä»¥Rust为&xéæ©äºå°½å¯è½çççå½å¨æï¼å³å¯¹gçè°ç¨ççå½å¨æãè¿æ»¡è¶³äºææçº¦ææ¡ä»¶ï¼å®ä¸ä¼è¶
è¿xççå½å¨æï¼å¹¶ä¸å
å´äºå¯¹gçæ´ä¸ªè°ç¨ãæä»¥è¿æ®µä»£ç æ¯æ²¡é®é¢çã
注æï¼è½ç¶gæä¸ä¸ªçå½å¨æåæ°'aï¼ä½å¨è°ç¨gæ¶æä»¬æ éæåå®ãåªæå¨å®ä¹å½æ°åç±»åæ¶æéè¦èèçå½å¨æåæ°ï¼å¨ä½¿ç¨å®ä»¬æ¶ï¼Rustä¼ä¸ºä½ æ¨æçå½å¨æã
妿æä»¬å°è¯å°&xä¼ éç»ä¹åé£ä¸ªæåæ°åå¨å¨éæåéä¸ç彿°fä¼ææ ·å¢ï¼
fn f(p: &'static i32) { ... }
let x = 10;
f(&x);
2
3
è¿æ®µä»£ç æ æ³ç¼è¯ï¼å¼ç¨&xççå½å¨æä¸è½è¶
è¿xï¼ä½å°å®ä¼ éç»fï¼å°±éå¶äºå®ççå½å¨æè³å°è¦å'static䏿 ·é¿ãè¿éæ æ³æ»¡è¶³ææè¦æ±ï¼æä»¥Rust伿ç»è¿æ®µä»£ç ã
# è¿åå¼ç¨
彿°æ¥æ¶ä¸ä¸ªæåæä¸ªæ°æ®ç»æçå¼ç¨ï¼ç¶åè¿åæåè¯¥ç»æä¸æä¸ªé¨åçå¼ç¨ï¼è¿ç§æ åµå¾å¸¸è§ãä¾å¦ï¼ä¸é¢è¿ä¸ªå½æ°è¿åæååç䏿å°å ç´ çå¼ç¨ï¼
// våºè¯¥è³å°æä¸ä¸ªå
ç´ ã
fn smallest(v: &[i32]) -> &i32 {
let mut s = &v[0];
for r in &v[1..] {
if *r < *s {
s = r;
}
}
s
}
2
3
4
5
6
7
8
9
10
æä»¬åå¾å¸¸ä¸æ ·å¨å½æ°ç¾åä¸çç¥äºçå½å¨æãå½å½æ°æ¥æ¶ä¸ä¸ªå¼ç¨ä½ä¸ºåæ°å¹¶è¿åä¸ä¸ªå¼ç¨æ¶ï¼Ruståå®è¿ä¸¤ä¸ªå¼ç¨ççå½å¨æå¿ é¡»ç¸åãæç¡®ååºçè¯ï¼ä»£ç å¦ä¸ï¼
fn smallest<'a>(v: &'a [i32]) -> &'a i32 { ... }
å设æä»¬è¿æ ·è°ç¨smallestï¼
let s;
{
let parabola = [9, 4, 1, 0, 1, 4, 9];
s = smallest(¶bola);
}
assert_eq!(*s, 0); // bad: points to element of dropped array
2
3
4
5
6
ä»smallestçç¾åä¸ï¼æä»¬å¯ä»¥çå°å®çåæ°åè¿åå¼å¿
é¡»æç¸åççå½å¨æ'aã卿们çè°ç¨ä¸ï¼åæ°¶bolaççå½å¨æä¸è½è¶
è¿parabolaæ¬èº«ï¼ç¶èsmallestçè¿åå¼ççå½å¨æå¿
é¡»è³å°ås䏿 ·é¿ãä¸åå¨è½åæ¶æ»¡è¶³è¿ä¸¤ä¸ªçº¦ææ¡ä»¶ççå½å¨æ'aï¼æä»¥Rust伿ç»è¿æ®µä»£ç ï¼
error: `parabola` does not live long enough
--> references_lifetimes_propagated.rs:12:5
|
-------- borrow occurs here
^ `parabola` dropped here while still borrowed
11 | s = smallest(¶bola);
12 | }
13 | assert_eq!(*s, 0); // bad: points to element of dropped array
| - borrowed value needs to live until here
14 | }
2
3
4
5
6
7
8
9
10
å°sçä½ç½®ç§»å¨ï¼ä½¿å
¶çå½å¨æææ¾å
å«å¨parabolaççå½å¨æå
ï¼å°±è½è§£å³è¿ä¸ªé®é¢ï¼
{
let parabola = [9, 4, 1, 0, 1, 4, 9];
let s = smallest(¶bola);
assert_eq!(*s, 0); // fine: parabola still alive
}
2
3
4
5
彿°ç¾åä¸ççå½å¨æè®©Rustè½å¤è¯ä¼°ä¼ éç»å½æ°çå¼ç¨å彿°è¿åçå¼ç¨ä¹é´çå ³ç³»ï¼ç¡®ä¿å®ä»¬è¢«å®å ¨ä½¿ç¨ã
# å å«å¼ç¨çç»æä½
Rustå¦ä½å¤çåå¨å¨æ°æ®ç»æä¸çå¼ç¨å¢ï¼ä¸é¢æ¯æä»¬ä¹åçè¿çé误代ç ï¼åªæ¯è¿æ¬¡æä»¬æå¼ç¨æ¾å¨äºç»æä½ä¸ï¼
// è¿æ®µä»£ç æ æ³ç¼è¯ã
struct S {
r: &i32
}
let s;
{
let x = 10;
s = S { r: &x };
}
assert_eq!(*s.r, 10); // bad: reads from dropped `x`
2
3
4
5
6
7
8
9
10
Rust对å¼ç¨è®¾ç½®çå®å
¨çº¦æå¹¶ä¸ä¼å 为æä»¬æå¼ç¨èå¨ç»æä½ä¸å°±ç¥å¥å°æ¶å¤±ãä¸ç¥æçï¼è¿äºçº¦ææç»ä¹å¿
é¡»åºç¨å°Sä¸ãå®é
ä¸ï¼Rustå¯¹æ¤ææçæåº¦ï¼
error[E0106]: missing lifetime specifier
--> references_in_struct.rs:7:12
|
7 | r: &i32
| ^ expected lifetime parameter
2
3
4
5
æ¯å½å¼ç¨ç±»ååºç°å¨å ¶ä»ç±»åçå®ä¹ä¸æ¶ï¼ä½ é½å¿ é¡»ååºå®ççå½å¨æãä½ å¯ä»¥è¿æ ·åï¼
struct S {
r: &'static i32
}
2
3
è¿è¡¨ç¤ºråªè½æåé£äºçå½å¨æä¸ç¨åºç¸åçi32å¼ï¼è¿ç¸å½åéã
å¦ä¸ç§æ¹æ³æ¯ç»ç±»åä¸ä¸ªçå½å¨æåæ°'aï¼å¹¶å°å
¶ç¨äºrï¼
struct S<'a> {
r: &'a i32
}
2
3
ç°å¨Sç±»åå°±æäºä¸ä¸ªçå½å¨æï¼å°±åå¼ç¨ç±»å䏿 ·ãä½ åå»ºçæ¯ä¸ªSç±»åçå¼é½æä¸ä¸ªæ°ççå½å¨æ'aï¼è¿ä¸ªçå½å¨æä¼æ ¹æ®ä½ 使ç¨è¯¥å¼çæ¹å¼åå°çº¦æãåå¨å¨rä¸çä»»ä½å¼ç¨ççå½å¨ææå¥½å
å´'aï¼å¹¶ä¸'aå¿
é¡»æ¯åå¨Sçå°æ¹ççå½å¨æé¿ã
åå°åé¢ç代ç ï¼è¡¨è¾¾å¼S { r: &x }å建äºä¸ä¸ªå
·ææä¸ªçå½å¨æ'açæ°çSå¼ãå½ä½ å°&xåå¨å¨råæ®µä¸æ¶ï¼ä½ å°'aççå½å¨æéå¶å¨å®å
¨å¨xççå½å¨æå
ã
èµå¼s = S {... }å°è¿ä¸ªSåå¨å¨ä¸ä¸ªåéä¸ï¼è¯¥åéççå½å¨æä¸ç´å»¶ç»å°ç¤ºä¾ç»æï¼è¿å°±éå¶äº'aççå½å¨æè¦æ¯sççå½å¨æé¿ãç°å¨Rustéå°äºåä¹å䏿 ·ç¸äºçç¾ç约æï¼'aççå½å¨æä¸è½è¶
è¿xï¼ä½åå¿
é¡»è³å°åsççå½å¨æä¸æ ·é¿ãä¸åå¨ä»¤äººæ»¡æççå½å¨æï¼æä»¥Rustæç»è¿æ®µä»£ç ã
屿ºè§£é¤ï¼
å½ä¸ä¸ªå¸¦æçå½å¨æåæ°çç±»å被æ¾å¨å ¶ä»ç±»å䏿¶ä¼ææ ·å¢ï¼
struct D {
s: S // not adequate
}
2
3
Ruståæ ·ææçæåº¦ï¼å°±åæä»¬ä¹åå¨S䏿¾ç½®å¼ç¨å´æªæå®å
¶çå½å¨ææ¶ä¸æ ·ï¼
error[E0106]: missing lifetime specifier
--> <source>:8:8
|
8 | s: S // not adequate
| ^ expected named lifetime parameter
2
3
4
5
è¿éæä»¬ä¸è½çç¥Sççå½å¨æåæ°ï¼Rustéè¦ç¥éDççå½å¨æä¸å®å
é¨Sä¸çå¼ç¨ççå½å¨æä¹é´çå
³ç³»ï¼ä»¥ä¾¿å¯¹Dè¿è¡å对S以忮éå¼ç¨ä¸æ ·çæ£æ¥ã
æä»¬å¯ä»¥ç»sèµäº'staticçå½å¨æãè¿æ ·åå¯è¡ï¼
struct D {
s: S<'static>
}
2
3
æç
§è¿ä¸ªå®ä¹ï¼såæ®µåªè½åç¨é£äºå¨ç¨åºæ´ä¸ªæ§è¡è¿ç¨ä¸é½åå¨çå¼ãè¿æç¹éå¶ï¼ä½è¿ç¡®å®æå³çDä¸å¯è½åç¨å±é¨åéï¼å¯¹Dççå½å¨æä¹æ²¡æç¹æ®éå¶ã
å®é ä¸ï¼Rustçéè¯¯ä¿¡æ¯æç¤ºäºå¦ä¸ç§æ´éç¨çæ¹æ³ï¼
help: consider introducing a named lifetime parameter
|
7 | struct D<'a> {
8 | s: S<'a>
|
2
3
4
5
å¨è¿éï¼æä»¬ç»Dèªå·±ççå½å¨æåæ°ï¼å¹¶å°å
¶ä¼ éç»Sï¼
struct D<'a> {
s: S<'a>
}
2
3
éè¿ä½¿ç¨çå½å¨æåæ°'aå¹¶å°å
¶ç¨äºsçç±»åï¼æä»¬è®©Rustè½å¤å°Då¼ççå½å¨æä¸å®å
é¨Sææçå¼ç¨ççå½å¨æè系起æ¥ã
æä»¬ä¹åå±ç¤ºäºå½æ°ç¾åå¦ä½æç¤ºå®å¯¹æä»¬ä¼ éçå¼ç¨çæä½ãç°å¨æä»¬å±ç¤ºäºç±»åä¹æç±»ä¼¼çæ
åµï¼ç±»åççå½å¨æåæ°æ»æ¯ä¼æç¤ºå®æ¯å¦å
å«å
·æç¹æ®ï¼å³é'staticï¼çå½å¨æçå¼ç¨ï¼ä»¥åè¿äºçå½å¨æå¯è½æ¯ä»ä¹ã
ä¾å¦ï¼å设æä»¬æä¸ä¸ªè§£æå½æ°ï¼å®æ¥æ¶ä¸ä¸ªåèåçå¹¶è¿åä¸ä¸ªå å«è§£æç»æçç»æä½ï¼
fn parse_record<'i>(input: &'i [u8]) -> Record<'i> { ... }
å³ä½¿å®å
¨ä¸æ¥çRecordç±»åçå®ä¹ï¼æä»¬ä¹è½ç¥éï¼å¦æä»parse_record彿°ä¸å¾å°ä¸ä¸ªRecordï¼å®å
å«çä»»ä½å¼ç¨é½å¿
é¡»æåæä»¬ä¼ å
¥çè¾å
¥ç¼å²åºï¼èä¸ä¼æåå
¶ä»å°æ¹ï¼å¯è½é¤äº'staticå¼ï¼ã
å®é ä¸ï¼Rustè¦æ±å å«å¼ç¨çç±»åä½¿ç¨æ¾å¼çå½å¨æåæ°ï¼åå å°±å¨äºè¿ç§å¯¹å é¨è¡ä¸ºçæç¤ºãRustå¹¶éä¸è½ç®åå°ä¸ºç»æä½ä¸çæ¯ä¸ªå¼ç¨çæä¸ä¸ªä¸åççå½å¨æï¼ä»èçå»ä½ 书åå®ä»¬ç麻ç¦ãæ©æçæ¬çRustå®é ä¸å°±æ¯è¿æ ·åçï¼ä½å¼åè 们åç°è¿å¾å®¹æè®©äººå°æï¼ç¥éä¸ä¸ªå¼ä½æ¶ä»å¦ä¸ä¸ªå¼åç¨æ°æ®æ¯å¾æå¸®å©çï¼å°¤å ¶æ¯å¨ææ¥éè¯¯çæ¶åã
ä¸åªæ¯å¼ç¨ååSè¿æ ·çç±»åæçå½å¨æãRustä¸çæ¯ä¸ªç±»å齿çå½å¨æï¼å
æ¬i32åStringã大夿°ç±»åççå½å¨æåªæ¯'staticï¼è¿æå³çè¿äºç±»åçå¼å¯ä»¥æ ¹æ®ä½ çéè¦åå¨ä»»æé¿çæ¶é´ï¼ä¾å¦ï¼Vec<i32>æ¯èªå
å«çï¼æ éå¨ä»»ä½ç¹å®åéè¶
åºä½ç¨åä¹å被丢å¼ã使¯åVec<&'a i32>è¿æ ·çç±»åï¼å
¶çå½å¨æå¿
须被'aå
å´ï¼å®å¿
é¡»å¨å
¶å¼ç¨ç对象ä»ç¶åæ´»æ¶è¢«ä¸¢å¼ã
# ä¸åççå½å¨æåæ°
åè®¾ä½ å®ä¹äºä¸ä¸ªå å«ä¸¤ä¸ªå¼ç¨çç»æä½ï¼å¦ä¸æç¤ºï¼
struct S<'a> {
x: &'a i32,
y: &'a i32
}
2
3
4
两个å¼ç¨é½ä½¿ç¨ç¸åççå½å¨æ'aãå¦æä½ çä»£ç æ³è¦è¿æ ·åï¼å¯è½ä¼åºç°é®é¢ï¼
let x = 10;
let r;
{
let y = 20;
{
let s = S { x: &x, y: &y };
r = s.x;
}
}
println!("{}", r);
2
3
4
5
6
7
8
9
10
è¿æ®µä»£ç ä¸ä¼åå»ºä»»ä½æ¬ç©ºæéã对yçå¼ç¨ä¿åå¨sä¸ï¼så¨yä¹åè¶
åºä½ç¨åã对xçå¼ç¨æç»ä¿åå¨rä¸ï¼rççå½å¨æä¸ä¼è¶
è¿xã
ç¶èï¼å¦æä½ å°è¯ç¼è¯è¿æ®µä»£ç ï¼Rust伿±æ¨yççå½å¨æä¸å¤é¿ï¼å³ä½¿æ¾ç¶å®æ¯è¶³å¤çã
Rust为ä»ä¹ä¼æ å¿å¢ï¼å¦æä½ ä»ç»åæä»£ç ï¼å°±è½çè§£å®çé»è¾ï¼
Sçä¸¤ä¸ªåæ®µé½æ¯å ·æç¸åçå½å¨æ'açå¼ç¨ï¼æä»¥Rustå¿ é¡»æ¾å°ä¸ä¸ªå¯¹s.xås.yé½éç¨çåä¸çå½å¨æã- æä»¬æ§è¡
r = s.xï¼è¿è¦æ±'aå å´rççå½å¨æã - æä»¬ç¨
&yåå§ås.yï¼è¿è¦æ±'aä¸è¶ è¿yççå½å¨æã
è¿äºçº¦ææ¡ä»¶æ æ³åæ¶æ»¡è¶³ï¼ä¸å卿¯yçä½ç¨åç使¯rççå½å¨æé¿ççå½å¨æãRustæç»ç¼è¯ã
é®é¢å¨äºSä¸ç两个å¼ç¨å
·æç¸åççå½å¨æ'aãä¿®æ¹Sçå®ä¹ï¼è®©æ¯ä¸ªå¼ç¨æä¸åççå½å¨æï¼å°±è½è§£å³ææé®é¢ï¼
struct S<'a, 'b> {
x: &'a i32,
y: &'b i32
}
2
3
4
æç
§è¿ä¸ªå®ä¹ï¼s.xås.yæç¬ç«ççå½å¨æãæä»¬å¯¹s.xçæä½ä¸ä¼å½±ås.yä¸åå¨çå
å®¹ï¼æä»¥ç°å¨å¾å®¹ææ»¡è¶³çº¦ææ¡ä»¶ï¼'aå¯ä»¥å°±æ¯rççå½å¨æï¼'bå¯ä»¥æ¯sççå½å¨æãï¼yççå½å¨æä¹å¯ä»¥ä½ä¸º'bï¼ä½Rustä¼å°è¯éæ©æççææçå½å¨æãï¼ä¸å齿²¡é®é¢äºã
彿°ç¾åä¹å¯è½æç±»ä¼¼çå½±åãå设æä»¬æè¿æ ·ä¸ä¸ªå½æ°ï¼
fn f<'a>(r: &'a i32, s: &'a i32) -> &'a i32 { r } // perhaps too tight
è¿éï¼ä¸¤ä¸ªå¼ç¨åæ°é½ä½¿ç¨ç¸åççå½å¨æ'aï¼è¿å¯è½ä¼åæä»¬ä¹åå±ç¤ºç飿 ·ï¼ä¸å¿
è¦å°éå¶è°ç¨è
ãå¦æè¿æ¯ä¸ªé®é¢ï¼ä½ å¯ä»¥è®©åæ°ççå½å¨æç¬ç«ååï¼
fn f<'a, 'b>(r: &'a i32, s: &'b i32) -> &'a i32 { r } // looser
è¿æ ·åçç¼ºç¹æ¯ï¼å¢å çå½å¨æä¼ä½¿ç±»åå彿°ç¾åæ´é¾é è¯»ãæ¬ä¹¦çä½è å¾åäºå å°è¯æç®åçå®ä¹ï¼ç¶å鿥æ¾å®½éå¶ï¼ç´å°ä»£ç è½å¤ç¼è¯ãç±äºRustä¸ä¼å 许ä¸å®å ¨ç代ç è¿è¡ï¼æä»¥çå¾ Rustæåºé®é¢æå¨æ¯ä¸ç§å®å ¨å¯è¡ççç¥ã
# çç¥çå½å¨æåæ°
å°ç®å为æ¢ï¼æ¬ä¹¦ä¸å±ç¤ºäºå¾å¤è¿åå¼ç¨ææ¥æ¶å¼ç¨ä½ä¸ºåæ°ç彿°ï¼ä½æä»¬é常ä¸éè¦æç¡®æåºæ¯ä¸ªçå½å¨æãçå½å¨ææ¯åå¨çï¼åªæ¯å¨çå½å¨æå¾ææ¾çæ åµä¸ï¼Rustå 许æä»¬çç¥å®ä»¬ã
卿ç®åçæ åµä¸ï¼ä½ å¯è½æ°¸è¿ä¸éè¦ä¸ºåæ°ååºçå½å¨æãRustä¼ä¸ºæ¯ä¸ªéè¦çå½å¨æçå°æ¹åé ä¸ä¸ªä¸åççå½å¨æãä¾å¦ï¼
struct S<'a, 'b> {
x: &'a i32,
y: &'b i32
}
fn sum_xy(r: &i32, s: S) -> i32 {
r + s.x + s.y
}
2
3
4
5
6
7
8
è¿ä¸ªå½æ°çç¾åæ¯ä»¥ä¸åæ³çç®åï¼
fn sum_xy<'a, 'b, 'c>(r: &'a i32, s: S<'b, 'c>) -> i32
å¦æä½ è¿åå¼ç¨æå ¶ä»å¸¦æçå½å¨æåæ°çç±»åï¼Rustä»ç¶ä¼å°½éç®åæç¡®çæ åµã妿彿°åæ°ä¸åªåºç°ä¸ä¸ªçå½å¨æï¼é£ä¹Rustä¼åå®è¿åå¼ä¸çä»»ä½çå½å¨æé½å¿ é¡»æ¯è¿ä¸ªçå½å¨æï¼
fn first_third(point: &[i32; 3]) -> (&i32, &i32) {
(&point[0], &point[2])
}
2
3
宿´ååºææçå½å¨æççæä»£ç æ¯ï¼
fn first_third<'a>(point: &'a [i32; 3]) -> (&'a i32, &'a i32)
妿忰䏿å¤ä¸ªçå½å¨æï¼é£ä¹å¯¹äºè¿å弿¥è¯´ï¼æ²¡æèªç¶ççç±ååå ¶ä¸æä¸ä¸ªï¼Rustä¼è¦æ±ä½ æç¡®ååºå ·ä½æ åµã
å¦æä½ ç彿°æ¯æä¸ªç±»åçæ¹æ³ï¼å¹¶ä¸éè¿å¼ç¨æ¥æ¶selfåæ°ï¼é£ä¹è¿å°±æç ´äºè¿ç§ä¸ç¡®å®æ§ï¼Ruståå®selfççå½å¨æå°±æ¯è¿åå¼ä¸ææå
容ççå½å¨æãï¼selfåæ°æçæ¯è°ç¨æ¹æ³çé£ä¸ªå¼ï¼å®ç¸å½äºC++ãJavaæJavaScriptä¸çthisï¼æè
Pythonä¸çselfãæä»¬å°å¨âç¨implå®ä¹æ¹æ³âä¸ä»ç»æ¹æ³ãï¼
ä¾å¦ï¼ä½ å¯ä»¥è¿æ ·åï¼
struct StringTable {
elements: Vec<String>,
}
impl StringTable {
fn find_by_prefix(&self, prefix: &str) -> Option<&String> {
for i in 0..self.elements.len() {
if self.elements[i].starts_with(prefix) {
return Some(&self.elements[i]);
}
}
None
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
find_by_prefixæ¹æ³çç¾åæ¯ä»¥ä¸åæ³çç®åï¼
fn find_by_prefix<'a, 'b>(&'a self, prefix: &'b str) -> Option<&'a String>
Ruståå®ä½ åç¨çä»»ä½å
容齿¯ä»selfåç¨çã
åæ ·ï¼è¿äºåªæ¯ç¼©åï¼æ¨å¨æä¾ä¾¿å©ä¸ä¸ä¼å¸¦æ¥æå¤æ åµãå¦æä½ ä¸æ³è¦è¿ç§ç¼©åï¼æ»æ¯å¯ä»¥æ¾å¼ååºçå½å¨æã
# å ±äº«ä¸å¯å
å°ç®å为æ¢ï¼æä»¬è®¨è®ºäºRustå¦ä½ç¡®ä¿å¼ç¨æ°¸è¿ä¸ä¼æåå·²ç»è¶ åºä½ç¨åçåéã使¯ï¼è¿æå ¶ä»æ¹å¼ä¼å¼å ¥æ¬ç©ºæéãä¸é¢æ¯ä¸ä¸ªç®åçä¾åï¼
let v = vec![4, 8, 19, 27, 34, 10];
let r = &v;
let aside = v; // move vector to aside
r[0]; // bad: uses `v`, which is now uninitialized
2
3
4
对asideçèµå¼ç§»å¨äºåéï¼ä½¿væªåå§åï¼å¹¶ä¸å°råæäºæ¬ç©ºæéï¼å¦å¾5-7æç¤ºã
å¾5-7 æå已被移å¨èµ°çåéçå¼ç¨
è½ç¶å¨rçæ´ä¸ªçå½å¨æå
ï¼vé½å¨ä½ç¨åå
ï¼ä½è¿éçé®é¢æ¯vçå¼è¢«ç§»å¨å°äºå
¶ä»å°æ¹ï¼å¨rä»ç¶æå宿¶ï¼v被置为æªåå§åç¶æãèªç¶å°ï¼Rustæè·å°äºè¿ä¸ªé误ï¼
error[E0505]: cannot move out of `v` because it is borrowed
--> references_sharing_vs_mutation_1.rs:10:9
|
9 | let r = &v;
| - borrow of `v` occurs here
^^^^^ move out of `v` occurs here
10 | let aside = v; // move vector to aside
2
3
4
5
6
7
å¨å
±äº«å¼ç¨çæ´ä¸ªçå½å¨æå
ï¼å®ä¼ä½¿ææåç对象为åªè¯»ç¶æï¼ä½ ä¸è½å¯¹ææåç对象è¿è¡èµå¼ï¼ä¹ä¸è½å°å
¶å¼ç§»å¨å°å
¶ä»å°æ¹ãå¨è¿æ®µä»£ç ä¸ï¼rççå½å¨æå
å«äºç§»å¨åéçæä½ï¼æä»¥Rustæç»äºè¿ä¸ªç¨åºãå¦æä½ åè¿æ ·ä¿®æ¹ç¨åºï¼å°±ä¸ä¼æé®é¢ï¼
let v = vec![4, 8, 19, 27, 34, 10];
{
let r = &v;
r[0]; // ok: vector is still there
}
let aside = v;
2
3
4
5
6
å¨è¿ä¸ªçæ¬ä¸ï¼ræ´æ©å°è¶
åºäºä½ç¨åï¼å¼ç¨ççå½å¨æå¨v被移å¨ä¹åå°±ç»æäºï¼ä¸åæ£å¸¸ã
è¿æä¸ç§ä¸åçä¼å¼åé®é¢çæ åµãå设æä»¬æä¸ä¸ªæ¹ä¾¿ç彿°ï¼ç¨äºå°åçä¸çå ç´ æ·»å å°åéä¸ï¼
fn extend(vec: &mut Vec<f64>, slice: &[f64]) {
for elt in slice {
vec.push(*elt);
}
}
2
3
4
5
è¿æ¯æ ååºä¸åéçextend_from_sliceæ¹æ³çä¸ä¸ªçµæ´»æ§è¾å·®ï¼å¹¶ä¸ä¼åç¨åº¦ä½å¾å¤ï¼ççæ¬ãæä»¬å¯ä»¥ç¨å®ä»å
¶ä»åéææ°ç»çåçæå»ºä¸ä¸ªåéï¼
let mut wave = Vec::new();
let head = vec![0.0, 1.0];
let tail = [0.0, -1.0];
extend(&mut wave, &head); // extend wave with another vector
extend(&mut wave, &tail); // extend wave with an array
assert_eq!(wave, vec![0.0, 1.0, 0.0, -1.0]);
2
3
4
5
6
è¿æ ·æä»¬å°±æå»ºåºäºæ£å¼¦æ³¢çä¸ä¸ªå¨æã妿æä»¬æ³åæ·»å ä¸ä¸ªæ³¢å¨ï¼è½å°åé追å å°å®èªèº«åï¼
extend(&mut wave, &wave);
assert_eq!(wave, vec![0.0, 1.0, 0.0, -1.0,
0.0, 1.0, 0.0, -1.0]);
2
3
ä¹ä¸çï¼è¿ä¼¼ä¹æ²¡é®é¢ãä½è¯·è®°ä½ï¼å½æä»¬ååé䏿·»å å
ç´ æ¶ï¼å¦æå®çç¼å²åºå·²æ»¡ï¼å°±å¿
é¡»åé
ä¸ä¸ªæ´å¤§çæ°ç¼å²åºãå设waveæåæå®¹çº³å个å
ç´ ç空é´ï¼é£ä¹å½extendå°è¯æ·»å 第äºä¸ªå
ç´ æ¶ï¼å°±å¿
é¡»åé
ä¸ä¸ªæ´å¤§çç¼å²åºãå
åæç»ä¼å¦å¾5-8æç¤ºã
extend彿°çvecåæ°åç¨äºwaveï¼ç±è°ç¨è
æ¥æï¼ï¼wave为èªå·±åé
äºä¸ä¸ªè½å®¹çº³å
«ä¸ªå
ç´ çæ°ç¼å²åºã使¯sliceä»ç¶æå已被丢å¼çæ§çå个å
ç´ çç¼å²åºã
å¾5-8 å åééæ°åé
å
åèåææ¬ç©ºæéçåç
è¿ç±»é®é¢å¹¶éRustæç¬æï¼å¨å¾å¤è¯è¨ä¸ï¼å¨æåéåçåæ¶ä¿®æ¹éå齿¯éè¦å°å¿å¤ççæ
åµãå¨C++ä¸ï¼std::vectorè§èæéä½ ï¼â[åéç¼å²åºç]éæ°åé
ä¼ä½¿æååºåä¸å
ç´ çææå¼ç¨ãæéåè¿ä»£å¨å¤±æâã类似å°ï¼Javaå¨ä¿®æ¹java.util.Hashtableå¯¹è±¡æ¶æå°ï¼â妿å¨å建è¿ä»£å¨ä¹åç任使¶åï¼ä»¥è¿ä»£å¨èªèº«çremoveæ¹æ³ä¹å¤ç任使¹å¼å¯¹Hashtableè¿è¡ç»æä¿®æ¹ï¼è¿ä»£å¨å°æåºConcurrentModificationExceptionå¼å¸¸âã
è¿ç±»é误ç¹å«æ£æçå°æ¹å¨äºï¼å®å¹¶éæ»æ¯ä¼åºç°ã卿µè¯æ¶ï¼ä½ çåéå¯è½æ»æ¯æ°å¥½æè¶³å¤ç空é´ï¼ç¼å²åºå¯è½æ°¸è¿ä¸ä¼éæ°åé ï¼é®é¢ä¹å°±æ°¸è¿ä¸ä¼æ´é²åºæ¥ã
ç¶èï¼Rustå¨ç¼è¯æ¶å°±æ¥åäºæä»¬è°ç¨extendæ¶çé®é¢ï¼
error[E0502]: cannot borrow `wave` as immutable because it is also borrowed as mutable
--> references_sharing_vs_mutation_2.rs:9:24
|
| ^^^^- mutable borrow ends here
9 | extend(&mut wave, &wave);
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
2
3
4
5
6
7
8
æ¢å¥è¯è¯´ï¼æä»¬å¯ä»¥åç¨åéçå¯åå¼ç¨ï¼ä¹å¯ä»¥åç¨å
¶å
ç´ çå
±äº«å¼ç¨ï¼ä½è¿ä¸¤ä¸ªå¼ç¨ççå½å¨æä¸è½éå ã卿们çä¾åä¸ï¼ä¸¤ä¸ªå¼ç¨ççå½å¨æé½å
å«å¯¹extendçè°ç¨ï¼æä»¥Rustæç»äºè¿æ®µä»£ç ã
è¿äºéè¯¯é½æºäºè¿åäºRustå ³äºå¯ååå ±äº«çè§åï¼
- å ±äº«è®¿é®æ¯åªè¯»è®¿é®ï¼å ±äº«å¼ç¨åç¨ç弿¯åªè¯»çãå¨å ±äº«å¼ç¨çæ´ä¸ªçå½å¨æå ï¼å®ææåç对象ï¼ä»¥åä»è¯¥å¯¹è±¡å¯è¾¾çä»»ä½å 容ï¼é½ä¸è½è¢«ä»»ä½æä½ä¿®æ¹ãè¯¥ç»æä¸ä»»ä½å 容é½ä¸å卿æçå¯åå¼ç¨ï¼å ¶ææè ä¹è¢«è§ä¸ºåªè¯»ï¼ççãå®å®é 䏿¯è¢«å»ç»çã
- å¯åè®¿é®æ¯ç¬å 访é®ï¼éè¿å¯åå¼ç¨åç¨çå¼ï¼åªè½é è¿ä¸ªå¯åå¼ç¨æ¥è®¿é®ãå¨å¯åå¼ç¨åå¨çæ´ä¸ªæé´ï¼æ²¡åæ³éè¿å ¶ä»éå¾è®¿é®å®ææåçå¼ï¼ä¹ä¸è½è®¿é®ä»è¿ä¸ªå¼è½è®¿é®å°çå ¶ä»å¼ãåªæä»è¿ä¸ªå¯åå¼ç¨æ¬èº«åç¨æ¥çå¼ç¨ï¼å ¶çå½å¨ææå¯ä»¥åè¿ä¸ªå¯åå¼ç¨ççå½å¨ææéå ï¼å ¶ä»å¼ç¨é½ä¸è¡ã
Rustæextend彿°çä¾åå½ä½è¿åç¬¬äºæ¡è§åçæ
嵿¥å¤çï¼å 为æä»¬åç¨äºwaveçå¯åå¼ç¨ï¼é£ä¹è¿ä¸ªå¯åå¼ç¨å°±å¿
é¡»æ¯è®¿é®åéæå
¶å
ç´ çå¯ä¸éå¾ãè对åççå
±äº«å¼ç¨æ¬èº«å°±æ¯å¦ä¸ç§è®¿é®å
ç´ çæ¹å¼ï¼è¿å°±è¿åäºç¬¬äºæ¡è§åã
ä½Rustä¹å¯ä»¥æè¿ä¸ªé误å½ä½è¿åç¬¬ä¸æ¡è§åæ¥å¤çï¼å 为æä»¬åç¨äºwaveå
ç´ çå
±äº«å¼ç¨ï¼é£ä¹è¿äºå
ç´ åVecæ¬èº«å°±é½æ¯åªè¯»çãä½ ä¸è½å¯¹åªè¯»çå¼åç¨å¯åå¼ç¨ã
æ¯ç§å¼ç¨é½ä¼å½±åæä»¬å¯¹æ²¿çæå被å¼ç¨å¯¹è±¡çæææè·¯å¾ä¸çå¼ï¼ä»¥åä»è¢«å¼ç¨å¯¹è±¡å¯è¾¾çå¼çæä½ï¼å¾5-9ï¼ã
å¾5-9 åç¨å¼ç¨ä¼å½±åä½ å¯¹åä¸ææææ ä¸å
¶ä»å¼çæä½
注æï¼å¨è¿ä¸¤ç§æ åµä¸ï¼å¨å¼ç¨ççå½å¨æå ï¼æå被å¼ç¨å¯¹è±¡çæææè·¯å¾é½ä¸è½æ¹åã对äºå ±äº«åç¨ï¼è¿æ¡è·¯å¾æ¯åªè¯»çï¼å¯¹äºå¯ååç¨ï¼è¿æ¡è·¯å¾æ¯å®å ¨ä¸å¯è®¿é®çãæä»¥ç¨åºæ æ³ååºä»»ä½ä¼ä½¿å¼ç¨æ æçæä½ã
æè¿äºååç¨æç®åçä¾åæ¥å±ç¤ºï¼
let mut x = 10;
let r1 = &x;
let r2 = &x;
x += 10; // ok: multiple shared borrows permitted
let m = &mut x; // error: cannot assign to `x` because it is borrowed
// error: cannot borrow `x` as mutable because it is also borrowed as immutable
println!("{}, {}, {}", r1, r2, m); // the references are used here, so their lifetimes must last at least this long
let mut y = 20;
let m1 = &mut y;
let m2 = &mut y; // error: cannot borrow as mutable more than once
let z = y; // error: cannot use `y` because it was mutably borrowed
println!("{}, {}, {}", m1, m2, z); // references are used here
2
3
4
5
6
7
8
9
10
11
12
13
ä»å ±äº«å¼ç¨ååç¨ä¸ä¸ªå ±äº«å¼ç¨æ¯å¯ä»¥çï¼
let mut w = (107, 109);
let r = &w;
let r0 = &r.0; // ok: reborrowing shared as shared
let m1 = &mut r.1; // error: can't reborrow shared as mutable
println!("{}", r0); // r0 gets used here
2
3
4
5
ä½ ä¹å¯ä»¥ä»å¯åå¼ç¨è¿è¡ååç¨ï¼
let mut v = (136, 139);
let m = &mut v;
let m0 = &mut m.0; // ok: reborrowing mutable from mutable
*m0 = 137;
let r1 = &m.1; // ok: reborrowing shared from mutable, and doesn't overlap with m0
v.1; // error: access through other paths still forbidden
println!("{}", r1); // r1 gets used here
2
3
4
5
6
7
8
è¿äºéå¶ç¸å½ä¸¥æ ¼ãå尿们ä¹åå°è¯è°ç¨çextend(&mut wave, &wave)ï¼æ²¡æç®åå¿«æ·çæ¹æ³è½ä¿®æ¹ä»£ç 使å
¶ææä»¬ææçæ¹å¼è¿è¡ãèä¸Rust卿æå°æ¹é½åºç¨è¿äºè§åï¼æ¯å¦ï¼å¦ææä»¬åç¨äºHashMapä¸æä¸ªé®çå
±äº«å¼ç¨ï¼é£ä¹å¨è¿ä¸ªå
±äº«å¼ç¨ççå½å¨æç»æä¹åï¼æä»¬ä¸è½åç¨HashMapçå¯åå¼ç¨ã
ä½è¿æ ·åæ¯æå
åçç±çï¼è®¾è®¡æ¯ææ éå¶ãåæ¶è¿è¡è¿ä»£åä¿®æ¹çé忝å¾å°é¾çï¼èä¸è¿é叏伿餿´ç®åãæ´é«æçå®ç°æ¹å¼ãJavaçHashtableåC++çvector齿²¡æå»è§£å³è¿ä¸ªé®é¢ï¼Pythonçåå
¸åJavaScriptçå¯¹è±¡ä¹æ²¡ææç¡®å®ä¹è¿ç§è®¿é®çå
·ä½è¡ä¸ºãJavaScriptä¸çå
¶ä»éåç±»åæç¸å
³å®ä¹ï¼ä½ç»ææ¯å®ç°èµ·æ¥æ´å¤æãC++çstd::mapæ¿è¯ºæå
¥æ°æ¡ç®ä¸ä¼ä½¿æåå
¶ä»æ¡ç®çæé失æï¼ä½ä¸ºäºå®ç°è¿ä¸ªæ¿è¯ºï¼è¯¥æ åæé¤äºåRustçBTreeMap飿 ·æ´é«æå©ç¨ç¼åç设计ï¼BTreeMap卿 çæ¯ä¸ªèç¹ä¸åå¨å¤ä¸ªæ¡ç®ã
ä¸é¢æ¯è¿äºè§åè½å¤ææå°çå¦ä¸ç§é误示ä¾ãèèä¸é¢è¿æ®µC++代ç ï¼å®ç¨äºç®¡çæä»¶æè¿°ç¬¦ã为äºç®åï¼æä»¬åªå±ç¤ºæé 彿°åå¤å¶èµå¼è¿ç®ç¬¦ï¼å¹¶ä¸çç¥é误å¤çï¼
struct File {
int descriptor;
File(int d) : descriptor(d) {}
File& operator=(const File &rhs) {
close(descriptor);
descriptor = dup(rhs.descriptor);
return *this;
}
};
2
3
4
5
6
7
8
9
10
èµå¼è¿ç®ç¬¦çèµ·æ¥å¾ç®åï¼ä½å¨è¿ç§æ åµä¸ä¼åºå¤§é®é¢ï¼
File f(open("foo.txt", ...));
...
f = f;
2
3
妿æä»¬å°ä¸ä¸ªFile对象èµå¼ç»èªå·±ï¼rhså*thisæ¯åä¸ä¸ªå¯¹è±¡ï¼æä»¥operator=å¨å³å°ææä»¶æè¿°ç¬¦ä¼ éç»dupä¹åå°±å
³éäºå®ãæä»¬ç ´åäºæ¬åºå¤å¶çèµæºã
å¨Rustä¸ï¼ç±»ä¼¼ç代ç å¦ä¸ï¼
struct File {
descriptor: i32
}
fn new_file(d: i32) -> File {
File { descriptor: d }
}
fn clone_from(this: &mut File, rhs: &File) {
close(this.descriptor);
this.descriptor = dup(rhs.descriptor);
}
2
3
4
5
6
7
8
9
10
11
12
ï¼è¿ä¸æ¯ç¬¦åRustä¹ æ¯ç代ç ãå¨Rustä¸ï¼æå¾å¥½çæ¹æ³ä¸ºç±»åå®ä¹æé 彿°åæ¹æ³ï¼æä»¬å°å¨ç¬¬9ç« ä»ç»ï¼ä½ä¸è¿°å®ä¹éç¨äºè¿ä¸ªä¾åãï¼
妿æä»¬ç¼åä¸ä½¿ç¨File对åºçRust代ç ï¼ä¼å¾å°ï¼
let mut f = new_file(open("foo.txt", ...));
...
clone_from(&mut f, &f);
2
3
å½ç¶ï¼Rustçè³ä¸ä¼ç¼è¯è¿æ®µä»£ç ï¼
error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
--> references_self_assignment.rs:18:25
|
| ^- mutable borrow ends here
18 | clone_from(&mut f, &f);
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
2
3
4
5
6
7
8
è¿çèµ·æ¥åºè¯¥å¾ç¼çãäºå®è¯æï¼ä¸¤ä¸ªç»å
¸çC++é误ââæ æ³å¤çèªèµå¼åä½¿ç¨æ æè¿ä»£å¨ï¼æ¬è´¨ä¸æ¯åä¸ç§é误ï¼å¨è¿ä¸¤ç§æ
åµä¸ï¼ä»£ç é½åå®å¨åèå¦ä¸ä¸ªå¼çåæ¶ä¿®æ¹ä¸ä¸ªå¼ï¼ä½å®é
ä¸å®ä»¬æ¯åä¸ä¸ªå¼ãå¦æä½ å¨CæC++ä¸ï¼æ¾ä¸å°å¿è®©memcpyæstrcpyè°ç¨çæºåç®æ éå ï¼é£å°±æ¯è¿ç§é误çå¦ä¸ç§å½¢å¼ãéè¿è¦æ±å¯åè®¿é®æ¯ç¬å çï¼Rusté¿å
äºå¾å¤å¸¸è§é误ã
å¨ç¼åå¹¶åä»£ç æ¶ï¼å ±äº«å¼ç¨åå¯åå¼ç¨ä¸è½æ··å使ç¨çè§åçæ£ä½ç°åºäºä»·å¼ãåªæå½æä¸ªå¼å¨å¤ä¸ªçº¿ç¨ä¹é´æ¢å¯ååå ±äº«æ¶ï¼æå¯è½åºç°æ°æ®ç«äºââèè¿æ£æ¯Rustçå¼ç¨è§åæé¿å çæ åµãä¸ä¸ªé¿å 使ç¨ä¸å®å ¨ä»£ç çå¹¶åRustç¨åºï¼ä»ç»æä¸å°±ä¸ä¼åºç°æ°æ®ç«äºã
æä»¬å°å¨ç¬¬19ç« è®¨è®ºå¹¶åæ¶æ´è¯¦ç»å°ä»ç»è¿æ¹é¢å 容ï¼ä½æ»ä¹ï¼å¨Rustä¸ä½¿ç¨å¹¶åæ¯å¨å¤§å¤æ°å ¶ä»è¯è¨ä¸è¦å®¹æå¾å¤ã
# Rustçå ±äº«å¼ç¨ä¸Cè¯è¨æå常éçæé对æ¯
ä¹ä¸çï¼Rustçå ±äº«å¼ç¨ä¼¼ä¹ä¸CåC++䏿å常éå¼çæéå¾ç¸ä¼¼ãç¶èï¼Rustå¯¹å ±äº«å¼ç¨çè§åè¦ä¸¥æ ¼å¾å¤ãä¾å¦ï¼èèä¸é¢è¿æ®µC代ç ï¼
int x = 42; // int variable, not const
const int *p = &x; // pointer to const int
assert(*p == 42);
x++; // change variable directly
assert(*p == 43); // âconstantâ referent's value has changed
2
3
4
5
pæ¯const int *ç±»åï¼è¿æå³çä½ ä¸è½éè¿pæ¬èº«ä¿®æ¹å®ææåçå¼ï¼(*p)++æ¯è¢«ç¦æ¢çã使¯ä½ ä¹å¯ä»¥ç´æ¥éè¿x访é®è¢«æåçå¼ï¼èx䏿¯å¸¸éï¼æä»¥å¯ä»¥è¿æ ·ä¿®æ¹å®çå¼ãCè¯è¨å®¶æä¸çconstå
³é®åæå®çç¨éï¼ä½å®å¹¶ä¸è½çæ£ä¿è¯å¸¸éæ§ã
å¨Rustä¸ï¼å ±äº«å¼ç¨ç¦æ¢å¨å ¶çå½å¨æç»æåå¯¹å ¶æåçå¼è¿è¡ä»»ä½ä¿®æ¹ï¼
let mut x = 42; // non-const i32 variable
let p = &x; // shared reference to i32
assert_eq!(*p, 42);
x += 1; // error: cannot assign to x because it is borrowed
assert_eq!(*p, 42); // if you take out the assignment, this is true
2
3
4
5
为äºç¡®ä¿ä¸ä¸ªå¼æ¯å¸¸éï¼æä»¬éè¦è·è¸ªææå¯è½è®¿é®è¯¥å¼çè·¯å¾ï¼å¹¶ç¡®ä¿è¿äºè·¯å¾è¦ä¹ä¸å 许修æ¹ï¼è¦ä¹æ ¹æ¬ä¸è½ä½¿ç¨ãCåC++çæééå¶å¤ªå°ï¼ç¼è¯å¨æ æ³è¿è¡è¿ç§æ£æ¥ãRustçå¼ç¨æ»æ¯ä¸ç¹å®ççå½å¨æç¸å ³èï¼è¿ä½¿å¾å¨ç¼è¯æ¶è¿è¡æ£æ¥æä¸ºå¯è½ã
# 对æå¯¹è±¡æµ·æ´
èª20ä¸çºª90年代èªå¨å å管çå ´èµ·ä»¥æ¥ï¼ææç¨åºçé»è®¤æ¶æå°±åæäºâ对象海æ´âï¼å¦å¾5-10æç¤ºã è¿å°±æ¯å¨æåå¾åæ¶æºå¶çæ åµä¸ï¼ä½ 卿²¡æä»»ä½è®¾è®¡å°±å¼å§ç¼åç¨åºæ¶ä¼åºç°çæ åµãæä»¬é½æå»ºè¿ç±»ä¼¼è¿æ ·çç³»ç»ã
è¿ç§æ¶ææå¾å¤å¾ä¸æ²¡æä½ç°çä¼ç¹ï¼åæè¿å±è¿ éï¼å¾å®¹ææ·»å åè½ï¼èä¸å å¹´åï¼ä½ å®å ¨æçç±å¯¹æ´ä¸ªç³»ç»è¿è¡éåãï¼æ¤æ¶å¯ä»¥ææ¾AC/DCçãHighway to Hellããï¼
å½ç¶ï¼å®ä¹æç¼ºç¹ã彿æä¸è¥¿é½åè¿æ ·ç¸äºä¾èµæ¶ï¼å¾é¾å¯¹ä»»ä½ä¸ä¸ªç»ä»¶è¿è¡åç¬æµè¯ãæ¹è¿ï¼çè³é¾ä»¥åç¬æèã
å¾5-10 对象海æ´
Rustä¸ä¸ªå¾æè¶£çå°æ¹å¨äºï¼ææææ¨¡åç»éå¾âå°ç±âï¼æ··ä¹±çç¼ç¨ç¶æï¼çé路设置äºåé带ãå¨Rustä¸å建ä¸ä¸ªå¾ªç¯ï¼å³ä¸¤ä¸ªå¼ï¼æ¯ä¸ªå¼é½å
å«ä¸ä¸ªæåå¦ä¸ä¸ªå¼çå¼ç¨ï¼éè¦è´¹ç¹å夫ãä½ éè¦ä½¿ç¨æºè½æéç±»åï¼æ¯å¦Rcï¼ä»¥åå
é¨å¯åæ§ï¼è¿æ¯æä»¬è¿æ²¡è®²å°çå
容ï¼ãRustæ´å¾åäºè®©æéãæææåæ°æ®æµå¨ç³»ç»ä¸ååä¼ éï¼å¦å¾5-11æç¤ºã
å¾5-11 å¼çæ ç¶ç»æ
æä»¬ç°å¨æå°è¿ä¸ªçåå æ¯ï¼è¯»å®æ¬ç« åï¼ä½ å¾èªç¶å°å¯è½ä¼æ³é©¬ä¸å建ä¸ä¸ªç±Rcæºè½æéè¿æ¥èµ·æ¥çâç»æä½æµ·æ´âï¼éæ°åé åºä½ çæçææé¢å对象ç忍¡å¼ãä½è¿ä¸ä¼é©¬ä¸æåãRustçææææ¨¡åä¼ç»ä½ 带æ¥ä¸äºéº»ç¦ãè§£å³åæ³æ¯è¿è¡ä¸äºé¢å
è®¾è®¡ï¼æå»ºä¸ä¸ªæ´å¥½çç¨åºã
Rustè´åäºå°çè§£ç¨åºççè¦ä»æªæ¥è½¬ç§»å°ç°å¨ãå®çææåºå¥å°å¥½ï¼Rustä¸ä» è½è¿«ä½¿ä½ ç解为ä»ä¹ä½ çç¨åºæ¯çº¿ç¨å®å ¨çï¼çè³è¿è½è¦æ±ä½ è¿è¡ä¸å®ç¨åº¦çé«çº§æ¶æè®¾è®¡ã