第16ç« éå
# 第16ç« éå
æä»¬çè¡ä¸ºé½å¦åéº¦å æ¯é¦å¦ãçç©ä½è¿è¡çç»ç»æ´»å¨ã卿¥å¸¸ç»éªä¸ï¼è½æ¾å°ä¸¤ä¸ªä¸çºªä»¥æ¥ä¸¥è°¨çç©çå¦å®¶ä¸ç´çè¡·äºè¿ä¸ªå¥å¦å¹»æ³çåå ãæä»¬åæ£é®ä»¶ãå»ºé æ²å ¡ãç©æ¼å¾ãæ¬è°·ãéæ°æåæ£åãéé®ãç»ä¹¦ç±æåæ¯é¡ºåºæåãåé å¯¹ç§°å¾æ¡ãåä½ååè¡è¯åå¥é¸£æ²ï¼è¿ä¼æ´çæ¿é´ãåªè¦æä»¬è¿ç¨æºæ §ï¼åè¿äºäºå¹¶ä¸éè¦æ¶è太å¤ç²¾åã ââè©¹å§æ¯Â·æ ¼é·å ï¼ãä¿¡æ¯ç®å²ï¼ä¸é¨åå²ï¼ä¸ä¸ªç论ï¼ä¸è¡æ´ªæµã
Rustæ ååºå
å«å¤ç§éåï¼è¿äºæ³åç±»åç¨äºå¨å
åä¸å卿°æ®ã卿¬ä¹¦ä¸ï¼æä»¬å·²ç»ä¸ç´å¨ä½¿ç¨è¯¸å¦VecåHashMapçéåã卿¬ç« ä¸ï¼æä»¬å°è¯¦ç»ä»ç»è¿ä¸¤ç§ç±»åçæ¹æ³ï¼ä»¥åå
¶ä»å ç§æ åéåãå¨å¼å§ä¹åï¼è®©æä»¬å
æ¢è®¨ä¸ä¸Rustéåä¸å
¶ä»è¯è¨éåä¹é´çä¸äºç³»ç»æ§å·®å¼ã
é¦å
ï¼ç§»å¨ï¼moveï¼ååç¨ï¼borrowingï¼æ å¤ä¸å¨ãRust使ç¨ç§»å¨è¯ä¹æ¥é¿å
深度å¤å¶å¼ãè¿å°±æ¯ä¸ºä»ä¹Vec<T>::push(item)æ¹æ³æå¼è䏿¯æå¼ç¨æ¥æ¶åæ°ãå¼è¢«ç§»å¨å°åéä¸ã第4ç« ä¸çå¾ç¤ºå±ç¤ºäºè¿å¨å®é
ä¸çå·¥ä½åçï¼å°ä¸ä¸ªRustçStringç±»åå¼åå
¥Vec<String>ä¸å¾å¿«ï¼å 为Rustä¸å¿
å¤å¶å符串çåç¬¦æ°æ®ï¼å¹¶ä¸åç¬¦ä¸²çæææå§ç»æ¸
æ°æç¡®ã
å
¶æ¬¡ï¼Rust没æå¤±æé误ï¼invalidation errorsï¼ï¼å³é£ç§å¨ç¨åºæææåéåå
鍿°æ®çæéæ¶ï¼éå大å°è°æ´æåçå
¶ä»åå导è´çæ¬ç©ºæéé误ã失æé误æ¯C++䏿ªå®ä¹è¡ä¸ºçå¦ä¸ä¸ªæ¥æºï¼çè³å¨å
åå®å
¨çè¯è¨ä¸ï¼å®ä¹å¶å°ä¼å¼åConcurrentModificationExceptionå¼å¸¸ãRustçåç¨æ£æ¥å¨å¨ç¼è¯æ¶å°±æé¤äºè¿ç±»é误ã
æåï¼Rust没ænullï¼æä»¥å¨å
¶ä»è¯è¨ä½¿ç¨nullçå°æ¹ï¼æä»¬ä¼çå°Optionç±»åã
é¤äºè¿äºå·®å¼ï¼Rustçéååä½ é¢æçå·®ä¸å¤ãå¦æä½ æ¯ä¸ä½ç»éªä¸°å¯ä¸æ¶é´ç´§è¿«çç¨åºåï¼å¯ä»¥å¿«éæµè§æ¬ç« å 容ï¼ä½ä¸è¦éè¿âEntriesâï¼æ¡ç®ï¼é¨åã
# æ¦è¿°
表16-1å±ç¤ºäºRustçå «ç§æ åéåãå®ä»¬é½æ¯æ³åç±»åã
表16-1. æ åéåæ¦è¿°
| éå | æè¿° | C++ä¸ç类似éåç±»å | Javaä¸ç类似éåç±»å | Pythonä¸ç类似éåç±»å |
|---|---|---|---|---|
Vec<T> | å¯å¢é¿æ°ç» | vector | ArrayList | list |
VecDeque<T> | å端éåï¼å¯å¢é¿çç¯å½¢ç¼å²åºï¼ | deque | ArrayDeque | collections.deque |
LinkedList<T> | ååé¾è¡¨ | list | LinkedList | â |
BinaryHeap<T>å ¶ä¸ T: Ord | æå¤§å | priority_queue | PriorityQueue | heapq |
HashMap<K, V>å ¶ä¸ K: Eq + Hash | é®å¼å¯¹åå¸è¡¨ | unordered_map | HashMap | dict |
BTreeMap<K, V>å ¶ä¸ K: Ord | æåºé®å¼å¯¹è¡¨ | map | TreeMap | â |
HashSet<T>å ¶ä¸ T: Eq + Hash | åºäºåå¸çæ åºéå | unordered_set | HashSet | set |
BTreeSet<T>å ¶ä¸ T: Ord | æåºéå | set | TreeSet | â |
Vec<T>ãHashMap<K, V>åHashSet<T>æ¯æå¸¸ç¨çéåç±»åãå
¶ä½çéåæç¹å®ç使ç¨åºæ¯ãæ¬ç« å°ä¾æ¬¡è®¨è®ºæ¯ç§éåç±»åï¼
Vec<T>ï¼ä¸ç§å¯å¢é¿çãå¨å ä¸åé çTç±»åå¼çæ°ç»ãæ¬ç« 大约ä¸åçå 容å°ä»ç»Vecåå ¶ä¼å¤æç¨çæ¹æ³ãVecDeque<T>ï¼ä¸Vec<T>类似ï¼ä½æ´éåç¨ä½å è¿å åºéåã宿¯æå¨å表çå端ååç«¯é«æå°æ·»å åå é¤å¼ãä¸è¿ï¼è¿ä¼å¯¼è´å ¶ä»æææä½ç¨å¾®åæ ¢ãBinaryHeap<T>ï¼ä¸ç§ä¼å éåãBinaryHeapä¸çå¼è¢«ç»ç»èµ·æ¥ï¼ä»¥ä¾¿å§ç»è½é«æå°æ¥æ¾åå 餿大å¼ãHashMap<K, V>ï¼ä¸ç§é®å¼å¯¹è¡¨ãéè¿é®æ¥æ¾å¼çé度å¾å¿«ãæ¡ç®ä»¥ä»»æé¡ºåºåå¨ãBTreeMap<K, V>ï¼ä¸HashMap<K, V>类似ï¼ä½å®ä¼æé®å¯¹æ¡ç®è¿è¡æåºãBTreeMap<String, i32>伿Stringçæ¯è¾é¡ºåºåå¨å ¶æ¡ç®ãé¤éä½ éè¦æ¡ç®ä¿ææåºï¼å¦åHashMapçé度æ´å¿«ãHashSet<T>ï¼ä¸ç§Tç±»åå¼çéåãæ·»å åå é¤å¼çé度å¾å¿«ï¼å¤æç»å®å¼æ¯å¦å¨éåä¸ä¹å¾å¿«ãBTreeSet<T>ï¼ä¸HashSet<T>类似ï¼ä½å®ä¼æå¼å¯¹å ç´ è¿è¡æåºãåæ ·ï¼é¤éä½ éè¦æ°æ®æåºï¼å¦åHashSetçé度æ´å¿«ã
ç±äºLinkedListå¾å°è¢«ä½¿ç¨ï¼å¹¶ä¸å¨å¤§å¤æ°ä½¿ç¨åºæ¯ä¸ï¼å¨æ§è½åæ¥å£æ¹é¢é½ææ´å¥½çæ¿ä»£æ¹æ¡ï¼ï¼æä»¬å¨è¿éä¸ä¼å¯¹å
¶è¿è¡æè¿° ã
# Vec<T>
ç±äºæä»¬å¨æ¬ä¹¦ä¸ä¸ç´å¨ä½¿ç¨Vecï¼æä»¥åè®¾å¤§å®¶å¯¹å®æä¸å®çäºè§£ãè¥è¦äºè§£å
¶å
¥é¨ç¥è¯ï¼è¯·åè§âVectorsâï¼åéï¼ãå¨è¿éï¼æä»¬å°æ·±å
¥ä»ç»å®çæ¹æ³åå
¶å
é¨å·¥ä½åçã
å建åéæç®åçæ¹æ³æ¯ä½¿ç¨vec!å®ï¼
// å建ä¸ä¸ªç©ºåé
let mut numbers: Vec<i32> = vec![];
// å建ä¸ä¸ªå
·æç»å®å
容çåé
let words = vec!["step", "on", "no", "pets"];
let mut buffer = vec![0u8; 1024]; // 1024个å½é¶çåè
2
3
4
5
å¦ç¬¬4ç« æè¿°ï¼åéæä¸ä¸ªå段ï¼é¿åº¦ã容éï¼ä»¥åä¸ä¸ªæååå¨å
ç´ çå åé
空é´çæéãå¾16-1å±ç¤ºäºä¸è¿°åéå¨å
åä¸çæ ·åã空åénumbersæåç容é为0ã卿·»å 第ä¸ä¸ªå
ç´ ä¹åï¼ä¸ä¼ä¸ºå®åé
å å
åã
䏿æéå䏿 ·ï¼Vecå®ç°äºstd::iter::FromIteratorï¼æä»¥ä½ å¯ä»¥ä½¿ç¨è¿ä»£å¨ç.collect()æ¹æ³ä»ä»»ä½è¿ä»£å¨å建åéï¼å¦âBuilding Collections: collect and FromIteratorâï¼æå»ºéåï¼collectåFromIteratorï¼ä¸æè¿°ï¼
// å°å¦ä¸ä¸ªéå转æ¢ä¸ºåé
let my_vec = my_set.into_iter().collect::<Vec<String>>();
2
å¾16-1. åéå¨å
åä¸çå¸å±ï¼wordsä¸çæ¯ä¸ªå
ç´ é½æ¯ä¸ä¸ª&strå¼ï¼ç±ä¸ä¸ªæéåä¸ä¸ªé¿åº¦ç»æ
# 访é®å ç´
éè¿ç´¢å¼è·åæ°ç»ãåçæåéçå ç´ å¾ç®åï¼
// è·å对å
ç´ çå¼ç¨
let first_line = &lines[0];
// è·åå
ç´ ç坿¬
let fifth_number = numbers[4]; // éè¦Copy
let second_line = lines[1].clone(); // éè¦Clone
// è·å对åççå¼ç¨
let my_ref = &buffer[4..12];
// è·ååçç坿¬
let my_copy = buffer[4..12].to_vec(); // éè¦Clone
2
3
4
5
6
7
8
9
å¦æç´¢å¼è¶ åºèå´ï¼ææè¿äºå½¢å¼é½ä¼å¯¼è´ç¨åºææ ï¼panicï¼ã
Rust对æ°å¼ç±»åè¦æ±ä¸¥æ ¼ï¼å¯¹åéä¹ä¸ä¾å¤ãåéçé¿åº¦åç´¢å¼çç±»åæ¯usizeãå°è¯ä½¿ç¨u32ãu64æisizeä½ä¸ºåéç´¢å¼ä¼åºéãä½ å¯ä»¥æ ¹æ®éè¦ä½¿ç¨n as usizeè¿è¡ç±»å转æ¢ï¼åè§âType Castsâï¼ç±»å转æ¢ï¼ã
æå ä¸ªæ¹æ³å¯ä»¥æ¹ä¾¿å°è®¿é®åéæåççç¹å®å ç´ ï¼è¯·æ³¨æï¼ææåçæ¹æ³ä¹éç¨äºæ°ç»ååéï¼ï¼
slice.first()ï¼è¿å对åç第ä¸ä¸ªå ç´ çå¼ç¨ï¼å¦ææçè¯ï¼ãè¿åç±»åæ¯Option<&T>ï¼æä»¥å¦æåç为空ï¼è¿å弿¯Noneï¼å¦æä¸ä¸ºç©ºï¼è¿å弿¯Some(&slice[0])ï¼
if let Some(item) = v.first() {
println!("We got one! {}", item);
}
2
3
slice.last()ï¼ä¸first()类似ï¼ä½è¿å对æåä¸ä¸ªå ç´ çå¼ç¨ãslice.get(index)ï¼å¦æslice[index]åå¨ï¼åè¿å对å®çSomeå¼ç¨ã妿åççå ç´ æ°éå°äºindex + 1ï¼åè¿åNoneï¼
let slice = [0, 1, 2, 3];
assert_eq!(slice.get(2), Some(&2));
assert_eq!(slice.get(4), None);
2
3
slice.first_mut()ãslice.last_mut()ãslice.get_mut(index)ï¼ä¸è¿°æ¹æ³çå¯ååç¨çæ¬ï¼
let mut slice = [0, 1, 2, 3];
{
let last = slice.last_mut().unwrap(); // lastçç±»å: &mut i32
assert_eq!(*last, 3);
*last = 100;
}
assert_eq!(slice, [0, 1, 2, 100]);
2
3
4
5
6
7
å 为æå¼è¿åTæå³çç§»å¨å®ï¼æä»¥å°±å°è®¿é®å
ç´ çæ¹æ³é常æå¼ç¨è¿åè¿äºå
ç´ ã
.to_vec()æ¹æ³æ¯ä¸ªä¾å¤ï¼å®ä¼è¿è¡å¤å¶ï¼
slice.to_vec()ï¼å éæ´ä¸ªåçï¼è¿åä¸ä¸ªæ°çåéï¼
let v = [1, 2, 3, 4, 5, 6, 7, 8, 9];
assert_eq!(v.to_vec(),
vec![1, 2, 3, 4, 5, 6, 7, 8, 9]);
assert_eq!(v[0..6].to_vec(),
vec![1, 2, 3, 4, 5, 6]);
2
3
4
5
åªæå½å
ç´ æ¯å¯å
éçï¼å³T: Cloneæ¶ï¼è¿ä¸ªæ¹æ³æå¯ç¨ã
# è¿ä»£
åéååç齿¯å¯è¿ä»£çï¼å¯ä»¥æå¼ææå¼ç¨è¿ä»£ï¼éµå¾ªâIntoIterator Implementationsâï¼IntoIteratorå®ç°ï¼ä¸æè¿°ç模å¼ï¼
- 对
Vec<T>è¿è¡è¿ä»£ä¼çæTç±»åçå ç´ ãå ç´ ä¼ä¸ä¸ªä¸ä¸ªå°ä»åéä¸ç§»åºï¼æ¶èæåéã - 对
&[T; N]ã&[T]æ&Vec<T>ç±»åçå¼ï¼å³å¯¹æ°ç»ãåçæåéçå¼ç¨ï¼è¿è¡è¿ä»£ï¼ä¼çæ&Tç±»åçå ç´ ï¼å³å¯¹å个å ç´ çå¼ç¨ï¼è¿äºå ç´ ä¸ä¼è¢«ç§»å¨ã - 对
&mut [T; N]ã&mut [T]æ&mut Vec<T>ç±»åçå¼è¿è¡è¿ä»£ä¼çæ&mut Tç±»åçå ç´ ã
æ°ç»ãåçååé乿.iter()å.iter_mut()æ¹æ³ï¼å¨âiteråiter_mutæ¹æ³âä¸ä»ç»ï¼ï¼ç¨äºå建çæå¯¹å
¶å
ç´ å¼ç¨çè¿ä»£å¨ã
æä»¬å°å¨âSplittingâï¼æåï¼é¨åä»ç»ä¸äºæ´é«çº§çåçè¿ä»£æ¹å¼ã
# åéçå¢é¿åæ¶ç¼©
æ°ç»ãåçæåéçé¿åº¦æ¯å ¶å å«çå ç´ æ°éï¼
slice.len()ï¼è¿ååççé¿åº¦ï¼ç±»å为usizeãslice.is_empty()ï¼å¦æåçä¸å å«ä»»ä½å ç´ ï¼å³slice.len() == 0ï¼ï¼åè¿åtrueã
æ¬èä¸çå ¶ä½æ¹æ³ç¨äºåéçå¢é¿åæ¶ç¼©ãæ°ç»ååç䏿¦å建就ä¸è½è°æ´å¤§å°ï¼å æ¤å®ä»¬æ²¡æè¿äºæ¹æ³ã
åéçææå
ç´ é½åå¨å¨å ä¸åé
çä¸åè¿ç»å
åä¸ãåéç容鿝è¿åå
åè½å®¹çº³çæå¤§å
ç´ æ°éãVecé常ä¼ä¸ºä½ 管ç容éï¼å½éè¦æ´å¤ç©ºé´æ¶ï¼å®ä¼èªå¨åé
ä¸ä¸ªæ´å¤§çç¼å²åºï¼å¹¶å°å
ç´ ç§»å¨å°æ°ç¼å²åºä¸ã乿ä¸äºæ¹æ³å¯ä»¥æ¾å¼ç®¡ç容éï¼
Vec::with_capacity(n)ï¼å建ä¸ä¸ªæ°çã空çåéï¼å ¶å®¹é为nãvec.capacity()ï¼è¿åvecç容éï¼ç±»å为usizeãvec.capacity() >= vec.len()å§ç»æç«ãvec.reserve(n)ï¼ç¡®ä¿åéè³å°æè¶³å¤ç空é²å®¹éæ¥å®¹çº³n个æ´å¤çå ç´ ï¼å³vec.capacity()è³å°ä¸ºvec.len() + nãå¦æå·²ç»æè¶³å¤ç空é´ï¼åæ¤æ¹æ³ä¸æ§è¡ä»»ä½æä½ãå¦æç©ºé´ä¸è¶³ï¼åä¼åé ä¸ä¸ªæ´å¤§çç¼å²åºï¼å¹¶å°åéçå 容移å¨å°å ¶ä¸ãvec.reserve_exact(n)ï¼ä¸vec.reserve(n)类似ï¼ä½åè¯vecé¤äºn个å ç´ æéç空é´å¤ï¼ä¸è¦ä¸ºæªæ¥çå¢é¿åé ä»»ä½é¢å¤ç容éãä¹åï¼vec.capacity()æ°å¥½ä¸ºvec.len() + nãvec.shrink_to_fit()ï¼å¦ævec.capacity()大äºvec.len()ï¼åå°è¯éæ¾å¤ä½çå åã
Vec<T>æè®¸å¤æ·»å æå é¤å
ç´ çæ¹æ³ï¼è¿äºæ¹æ³ä¼æ¹ååéçé¿åº¦ãè¿äºæ¹æ³é½éè¿å¯åå¼ç¨æ¥æ¶selfåæ°ã
以ä¸ä¸¤ä¸ªæ¹æ³å¨åéæ«å°¾æ·»å æå é¤å个å¼ï¼
vec.push(value)ï¼å°ç»å®ç弿·»å å°vecçæ«å°¾ãvec.pop()ï¼å é¤å¹¶è¿åæåä¸ä¸ªå ç´ ãè¿åç±»å为Option<T>ã妿弹åºçå ç´ ä¸ºxï¼åè¿åSome(x)ï¼å¦æåéå·²ç»ä¸ºç©ºï¼åè¿åNoneã
请注æï¼.push()æå¼è䏿¯æå¼ç¨æ¥æ¶åæ°ãåæ ·ï¼.pop()è¿åå¼¹åºçå¼ï¼è䏿¯å¼ç¨ãæ¬èä¸ç大夿°å
¶ä½æ¹æ³ä¹æ¯å¦æ¤ï¼å®ä»¬å°å¼ç§»å
¥åç§»åºåéã
以ä¸ä¸¤ä¸ªæ¹æ³å¯ä»¥å¨åéçä»»æä½ç½®æ·»å æå é¤å¼ï¼
vec.insert(index, value)ï¼å°ç»å®çå¼æå ¥å°vec[index]å¤ï¼å°vec[index..]ä¸çç°æå¼åå³ç§»å¨ä¸ä¸ªä½ç½®ä»¥è ¾åºç©ºé´ã妿index > vec.len()ï¼åä¼å¯¼è´ç¨åºææ ï¼panicï¼ãvec.remove(index)ï¼å é¤å¹¶è¿åvec[index]ï¼å°vec[index + 1..]ä¸çç°æå¼å左移å¨ä¸ä¸ªä½ç½®ä»¥å¡«è¡¥ç©ºç¼ºã妿index >= vec.len()ï¼åä¼å¯¼è´ç¨åºææ ï¼å 为å¨è¿ç§æ åµä¸ä¸åå¨è¦å é¤çvec[index]å ç´ ã
åéè¶é¿ï¼æ¤æä½å°±è¶æ
¢ãå¦æä½ ç»å¸¸ä½¿ç¨vec.remove(0)ï¼å¯ä»¥èè使ç¨VecDequeï¼å¨âVecDeque<T>âä¸ä»ç»ï¼ä»£æ¿Vecã
.insert()å.remove()æä½ä¸éè¦ç§»å¨çå
ç´ è¶å¤ï¼éåº¦å°±è¶æ
¢ã
æåä¸ªæ¹æ³å¯ä»¥å°åéçé¿åº¦æ´æ¹ä¸ºç¹å®å¼ï¼
vec.resize(new_len, value)ï¼å°vecçé¿åº¦è®¾ç½®ä¸ºnew_lenã妿è¿ä¼å¢åvecçé¿åº¦ï¼å伿·»åvalueç坿¬ä»¥å¡«å æ°ç©ºé´ãå ç´ ç±»åå¿ é¡»å®ç°Cloneç¹æ§ãvec.resize_with(new_len, closure)ï¼ä¸vec.resize类似ï¼ä½è°ç¨éå æ¥æé æ¯ä¸ªæ°å ç´ ãå®å¯ç¨äºå ç´ ç±»åæªå®ç°Cloneçåéãvec.truncate(new_len)ï¼å°vecçé¿åº¦åå°å°new_lenï¼ä¸¢å¼vec[new_len..]èå´å çä»»ä½å ç´ ã妿vec.len()å·²ç»å°äºæçäºnew_lenï¼å䏿§è¡ä»»ä½æä½ãvec.clear()ï¼ä»vecä¸å 餿æå ç´ ï¼çåäºvec.truncate(0)ã
æåä¸ªæ¹æ³å¯ä»¥ä¸æ¬¡æ·»å æå é¤å¤ä¸ªå¼ï¼
vec.extend(iterable)ï¼å°ç»å®å¯è¿ä»£å¼ä¸çææé¡¹æé¡ºåºæ·»å å°vecçæ«å°¾ï¼å°±åæ¯å¤å¼çæ¬ç.push()ãå¯è¿ä»£åæ°å¯ä»¥æ¯ä»»ä½å®ç°äºIntoIterator<Item = T>çç±»åãè¿ä¸ªæ¹æ³é常æç¨ï¼ä¸ºæ¤æä¸ä¸ªæ åç¹æ§Extendï¼æææ åéåé½å®ç°äºè¯¥ç¹æ§ãä¸å¹¸çæ¯ï¼è¿ä¼å¯¼è´rustdocå°.extend()ä¸å ¶ä»ç¹æ§æ¹æ³ä¸èµ·å æ¾å¨çæçHTMLåºé¨çä¸å¤§å æ¹æ³ä¸ï¼å æ¤å¨éè¦æ¶å¾é¾æ¾å°å®ãä½ åªéè®°ä½å®çåå¨å³å¯ï¼æ´å¤å 容请åè§ âThe Extend Traitâï¼Extendç¹æ§ï¼ãvec.split_off(index)ï¼ä¸vec.truncate(index)类似ï¼ä½å®è¿åä¸ä¸ªVec<T>ï¼å ¶ä¸å å«ä»vecæ«å°¾å é¤çå¼ï¼å°±åæ¯å¤å¼çæ¬ç.pop()ãvec.append(&mut vec2)ï¼å°vec2ä¸çææå ç´ ç§»å¨å°vecä¸ï¼å ¶ä¸vec2æ¯å¦ä¸ä¸ªVec<T>ç±»åçåéãä¹åï¼vec2为空ãè¿ç±»ä¼¼äºvec.extend(vec2)ï¼ä½vec2卿ä½åä»ç¶åå¨ï¼ä¸å ¶å®¹éä¸åå½±å ãvec.drain(range)ï¼ä»vecä¸å é¤vec[range]èå´çå ç´ ï¼å¹¶è¿åä¸ä¸ªå¯¹å é¤å ç´ çè¿ä»£å¨ï¼å ¶ä¸rangeæ¯ä¸ä¸ªèå´å¼ï¼å¦..æ0..4ã
è¿æä¸äºç¹æ®çæ¹æ³ç¨äºæéæ©å°å é¤åéä¸çæäºå ç´ ï¼
vec.retain(test)ï¼å é¤æææªéè¿ç»å®æµè¯çå ç´ ãteståæ°æ¯ä¸ä¸ªå®ç°äºFnMut(&T) -> boolç彿°æéå ã对äºvecä¸çæ¯ä¸ªå ç´ ï¼é½ä¼è°ç¨test(&element)ï¼å¦æè¿åfalseï¼åä»åéä¸å é¤è¯¥å ç´ å¹¶éæ¾å ¶å åãé¤äºæ§è½æ¹é¢ï¼è¿ç±»ä¼¼äºç¼åï¼vec = vec.into_iter().filter(test).collect();vec.dedup()ï¼å é¤éå¤çå ç´ ï¼ç±»ä¼¼äºUnixç³»ç»ä¸çuniqshellå·¥å ·ã宿«ævecï¼æ¥æ¾ç¸é»å ç´ ç¸ççä½ç½®ï¼å¹¶å é¤å¤ä½çç¸çå¼ï¼åªä¿çä¸ä¸ªï¼
let mut byte_vec = b"Misssssssissippi".to_vec();
byte_vec.dedup();
assert_eq!(&byte_vec, b"Misisipi");
2
3
注æï¼è¾åºä¸ä»ç¶æä¸¤ä¸ªsåç¬¦ãæ¤æ¹æ³ä»
å é¤ç¸é»çéå¤é¡¹ãè¦æ¶é¤ææéå¤é¡¹ï¼æä¸ç§éæ©ï¼å¨è°ç¨.dedup()ä¹å对åéè¿è¡æåºãå°æ°æ®ç§»å¨å°éåä¸ï¼æè
ï¼ä¸ºäºä¿æå
ç´ çåå§é¡ºåºï¼ä½¿ç¨è¿ä¸ª.retain()æå·§ï¼
let mut byte_vec = b"Misssssssissippi".to_vec();
let mut seen = HashSet::new();
byte_vec.retain(|r| seen.insert(*r));
assert_eq!(&byte_vec, b"Misp");
2
3
4
è¿æ¯å 为å½éåå·²ç»å
å«æä»¬è¦æå
¥ç项æ¶ï¼.insert()ä¼è¿åfalseã
vec.dedup_by(same)ï¼ä¸vec.dedup()ç¸åï¼ä½å®ä½¿ç¨å½æ°æéåsame(&mut elem1, &mut elem2)è䏿¯==è¿ç®ç¬¦æ¥æ£æ¥ä¸¤ä¸ªå ç´ æ¯å¦åºè¢«è§ä¸ºç¸çãvec.dedup_by_key(key)ï¼ä¸vec.dedup()ç¸åï¼ä½å¦ækey(&mut elem1) == key(&mut elem2)ï¼åå°ä¸¤ä¸ªå ç´ è§ä¸ºç¸çãä¾å¦ï¼å¦æerrorsæ¯Vec<Box<dyn Error>>ç±»åï¼ä½ å¯ä»¥è¿æ ·åï¼
// å é¤å
·æé夿¶æ¯çé误
errors.dedup_by_key(|err| err.to_string());
2
卿¬èä»ç»çæææ¹æ³ä¸ï¼åªæ.resize()ä¼å
éå¼ãå
¶ä»æ¹æ³é½æ¯éè¿å°å¼ä»ä¸ä¸ªå°æ¹ç§»å¨å°å¦ä¸ä¸ªå°æ¹æ¥å·¥ä½çã
# è¿æ¥
æä¸¤ä¸ªæ¹æ³ç¨äºå¤çæ°ç»çæ°ç»ï¼è¿éçæ°ç»çæ°ç»æçæ¯ä»»ä½å ç´ æ¬èº«æ¯æ°ç»ãåçæåéçæ°ç»ãåçæåéï¼
slices.concat()ï¼è¿åä¸ä¸ªæ°åéï¼è¯¥åéç±è¿æ¥ææåçèå¾ï¼
assert_eq!([[1, 2], [3, 4], [5, 6]].concat(),
vec![1, 2, 3, 4, 5, 6]);
2
slices.join(&separator)ï¼ä¸concat()类似ï¼åªæ¯å¨åçä¹é´æå ¥separatorå¼ç坿¬ï¼
assert_eq!([[1, 2], [3, 4], [5, 6]].join(&0),
vec![1, 2, 0, 3, 4, 0, 5, 6]);
2
# æå
䏿¬¡æ§è·åæ°ç»ãåçæåéçå¤ä¸ªä¸å¯åå¼ç¨å¾å®¹æï¼
let v = vec![0, 1, 2, 3];
let a = &v[i];
let b = &v[j];
let mid = v.len() / 2;
let front_half = &v[..mid];
let back_half = &v[mid..];
2
3
4
5
6
è·åå¤ä¸ªå¯åå¼ç¨å°±æ²¡é£ä¹å®¹æäºï¼
let mut v = vec![0, 1, 2, 3];
let a = &mut v[i];
let b = &mut v[j]; // é误: ä¸è½åæ¶å¤æ¬¡å¯ååç¨`v`
*a = 6; // è¿é使ç¨äºå¼ç¨`a`å`b`
*b = 7; // æä»¥å®ä»¬ççå½å¨æå¿
é¡»éå
2
3
4
5
Rustç¦æ¢è¿æ ·åï¼å ä¸ºå¦æi == jï¼é£ä¹aåbå°æ¯å¯¹åä¸ä¸ªæ´æ°ç两个å¯åå¼ç¨ï¼è¿è¿åäºRustçå®å
¨è§åï¼åè§ âSharing Versus Mutationâï¼å
±äº«ä¸åå¼ï¼ï¼ã
Rustæå ä¸ªæ¹æ³å¯ä»¥ä¸æ¬¡æ§åç¨æ°ç»ãåçæåéä¸ä¸¤ä¸ªææ´å¤é¨åçå¯åå¼ç¨ãä¸åé¢ç代ç ä¸åï¼è¿äºæ¹æ³æ¯å®å ¨çï¼å 为ä»è®¾è®¡ä¸çï¼å®ä»¬æ»æ¯å°æ°æ®æå为ä¸éå çåºåãè¿äºæ¹æ³ä¸çè®¸å¤æ¹æ³å¯¹äºå¤çä¸å¯ååçä¹å¾æ¹ä¾¿ï¼æä»¥æ¯ä¸ªæ¹æ³é½æå¯ååä¸å¯åçæ¬ã
å¾16-2说æäºè¿äºæ¹æ³ã
å¾16-2. æåæ¹æ³ç¤ºä¾ï¼æ³¨æï¼slice.split()è¾åºä¸çå°ç©å½¢æ¯ç±ä¸¤ä¸ªç¸é»åé符导è´ç空åçï¼rsplitnä¸å
¶ä»æ¹æ³ä¸åï¼å®æä»åååç顺åºçæè¾åº)
è¿äºæ¹æ³é½ä¸ä¼ç´æ¥ä¿®æ¹æ°ç»ãåçæåéï¼å®ä»¬åªæ¯è¿å对å 鍿°æ®é¨åçæ°å¼ç¨ï¼
slice.iter()ãslice.iter_mut()ï¼çæå¯¹åç䏿¯ä¸ªå ç´ çå¼ç¨ï¼æä»¬å¨ âIterationâï¼è¿ä»£ï¼ä¸ä»ç»è¿å®ä»¬ãslice.split_at(index)ãslice.split_at_mut(index)ï¼å°åçåæä¸¤é¨åï¼è¿åä¸ä¸ªå ç»ãslice.split_at(index)çåäº(&slice[..index], &slice[index..])ã妿indexè¶ åºèå´ï¼è¿äºæ¹æ³ä¼å¯¼è´ç¨åºææ ï¼panicï¼ãslice.split_first()ãslice.split_first_mut()ï¼ä¹è¿åä¸ä¸ªå ç»ï¼å¯¹ç¬¬ä¸ä¸ªå ç´ ï¼slice[0]ï¼çå¼ç¨åå¯¹å ¶ä½ææå ç´ ï¼slice[1..]ï¼çåçå¼ç¨ã.split_first()çè¿åç±»åæ¯Option<(&T, &[T])>ï¼å¦æåç为空ï¼ç»æä¸ºNoneãslice.split_last()ãslice.split_last_mut()ï¼ä¸split_first()类似ï¼ä½æåçæ¯æåä¸ä¸ªå ç´ è䏿¯ç¬¬ä¸ä¸ªå ç´ ã.split_last()çè¿åç±»åæ¯Option<(&T, &[T])>ãslice.split(is_sep)ãslice.split_mut(is_sep)ï¼ä½¿ç¨å½æ°æéåis_sepæ¥ç¡®å®æåä½ç½®ï¼å°åçæå为ä¸ä¸ªæå¤ä¸ªååçï¼å¹¶è¿åä¸ä¸ªå¯¹ååççè¿ä»£å¨ã卿¶èè¿ä»£å¨æ¶ï¼å®ä¼ä¸ºåçä¸çæ¯ä¸ªå ç´ è°ç¨is_sep(&element)ã妿is_sep(&element)为trueï¼å该å ç´ æ¯åé符ãåé符ä¸ä¼å å«å¨ä»»ä½è¾åºååçä¸ãè¾åºå§ç»è³å°å å«ä¸ä¸ªååçï¼å¹¶ä¸æ¯ä¸ªåé符ä¼é¢å¤äº§çä¸ä¸ªååçãæ¯å½åé符彼æ¤ç¸é»æä¸åçç两端ç¸é»æ¶ï¼é½ä¼å å«ç©ºååçãslice.rsplit(is_sep)ãslice.rsplit_mut(is_sep)ï¼ä¸slice.splitåslice.split_mut类似ï¼ä½ä»åççæ«å°¾å¼å§ãslice.splitn(n, is_sep)ãslice.splitn_mut(n, is_sep)ï¼ä¸slice.split类似ï¼ä½æå¤çæn个ååçã卿¾å°ån - 1个ååçåï¼ä¸åè°ç¨is_sepãæåä¸ä¸ªååçå 嫿æå©ä½å ç´ ãslice.rsplitn(n, is_sep)ãslice.rsplitn_mut(n, is_sep)ï¼ä¸.splitn()å.splitn_mut()类似ï¼åªæ¯æç¸åçé¡ºåºæ«æåçãä¹å°±æ¯è¯´ï¼è¿äºæ¹æ³å¨åççæån - 1个åé符å¤è¿è¡æåï¼è䏿¯å¨ç¬¬ä¸ä¸ªåé符å¤ï¼å¹¶ä¸ååç仿«å°¾å¼å§çæãslice.chunks(n)ãslice.chunks_mut(n)ï¼è¿åä¸ä¸ªå¯¹é¿åº¦ä¸ºnçä¸éå ååççè¿ä»£å¨ã妿nä¸è½æ´é¤slice.len()ï¼åæåä¸ä¸ªåå å«çå ç´ å°å°äºn个ãslice.rchunks(n)ãslice.rchunks_mut(n)ï¼ä¸slice.chunksåslice.chunks_mut类似ï¼ä½ä»åççæ«å°¾å¼å§ãslice.chunks_exact(n)ãslice.chunks_exact_mut(n)ï¼è¿åä¸ä¸ªå¯¹é¿åº¦ä¸ºnçä¸éå ååççè¿ä»£å¨ã妿nä¸è½æ´é¤slice.len()ï¼åæåä¸ä¸ªåï¼å å«å°äºn个å ç´ ï¼å¯éè¿ç»æçremainder()æ¹æ³è·åãslice.rchunks_exact(n)ãslice.rchunks_exact_mut(n)ï¼ä¸slice.chunks_exactåslice.chunks_exact_mut类似ï¼ä½ä»åççæ«å°¾å¼å§ã
è¿æä¸ä¸ªç¨äºè¿ä»£ååççæ¹æ³ï¼
slice.windows(n)ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼å ¶è¡ä¸ºå°±åå¨åçæ°æ®ä¸ç âæ»å¨çªå£âãå®çæè·¨è¶åçä¸n个è¿ç»å ç´ çååçãçæç第ä¸ä¸ªå¼æ¯&slice[0..n]ï¼ç¬¬äºä¸ªå¼æ¯&slice[1..n + 1]ï¼ä¾æ¤ç±»æ¨ã妿n大äºåççé¿åº¦ï¼åä¸ä¼çæä»»ä½åçã妿n为0ï¼åè¯¥æ¹æ³ä¼å¯¼è´ç¨åºææ ï¼panicï¼ãä¾å¦ï¼å¦ædays.len() == 31ï¼é£ä¹æä»¬å¯ä»¥éè¿è°ç¨days.windows(7)çædays䏿æä¸ºæä¸å¤©çæ¶é´æ®µã大å°ä¸º2çæ»å¨çªå£å¯¹äºæ¢ç´¢æ°æ®ç³»åä»ä¸ä¸ªæ°æ®ç¹å°ä¸ä¸ä¸ªæ°æ®ç¹çåå徿ç¨ï¼
let changes = daily_high_temperatures
.windows(2) // è·åç¸é»ä¸¤å¤©ç温度
.map(|w| w[1] - w[0]) // 温度ååäºå¤å°ï¼
.collect::<Vec<_>>();
2
3
4
ç±äºååçæ¯éå çï¼å æ¤è¯¥æ¹æ³æ²¡æè¿åå¯åå¼ç¨ççæ¬ã
# 交æ¢
æä¸äºæ¹ä¾¿çæ¹æ³ç¨äºäº¤æ¢åççå 容ï¼
slice.swap(i, j)ï¼äº¤æ¢åçä¸slice[i]åslice[j]è¿ä¸¤ä¸ªå ç´ ãslice_a.swap(&mut slice_b)ï¼äº¤æ¢slice_aåslice_bçå ¨é¨å 容ãslice_aåslice_bçé¿åº¦å¿ é¡»ç¸åã
åéæä¸ä¸ªç¸å ³çæ¹æ³ï¼å¯é«æå é¤ä»»æå ç´ ï¼
vec.swap_remove(i)ï¼å é¤å¹¶è¿åvec[i]ãè¿ä¸vec.remove(i)类似ï¼ä½å®ä¸æ¯å°åéçå ¶ä½å ç´ ç§»å¨æ¥å¡«è¡¥ç©ºç¼ºï¼èæ¯ç´æ¥å°åéçæåä¸ä¸ªå ç´ ç§»å¨å°ç©ºç¼ºå¤ãå½ä½ ä¸å ³å¿çå¨åéä¸çå ç´ é¡ºåºæ¶ï¼è¿ä¸ªæ¹æ³å¾æç¨ã
# æåºåæç´¢
åçæä¾äºä¸ç§æåºæ¹æ³ï¼
slice.sort()ï¼å°å ç´ æååºæåºãåªæå½å ç´ ç±»åå®ç°äºOrdæ¶ï¼è¿ä¸ªæ¹æ³æå¯ç¨ãslice.sort_by(cmp)ï¼ä½¿ç¨å½æ°æéåcmpæ¥æå®æåºé¡ºåºï¼å¯¹åçä¸çå ç´ è¿è¡æåºãcmpå¿ é¡»å®ç°Fn(&T, &T) -> std::cmp::Orderingãé¤éå§æç».cmp()æ¹æ³ï¼å¦åæå¨å®ç°cmpå¾éº»ç¦ï¼
students.sort_by(|a, b| a.last_name.cmp(&b.last_name));
è¦æä¸ä¸ªå段æåºï¼å¹¶ä½¿ç¨ç¬¬äºä¸ªå段ä½ä¸ºå¹³å±å³èæ¡ä»¶ï¼å¯ä»¥æ¯è¾å ç»ï¼
students.sort_by(|a, b| {
let a_key = (&a.last_name, &a.first_name);
let b_key = (&b.last_name, &b.first_name);
a_key.cmp(&b_key)
});
2
3
4
5
slice.sort_by_key(key)ï¼æ ¹æ®å½æ°æéåkeyç»åºçæåºé®ï¼å°åçä¸çå ç´ æååºæåºãkeyçç±»åå¿ é¡»å®ç°Fn(&T) -> Kï¼å ¶ä¸K: Ordãå½Tå å«ä¸ä¸ªæå¤ä¸ªæåºå段ï¼ä»èå¯ä»¥ç¨å¤ç§æ¹å¼æåºæ¶ï¼è¿ä¸ªæ¹æ³å¾æç¨ï¼
// æå¹³åç»©ç¹æåºï¼ä»ä½å°é«
students.sort_by_key(|s| s.grade_point_average());
2
注æï¼å¨æåºè¿ç¨ä¸ä¸ä¼ç¼åè¿äºæåºé®å¼ï¼å æ¤é®å½æ°å¯è½ä¼è¢«è°ç¨è¶
è¿n次ãç±äºææ¯åå ï¼key(element)ä¸è½è¿åä»å
ç´ ä¸åç¨çä»»ä½å¼ç¨ãä¸é¢è¿æ ·åæ¯ä¸è¡çï¼
students.sort_by_key(|s| &s.last_name); // é误: æ æ³æ¨æçå½å¨æ
Rustæ æ³ç¡®å®çå½å¨æãä½å¨è¿ç§æ
åµä¸ï¼ä½¿ç¨.sort_by()就足å¤ç®åäºã
è¿ä¸ç§æ¹æ³é½æ§è¡ç¨³å®æåºã
è¦æéåºæåºï¼ä½ å¯ä»¥ä½¿ç¨sort_byåä¸ä¸ªäº¤æ¢ä¸¤ä¸ªåæ°çcmpéå
ã使ç¨|b, a|è䏿¯|a, b|å®é
ä¸ä¼äº§çç¸åç顺åºãæè
ï¼ä½ ä¹å¯ä»¥å¨æåºåç´æ¥è°ç¨.reverse()æ¹æ³ï¼
slice.reverse()ï¼å°±å°å转åçã
䏿¦åç被æåºï¼å°±å¯ä»¥é«æå°è¿è¡æç´¢ï¼
slice.binary_search(&value)slice.binary_search_by(&value, cmp)slice.binary_search_by_key(&value, key)
è¿äºæ¹æ³é½å¨ç»å®çå·²æåºåçä¸æç´¢valueãæ³¨æï¼valueæ¯éè¿å¼ç¨ä¼ éçãè¿äºæ¹æ³çè¿åç±»åæ¯Result<usize, usize>ã妿卿å®çæåºé¡ºåºä¸ï¼slice[index]çäºvalueï¼å®ä»¬å°±è¿åOk(index)ã妿ä¸åå¨è¿æ ·çindexï¼åè¿åErr(insertion_point)ï¼å¨insertion_point夿å
¥valueå¯ä»¥ä¿æé¡ºåºã
å½ç¶ï¼äºåæ¥æ¾åªæå¨åçå®é 䏿æå®é¡ºåºæåºæ¶æææãå¦åï¼ç»ææ¯ä»»æçââè¾å ¥é误ï¼è¾åºä¹é误ã
ç±äºf32åf64æNaNå¼ï¼å®ä»¬æ²¡æå®ç°Ordï¼ä¸è½ç´æ¥ä½ä¸ºæåºåäºåæ¥æ¾æ¹æ³çé®ãè¦å¨æµ®ç¹æ°æ®ä¸ä½¿ç¨ç±»ä¼¼çæ¹æ³ï¼å¯ä»¥ä½¿ç¨ord_subsetåºã
æä¸ä¸ªæ¹æ³å¯ä»¥å¨æªæåºçåéä¸è¿è¡æç´¢ï¼
slice.contains(&value)ï¼å¦æåçä¸çä»»ä½å ç´ çäºvalueï¼åè¿åtrueãè¿ä¸ªæ¹æ³åªæ¯éä¸ªæ£æ¥åçä¸çå ç´ ï¼ç´å°æ¾å°å¹é 项ãåæ ·ï¼valueæ¯éè¿å¼ç¨ä¼ éçã
è¦å¨åç䏿¥æ¾å¼çä½ç½®ï¼å°±åJavaScriptä¸çarray.indexOf(value)䏿 ·ï¼å¯ä»¥ä½¿ç¨è¿ä»£å¨ï¼
slice.iter().position(|x| *x == value)
è¿å°è¿åä¸ä¸ªOption<usize>ã
# æ¯è¾åç
å¦æç±»åTæ¯æ==å!=è¿ç®ç¬¦ï¼PartialEqç¹æ§ï¼å¨âçä»·æ¯è¾âä¸æè¿°ï¼ï¼é£ä¹æ°ç»[T; N]ãåç[T]ååéVec<T>乿¯æãå¦æä¸¤ä¸ªåçé¿åº¦ç¸åä¸å¯¹åºå
ç´ ç¸çï¼åå®ä»¬ç¸çãæ°ç»ååé乿¯å¦æ¤ã
妿Tæ¯æ<ã<=ã>å>=è¿ç®ç¬¦ï¼PartialOrdç¹æ§ï¼å¨âæåºæ¯è¾âä¸æè¿°ï¼ï¼é£ä¹Tç±»åçæ°ç»ãåçååé乿¯æãåçæ¯è¾æ¯æåå
¸é¡ºåºè¿è¡çã
æä¸¤ä¸ªä¾¿æ·æ¹æ³ç¨äºæ§è¡å¸¸è§çåçæ¯è¾ï¼
slice.starts_with(other)ï¼å¦æåç以otheråçä¸çå ç´ åºåå¼å¤´ï¼åè¿åtrueï¼
assert_eq!([1, 2, 3, 4].starts_with(&[1, 2]), true);
assert_eq!([1, 2, 3, 4].starts_with(&[2, 3]), false);
2
slice.ends_with(other)ï¼ä¸starts_with类似ï¼ä½æ£æ¥åççæ«å°¾ï¼
assert_eq!([1, 2, 3, 4].ends_with(&[3, 4]), true);
# éæºå ç´
Rustæ ååºä¸æ²¡æå
ç½®éæºæ°åè½ãæä¾éæºæ°åè½çrandåºï¼ä¸ºä»æ°ç»ãåçæåéä¸è·åéæºè¾åºæä¾äºä»¥ä¸ä¸¤ä¸ªæ¹æ³ï¼
slice.choose(&mut rng)ï¼è¿å对åçä¸éæºå ç´ çå¼ç¨ãä¸slice.first()åslice.last()类似ï¼å®è¿åä¸ä¸ªOption<&T>ï¼åªæå½åçä¸ºç©ºæ¶æè¿åNoneãslice.shuffle(&mut rng)ï¼å°±å°éæºéæ°æååçä¸çå ç´ ãåçå¿ é¡»éè¿å¯åå¼ç¨ä¼ éã
è¿äºæ¯rand::Rngç¹æ§çæ¹æ³ï¼æä»¥ä½ éè¦ä¸ä¸ªéæºæ°çæå¨Rngæè½è°ç¨å®ä»¬ã幸è¿çæ¯ï¼éè¿è°ç¨rand::thread_rng()å¾å®¹æè·å¾ä¸ä¸ªãè¦æä¹±åémy_vecï¼æä»¬å¯ä»¥è¿æ ·åï¼
use rand::seq::SliceRandom;
use rand::thread_rng;
my_vec.shuffle(&mut thread_rng());
2
3
4
# Rust æç»å¤±æé误
大夿°ä¸»æµç¼ç¨è¯è¨é½æéååè¿ä»£å¨ï¼å¹¶ä¸å®ä»¬é½æç±»ä¼¼çè§åï¼å¨è¿ä»£éåæ¶ï¼ä¸è¦ä¿®æ¹å®ãä¾å¦ï¼Pythonä¸ä¸åéçä»·çæ¯å表ï¼
my_list = [1, 3, 5, 7, 9]
å设æä»¬è¯å¾ä»my_listä¸å 餿æå¤§äº4çå¼ï¼
for index, val in enumerate(my_list):
if val > 4:
del my_list[index] # é误: å¨è¿ä»£æ¶ä¿®æ¹å表
print(my_list)
2
3
4
ï¼enumerate彿°ç¸å½äºRustä¸ç.enumerate()æ¹æ³ï¼å¨âenumerateâä¸æè¿°ãï¼
令人æè®¶çæ¯ï¼è¿ä¸ªç¨åºè¾åº[1, 3, 7]ãä½7大äº4ï¼å®æ¯æä¹æ¼ç½çå¢ï¼è¿æ¯ä¸ä¸ªå¤±æé误ï¼ç¨åºå¨è¿ä»£æ°æ®æ¶ä¿®æ¹äºæ°æ®ï¼ä½¿è¿ä»£å¨å¤±æãå¨Javaä¸ï¼ç»æä¼æ¯æåºä¸ä¸ªå¼å¸¸ï¼å¨C++ä¸ï¼è¿æ¯æªå®ä¹è¡ä¸ºãå¨Pythonä¸ï¼è½ç¶è¡ä¸ºæ¯å®ä¹æç¡®çï¼ä½ä¸ç¬¦åç´è§ï¼è¿ä»£å¨è·³è¿äºä¸ä¸ªå
ç´ ãvalæ°¸è¿ä¸ä¼æ¯7ã
让æä»¬å¨Rustä¸å°è¯éç°è¿ä¸ªé误ï¼
fn main() {
let mut my_vec = vec![1, 3, 5, 7, 9];
for (index, &val) in my_vec.iter().enumerate() {
if val > 4 {
my_vec.remove(index); // é误: ä¸è½å¯ååç¨`my_vec`
}
}
println!("{:?}", my_vec);
}
2
3
4
5
6
7
8
9
èªç¶å°ï¼Rustå¨ç¼è¯æ¶å°±ä¼æç»è¿ä¸ªç¨åºã彿们è°ç¨my_vec.iter()æ¶ï¼å®åç¨äºåéçä¸ä¸ªå
±äº«ï¼ä¸å¯åï¼å¼ç¨ãè¿ä¸ªå¼ç¨ççå½å¨æåè¿ä»£å¨ä¸æ ·é¿ï¼ç´å°for循ç¯ç»æãå¨åå¨ä¸å¯åå¼ç¨çæ
åµä¸ï¼æä»¬ä¸è½éè¿è°ç¨my_vec.remove(index)æ¥ä¿®æ¹åéã
è½æåºé误åºç¶å¾å¥½ï¼ä½å½ç¶ï¼ä½ ä»ç¶éè¦æ¾å°ä¸ç§æ¹æ³æ¥å®ç°ææçè¡ä¸ºï¼è¿éæç®åçè§£å³æ¹æ³æ¯è¿æ ·åï¼
my_vec.retain(|&val| val <= 4);
æè ï¼ä½ å¯ä»¥åå¨Pythonæå ¶ä»ä»»ä½è¯è¨ä¸é£æ ·åï¼ä½¿ç¨è¿æ»¤å¨å建ä¸ä¸ªæ°åéã
# VecDeque<T>
Vecä»
æ¯æå¨æ«å°¾é«æå°æ·»å åå é¤å
ç´ ãå½ç¨åºéè¦ä¸ä¸ªå°æ¹æ¥åå¨ âæéçå¾
â ç弿¶ï¼Vecå¯è½ä¼å¾æ
¢ã
Rustçstd::collections::VecDeque<T>æ¯ä¸ä¸ªå端éåï¼åé³ä¸º âdeckâï¼ã宿¯æå¨å端ååç«¯é«æå°è¿è¡æ·»å åå 餿ä½ï¼
deque.push_front(value)ï¼å¨éåå端添å ä¸ä¸ªå¼ãdeque.push_back(value)ï¼å¨éåæ«å°¾æ·»å ä¸ä¸ªå¼ãï¼è¿ä¸ªæ¹æ³æ¯.push_front()使ç¨å¾æ´å¤ï¼å 为éåçéå¸¸çº¦å®æ¯å¨æ«å°¾æ·»å å¼ï¼å¨å端å é¤å¼ï¼å°±å人们æé䏿 ·ãï¼deque.pop_front()ï¼å é¤å¹¶è¿åéåçå端å¼ï¼è¿åä¸ä¸ªOption<T>ï¼å¦æéå为空åè¿åNoneï¼åvec.pop()类似ãdeque.pop_back()ï¼å é¤å¹¶è¿åé快尾çå¼ï¼åæ ·è¿åä¸ä¸ªOption<T>ãdeque.front()ãdeque.back()ï¼åvec.first()ãvec.last()çåè½ç±»ä¼¼ãå®ä»¬è¿å对éåå端æå端å ç´ çå¼ç¨ãè¿å弿¯Option<&T>ï¼å¦æéå为空åè¿åNoneãdeque.front_mut()ãdeque.back_mut()ï¼åvec.first_mut()ãvec.last_mut()çåè½ç±»ä¼¼ï¼è¿åOption<&mut T>ã
VecDequeçå®ç°æ¯ä¸ä¸ªç¯å½¢ç¼å²åºï¼å¦å¾16-3æç¤ºã
åVec䏿 ·ï¼å®å¨å 䏿ä¸ä¸ªåç¬çåé
ç©ºé´æ¥åå¨å
ç´ ãä¸Vecä¸åçæ¯ï¼æ°æ®å¹¶ä¸æ»æ¯ä»è¿ä¸ªåºåçå¼å¤´å¼å§ï¼å¹¶ä¸å®å¯ä»¥å¦å¾æç¤ºé£æ · âç¯ç»â å°æ«å°¾ãè¿ä¸ªå端éåä¸çå
ç´ ä¾æ¬¡æ¯['A', 'B', 'C', 'D', 'E']ãVecDequeæä¸äºç§æå段ï¼å¨å¾ä¸æ 记为startåstopï¼ç¨äºè®°å½æ°æ®å¨ç¼å²åºä¸çèµ·å§åç»æä½ç½®ã
å¨éåçä»»ä¸ç«¯æ·»å ä¸ä¸ªå¼ï¼æå³çå ç¨ä¸ä¸ªæªä½¿ç¨çæ§½ä½ï¼å¾ä¸ç¨è¾æ·±çå表示ï¼ï¼å¦æéè¦ï¼è¿ä¼ç¯ç»æåé æ´å¤§çå ååã
VecDequeä¼ç®¡çç¯ç»æä½ï¼æä»¥ä½ ä¸å¿
èèè¿äºãå¾16-3å±ç¤ºäºRustå¦ä½å®ç°å¿«éç.pop_front()æä½çå
é¨åçã
å¾16-3. VecDequeå¨å
åä¸çå卿¹å¼
é常ï¼å½ä½ éè¦ä¸ä¸ªå端éåæ¶ï¼.push_back()å.pop_front()æ¯ä½ å¯ä¸éè¦çä¸¤ä¸ªæ¹æ³ãç¨äºå建éåçç±»åå
³è彿°VecDeque::new()åVecDeque::with_capacity(n)ï¼ä¸Vecä¸ç对åºå½æ°ç±»ä¼¼ãVecçè®¸å¤æ¹æ³ä¹å¨VecDequeä¸å®ç°äºï¼æ¯å¦.len()ã.is_empty()ã.insert(index, value)ã.remove(index)ã.extend(iterable)ççã
ååé䏿 ·ï¼å端éåå¯ä»¥æå¼ãæå
±äº«å¼ç¨ææå¯åå¼ç¨è¿è¡è¿ä»£ãå®ä»¬æ.into_iter()ã.iter()å.iter_mut()è¿ä¸ä¸ªè¿ä»£å¨æ¹æ³ãå®ä»¬ä¹å¯ä»¥å平叏䏿 ·è¿è¡ç´¢å¼ï¼deque[index]ã
ç±äºå端éåä¸ä¼å¨å
åä¸è¿ç»åå¨å
ç´ ï¼æä»¥å®ä»¬ä¸è½ç»§æ¿åççæææ¹æ³ã使¯ï¼å¦æä½ æ¿æä»åºç§»å¨å
容ç代价ï¼VecDequeæä¾äºä¸ä¸ªæ¹æ³æ¥è§£å³è¿ä¸ªé®é¢ï¼
deque.make_contiguous()ï¼æ¥å&mut selfï¼å°VecDequeéæ°æåå°è¿ç»å åä¸ï¼å¹¶è¿å&mut [T]ã
VecåVecDequeå¯åç¸å
³ï¼æ ååºæä¾äºä¸¤ä¸ªç¹æ§å®ç°ï¼æ¹ä¾¿å¨ä¸¤è
ä¹é´è¿è¡è½¬æ¢ï¼
Vec::from(deque)ï¼Vec<T>å®ç°äºFrom<VecDeque<T>>ï¼æä»¥è¿ä¼å°ä¸ä¸ªå端éå转æ¢ä¸ºåéãè¿éè¦$O(n)$çæ¶é´ï¼å 为å¯è½éè¦éæ°æåå ç´ ãVecDeque::from(vec)ï¼VecDeque<T>å®ç°äºFrom<Vec<T>>ï¼æä»¥è¿ä¼å°ä¸ä¸ªåé转æ¢ä¸ºå端éåãè¿ä¹æ¯$O(n)$çæ¶é´ï¼ä½é常å¾å¿«ï¼å³ä½¿åéå¾å¤§ï¼å 为åéå¨å ä¸çåé 空é´å¯ä»¥ç´æ¥ç§»å¨å°æ°çå端éåä¸ã
è¿ä¸ªæ¹æ³ä½¿å¾å建ä¸ä¸ªå
嫿å®å
ç´ çå端éååå¾å¾å®¹æï¼å°½ç®¡æ²¡ææ åçvec_deque![]å®ï¼
use std::collections::VecDeque;
let v = VecDeque::from(vec![1, 2, 3, 4]);
2
3
# BinaryHeap<T>
BinaryHeapæ¯ä¸ç§éåï¼å
¶å
ç´ ä¿ææ¾æ£çç»ç»æ¹å¼ï¼ä½¿å¾æå¤§ç弿»æ¯ä¼ âåæ³¡â å°éåçå端ã以䏿¯BinaryHeapæå¸¸ç¨çä¸ä¸ªæ¹æ³ï¼
heap.push(value)ï¼åå 䏿·»å ä¸ä¸ªå¼ãheap.pop()ï¼ä»å ä¸å é¤å¹¶è¿åæå¤§çå¼ãå®è¿åä¸ä¸ªOption<T>ï¼å¦æå 为空åè¿åNoneãheap.peek()ï¼è¿å对å 䏿大çå¼çå¼ç¨ãè¿åç±»åæ¯Option<&T>ãheap.peek_mut()ï¼è¿åä¸ä¸ªPeekMut<T>ï¼å®ç¸å½äºå¯¹å 䏿大çå¼çå¯åå¼ç¨ï¼å¹¶æä¾ç±»åå ³è彿°pop()ï¼ç¨äºä»å ä¸å¼¹åºè¿ä¸ªå¼ã使ç¨è¿ä¸ªæ¹æ³ï¼æä»¬å¯ä»¥æ ¹æ®æå¤§å¼æ¥éæ©æ¯å¦ä»å ä¸å¼¹åºå¼ï¼
use std::collections::binary_heap::PeekMut;
if let Some(top) = heap.peek_mut() {
if *top > 10 {
PeekMut::pop(top);
}
}
2
3
4
5
6
7
BinaryHeapè¿æ¯æVecçé¨åæ¹æ³ï¼å
æ¬BinaryHeap::new()ã.len()ã.is_empty()ã.capacity()ã.clear()å.append(&mut heap2)ã
ä¾å¦ï¼å设æä»¬ç¨ä¸äºæ°åå¡«å
ä¸ä¸ªBinaryHeapï¼
use std::collections::BinaryHeap;
let mut heap = BinaryHeap::from(vec![2, 3, 8, 6, 9, 5, 4]);
2
3
å¼9ä½äºå çé¡¶é¨ï¼
assert_eq!(heap.peek(), Some(&9));
assert_eq!(heap.pop(), Some(9));
2
å é¤å¼9ä¹ä¼å¯¹å ¶ä»å ç´ è¿è¡è½»å¾®çéæ°æåï¼ä½¿å¾8ç°å¨ä½äºå端ï¼ä¾æ¤ç±»æ¨ï¼
assert_eq!(heap.pop(), Some(8));
assert_eq!(heap.pop(), Some(6));
assert_eq!(heap.pop(), Some(5));
...
2
3
4
å½ç¶ï¼BinaryHeapå¹¶ä¸å±éäºæ°åãå®å¯ä»¥åå¨ä»»ä½å®ç°äºå
ç½®Ordç¹æ§çç±»åçå¼ãè¿ä½¿å¾BinaryHeapä½ä¸ºå·¥ä½éå徿ç¨ãä½ å¯ä»¥å®ä¹ä¸ä¸ªtaskç»æä½ï¼æ ¹æ®ä¼å
级å®ç°Ordï¼ä»¥ä¾¿é«ä¼å
级çä»»å¡å¤§äºä½ä¼å
级çä»»å¡ãç¶åï¼å建ä¸ä¸ªBinaryHeapæ¥å卿æå¾
å¤ççä»»å¡ãå®ç.pop()æ¹æ³å°å§ç»è¿åæéè¦ç项ç®ï¼å³ä½ çç¨åºæ¥ä¸æ¥åºè¯¥å¤ççä»»å¡ã
注æï¼BinaryHeapæ¯å¯è¿ä»£çï¼å¹¶ä¸æä¸ä¸ª.iter()æ¹æ³ï¼ä½è¿ä»£å¨ä»¥ä»»æé¡ºåºçæå ä¸çå
ç´ ï¼è䏿¯ä»å¤§å°å°ãè¦æä¼å
çº§é¡ºåºæ¶è´¹BinaryHeapä¸çå¼ï¼å¯ä»¥ä½¿ç¨while循ç¯ï¼
while let Some(task) = heap.pop() {
handle(task);
}
2
3
# HashMap<K, V> å BTreeMap<K, V>
æ å°ï¼mapï¼æ¯é®å¼å¯¹ï¼ç§°ä¸ºæ¡ç®ï¼çéåãæ²¡æä¸¤ä¸ªæ¡ç®å ·æç¸åçé®ï¼å¹¶ä¸æ¡ç®è¢«ç»ç»èµ·æ¥ï¼è¿æ ·å¦æä½ æä¸ä¸ªé®ï¼å°±å¯ä»¥å¨æ å°ä¸é«æå°æ¥æ¾ç¸åºçå¼ãç®èè¨ä¹ï¼æ å°å°±æ¯ä¸ä¸ªæ¥æ¾è¡¨ã
Rustæä¾äºä¸¤ç§æ å°ç±»åï¼HashMap<K, V>åBTreeMap<K, V>ãè¿ä¸¤ç§ç±»åæå¾å¤ç¸åçæ¹æ³ï¼å®ä»¬çåºå«å¨äºå¦ä½ç»ç»æ¡ç®ä»¥å®ç°å¿«éæ¥æ¾ã
HashMapå°é®åå¼åå¨å¨åå¸è¡¨ä¸ï¼å æ¤å®è¦æ±é®ç±»åKå®ç°HashåEqï¼è¿æ¯ç¨äºåå¸åç¸çæ¯è¾çæ åç¹æ§ã
å¾16-4å±ç¤ºäºHashMapå¨å
åä¸çå¸å±ãè¾æ·±çåºåæ¯æªä½¿ç¨çãææçé®ãå¼åç¼åçåå¸ç é½åå¨å¨ä¸ä¸ªå åé
ç表ä¸ãæ·»å æ¡ç®æç»ä¼è¿«ä½¿HashMapåé
ä¸ä¸ªæ´å¤§ç表ï¼å¹¶å°æææ°æ®ç§»å¨å°æ°è¡¨ä¸ã

å¾16-4. å åä¸çHashMap
BTreeMapæé®ç顺åºå°æ¡ç®åå¨å¨æ ç»æä¸ï¼å æ¤å®è¦æ±é®ç±»åKå®ç°Ordãå¾16-5å±ç¤ºäºä¸ä¸ªBTreeMapãåæ ·ï¼è¾æ·±çåºåæ¯æªä½¿ç¨ç空é²å®¹éã
å¾16-5. å
åä¸çBTreeMap
BTreeMapå°å
¶æ¡ç®åå¨å¨èç¹ä¸ãBTreeMapä¸ç大夿°èç¹åªå
å«é®å¼å¯¹ãéå¶èç¹ï¼å¦å¾ä¸æç¤ºçæ ¹èç¹ï¼ä¹æç©ºé´å卿ååèç¹çæéãå¨(20, 'q')å(30, 'r')ä¹é´çæéæåä¸ä¸ªå
å«20å°30ä¹é´é®çåèç¹ã
æ·»å æ¡ç®é常éè¦å°æä¸ªèç¹çç°ææ¡ç®åå³ç§»å¨ï¼ä»¥ä¿æå®ä»¬çæåºï¼å¶å°è¿éè¦åé æ°çèç¹ã
为äºå¨é¡µé¢ä¸å±ç¤ºï¼è¿ä¸ªå¾åäºä¸äºç®åãä¾å¦ï¼å®é
çBTreeMapèç¹æç©ºé´åå¨11个æ¡ç®ï¼è䏿¯4个ã
Rustæ ååºä½¿ç¨Bæ è䏿¯å¹³è¡¡äºåæ ï¼å 为å¨ç°ä»£ç¡¬ä»¶ä¸Bæ é度æ´å¿«ãäºåæ æ¯æ¬¡æç´¢å¯è½æ¯Bæ ä½¿ç¨æ´å°çæ¯è¾æ¬¡æ°ï¼ä½æç´¢Bæ å ·ææ´å¥½çå±é¨æ§ï¼ä¹å°±æ¯è¯´ï¼å åè®¿é®æ¯éä¸å¨ä¸èµ·çï¼è䏿¯åæ£å¨æ´ä¸ªå ä¸ãè¿ä½¿å¾CPUç¼åæªå½ä¸çæ 嵿´å°è§ï¼ä»èæ¾èæé«äºé度ã
æå ç§å建æ å°çæ¹æ³ï¼
HashMap::new()ãBTreeMap::new()ï¼å建æ°ç空æ å°ãiter.collect()ï¼å¯ç¨äºä»é®å¼å¯¹åå»ºå¹¶å¡«å æ°çHashMapæBTreeMapãiterå¿ é¡»æ¯Iterator<Item=(K, V)>ç±»åãHashMap::with_capacity(n)ï¼å建ä¸ä¸ªæ°ç空å叿 å°ï¼è³å°æå®¹çº³n个æ¡ç®ç空é´ãä¸åé类似ï¼HashMapå°æ°æ®åå¨å¨å个å åé ä¸ï¼å æ¤å®ä»¬æå®¹é以åç¸å ³çæ¹æ³hash_map.capacity()ãhash_map.reserve(additional)åhash_map.shrink_to_fit()ãBTreeMap没æè¿äºã
HashMapåBTreeMapæç¸åçæ ¸å¿æ¹æ³æ¥å¤çé®åå¼ï¼
map.len()ï¼è¿åæ¡ç®çæ°éãmap.is_empty()ï¼å¦ææ å°æ²¡ææ¡ç®ï¼åè¿åtrueãmap.contains_key(&key)ï¼å¦ææ å°ä¸æç»å®é®çæ¡ç®ï¼åè¿åtrueãmap.get(&key)ï¼å¨æ å°ä¸æç´¢å ·æç»å®é®çæ¡ç®ã妿æ¾å°å¹é çæ¡ç®ï¼åè¿åSome(r)ï¼å ¶ä¸ræ¯å¯¹ç¸åºå¼çå¼ç¨ãå¦åï¼è¿åNoneãmap.get_mut(&key)ï¼ä¸map.get(&key)类似ï¼ä½è¿å对å¼çå¯åå¼ç¨ã
ä¸è¬æ¥è¯´ï¼æ å°å è®¸ä½ å¯¹åå¨å¨å ¶ä¸çå¼è¿è¡å¯å访é®ï¼ä½ä¸è½å¯¹é®è¿è¡å¯å访é®ãä½ å¯ä»¥éæä¿®æ¹å¼ãé®å±äºæ å°æ¬èº«ï¼æ å°éè¦ç¡®ä¿é®ä¸ä¼æ¹åï¼å 为æ¡ç®æ¯æ ¹æ®é®æ¥ç»ç»çãå°±å°ä¿®æ¹é®æ¯ä¸ä¸ªé误ã
map.insert(key, value)ï¼å°æ¡ç®(key, value)æå ¥å°æ å°ä¸ï¼å¹¶è¿åæ§å¼ï¼å¦ææçè¯ï¼ãè¿åç±»åæ¯Option<V>ã妿æ å°ä¸å·²ç»ækeyçæ¡ç®ï¼æ°æå ¥çå¼å°è¦çæ§å¼ãmap.extend(iterable)ï¼éåiterableä¸ç(K, V)项ï¼å¹¶å°æ¯ä¸ªé®å¼å¯¹æå ¥å°æ å°ä¸ãmap.append(&mut map2)ï¼å°map2ä¸çæææ¡ç®ç§»å¨å°mapä¸ãä¹åï¼map2为空ãmap.remove(&key)ï¼å¨æ å°ä¸æ¥æ¾å¹¶å é¤å ·æç»å®é®ç任使¡ç®ï¼å¦ææ¾å°åè¿åå é¤çå¼ãè¿åç±»åæ¯Option<V>ãmap.remove_entry(&key)ï¼å¨æ å°ä¸æ¥æ¾å¹¶å é¤å ·æç»å®é®ç任使¡ç®ï¼å¦ææ¾å°åè¿åå é¤çé®åå¼ãè¿åç±»åæ¯Option<(K, V)>ãmap.retain(test)ï¼å é¤æææªéè¿ç»å®æµè¯çå ç´ ãteståæ°æ¯ä¸ä¸ªå®ç°äºFnMut(&K, &mut V) -> boolç彿°æéå ãå¯¹äºæ å°ä¸çæ¯ä¸ªå ç´ ï¼é½ä¼è°ç¨test(&key, &mut value)ï¼å¦æè¿åfalseï¼å仿 å°ä¸å é¤è¯¥å ç´ å¹¶éæ¾å ¶å åãé¤äºæ§è½æ¹é¢ï¼è¿ç±»ä¼¼äºç¼åï¼map = map.into_iter().filter(test).collect();map.clear()ï¼å é¤æææ¡ç®ã
æ å°ä¹å¯ä»¥ä½¿ç¨æ¹æ¬å·è¿è¡æ¥è¯¢ï¼map[&key]ãä¹å°±æ¯è¯´ï¼æ å°å®ç°äºå
ç½®çIndexç¹æ§ãç¶èï¼å¦ææ²¡æç»å®é®çæ¡ç®ï¼è¿ä¼å¯¼è´ç¨åºææ
ï¼panicï¼ï¼å°±åæ°ç»è¶ç访é®ä¸æ ·ï¼æä»¥åªæå¨ç¡®å®è¦æ¥æ¾çæ¡ç®å·²è¢«å¡«å
çæ
åµä¸ï¼æä½¿ç¨è¿ç§è¯æ³ã
.contains_key()ã.get()ã.get_mut()å.remove()çé®åæ°ä¸ä¸å®å¿
é¡»æ¯ç²¾ç¡®ç&Kç±»åãè¿äºæ¹æ³å¯¹äºå¯ä»¥ä»Kåç¨çç±»åæ¯æ³åçãå¨HashMap<String, Fish>ä¸è°ç¨fish_map.contains_key("conger")æ¯å¯ä»¥çï¼å³ä½¿"conger"å¹¶ä¸å®å
¨æ¯Stringç±»åï¼å 为Stringå®ç°äºBorrow<&str>ã详ç»ä¿¡æ¯ï¼è¯·åè§ âBorrow and BorrowMutâï¼BorrowåBorrowMutï¼ã
å 为BTreeMap<K, V>æé®å¯¹å
¶æ¡ç®è¿è¡æåºï¼æä»¥å®æ¯æä¸ä¸ªé¢å¤çæä½ï¼
btree_map.split_off(&key)ï¼å°btree_mapåæä¸¤é¨åãé®å°äºkeyçæ¡ç®çå¨btree_mapä¸ãè¿åä¸ä¸ªæ°çBTreeMap<K, V>ï¼å ¶ä¸å å«å ¶ä»æ¡ç®ã
# æ¡ç®
HashMapåBTreeMap齿坹åºçEntryç±»åãæ¡ç®ï¼Entryï¼çæä¹å¨äºæ¶é¤éå¤çæ å°æ¥æ¾ã
ä¾å¦ï¼ä¸é¢è¿æ®µä»£ç ç¨äºè·åæå建å¦çè®°å½ï¼
// æä»¬å·²ç»æè¿ä¸ªå¦ççè®°å½äºåï¼
if!student_map.contains_key(name) {
// 没æï¼å建ä¸ä¸ªã
student_map.insert(name.to_string(), Student::new());
}
// ç°å¨è¯å®æè®°å½äºã
let record = student_map.get_mut(name).unwrap();
...
2
3
4
5
6
7
8
è¿æ®µä»£ç å¯ä»¥æ£å¸¸å·¥ä½ï¼ä½å®è®¿é®student_map两å°ä¸æ¬¡ï¼æ¯æ¬¡é½è¿è¡ç¸åçæ¥æ¾æä½ã
ä½¿ç¨æ¡ç®ï¼Entryï¼çæè·¯æ¯ï¼æä»¬åªè¿è¡ä¸æ¬¡æ¥æ¾ï¼çæä¸ä¸ªEntryå¼ï¼ç¶åç¨äºææåç»æä½ãä¸é¢è¿ä¸è¡ä»£ç ä¸åé¢çææä»£ç çæï¼ä½å®åªè¿è¡äºä¸æ¬¡æ¥æ¾ï¼
let record = student_map.entry(name.to_string()).or_insert_with(Student::new);
student_map.entry(name.to_string())è¿åçEntryå¼ï¼å°±åæ¯å¯¹æ å°ä¸æä¸ªä½ç½®çå¯åå¼ç¨ï¼è¿ä¸ªä½ç½®è¦ä¹è¢«ä¸ä¸ªé®å¼å¯¹å æ®ï¼è¦ä¹ä¸ºç©ºï¼å³è¿æ²¡ææ¡ç®ãå¦æä¸ºç©ºï¼æ¡ç®ç.or_insert_with()æ¹æ³ä¼æå
¥ä¸ä¸ªæ°çStudentã大夿°å¯¹æ¡ç®ç使ç¨é½æ¯è¿æ ·ï¼ç®æ´æäºã
ææçEntryå¼é½æ¯ç±åä¸ä¸ªæ¹æ³å建çï¼
map.entry(key)ï¼è¿åç»å®é®çEntryã妿æ å°ä¸æ²¡æè¿ä¸ªé®ï¼å°±è¿åä¸ä¸ªç©ºçEntryãè¿ä¸ªæ¹æ³éè¿å¯åå¼ç¨æ¥æ¶selfåæ°ï¼å¹¶è¿åä¸ä¸ªå ·æå¹é çå½å¨æçEntryï¼
pub fn entry<'a>(&'a mut self, key: K) -> Entry<'a, K, V>
Entryç±»åæä¸ä¸ªçå½å¨æåæ°'aï¼å 为å®å®é
䏿¯ä¸ç§å¯¹æ å°çç¹æ®åç¨å¯åå¼ç¨ãåªè¦Entryåå¨ï¼å®å°±å¯¹æ å°å
·æç¬å è®¿é®æã
å¨ âStructs Containing Referencesâï¼å
å«å¼ç¨çç»æä½ï¼ä¸ï¼æä»¬äºè§£äºå¦ä½å¨ç±»åä¸åå¨å¼ç¨ä»¥åè¿å¯¹çå½å¨æçå½±åãç°å¨æä»¬ä»ç¨æ·çè§åº¦æ¥çè¿æ¯ææ ·çãè¿å°±æ¯Entryçå·¥ä½åçã
éæ¾çæ¯ï¼å¦ææ å°çé®ç±»åæ¯Stringï¼å°±ä¸è½å°&strç±»åçå¼ç¨ä¼ éç»è¿ä¸ªæ¹æ³ãå¨è¿ç§æ
åµä¸ï¼.entry()æ¹æ³éè¦ä¸ä¸ªçæ£çStringã
Entry弿ä¾äºä¸ä¸ªæ¹æ³æ¥å¤ç空æ¡ç®ï¼
map.entry(key).or_insert(value)ï¼ç¡®ä¿æ å°å å«å ·æç»å®é®çæ¡ç®ï¼å¦æéè¦åæå ¥ä¸ä¸ªå ·æç»å®å¼çæ°æ¡ç®ãå®è¿å对æ°å¼æç°æå¼çå¯åå¼ç¨ãå设æä»¬éè¦ç»è®¡éç¥¨ï¼æä»¬å¯ä»¥è¿æ ·åï¼
let mut vote_counts: HashMap<String, usize> = HashMap::new();
for name in ballots {
let count = vote_counts.entry(name).or_insert(0);
*count += 1;
}
2
3
4
5
.or_insert()è¿åä¸ä¸ªå¯åå¼ç¨ï¼æä»¥countçç±»åæ¯&mut usizeã
map.entry(key).or_default()ï¼ç¡®ä¿æ å°å å«å ·æç»å®é®çæ¡ç®ï¼å¦æéè¦åæå ¥ä¸ä¸ªå¼ï¼è¯¥å¼ç±Default::default()è¿åãè¿åªå¯¹å®ç°äºDefaultçç±»åææãä¸or_insert类似ï¼è¿ä¸ªæ¹æ³è¿å对æ°å¼æç°æå¼çå¯åå¼ç¨ãmap.entry(key).or_insert_with(default_fn)ï¼ä¸or_default类似ï¼åªæ¯å¦æéè¦åå»ºæ°æ¡ç®ï¼å®ä¼è°ç¨default_fn()æ¥çæé»è®¤å¼ã妿æ å°ä¸å·²ç»æç»å®é®çæ¡ç®ï¼å°±ä¸ä¼ä½¿ç¨default_fnãå设æä»¬æ³ç¥éåªäºåè¯åºç°å¨åªäºæä»¶ä¸ï¼æä»¬å¯ä»¥è¿æ ·åï¼
// è¿ä¸ªæ å°å
嫿¯ä¸ªåè¯ä»¥åå®åºç°çæä»¶éåã
let mut word_occurrence: HashMap<String, HashSet<String>> = HashMap::new();
for file in files {
for word in read_words(file)? {
let set = word_occurrence
.entry(word)
.or_insert_with(HashSet::new);
set.insert(file.clone());
}
}
2
3
4
5
6
7
8
9
10
Entryè¿æä¾äºä¸ç§æ¹ä¾¿çæ¹å¼ï¼ä»
ä¿®æ¹ç°æå段ã
map.entry(key).and_modify(closure)ï¼å¦æåå¨å ·æç»å®é®çæ¡ç®ï¼åè°ç¨éå ï¼å¹¶ä¼ å ¥å¯¹å¼çå¯åå¼ç¨ãå®è¿åEntryï¼å æ¤å¯ä»¥ä¸å ¶ä»æ¹æ³é¾å¼è°ç¨ãä¾å¦ï¼æä»¬å¯ä»¥ç¨è¿ä¸ªæ¹æ³ç»è®¡å符串ä¸åè¯çåºç°æ¬¡æ°ï¼
// è¿ä¸ªæ å°å
å«ç»å®å符串ä¸çææåè¯ï¼ä»¥åå®ä»¬åºç°ç次æ°ã
let mut word_frequency: HashMap<&str, u32> = HashMap::new();
for c in text.split_whitespace() {
word_frequency.entry(c)
.and_modify(|count| *count += 1)
.or_insert(1);
}
2
3
4
5
6
7
Entryç±»åæ¯ä¸ä¸ªæä¸¾ï¼HashMapçå®ä¹å¦ä¸ï¼BTreeMap类似ï¼ï¼
// ï¼å¨std::collections::hash_mapä¸ï¼
pub enum Entry<'a, K, V> {
Occupied(OccupiedEntry<'a, K, V>),
Vacant(VacantEntry<'a, K, V>)
}
2
3
4
5
OccupiedEntryåVacantEntryç±»åå
·æç¨äºæå
¥ãå é¤åè®¿é®æ¡ç®çæ¹æ³ï¼èæ ééå¤åå§æ¥æ¾ãä½ å¯ä»¥å¨å¨çº¿ææ¡£ä¸æ¾å°å®ä»¬ãè¿äºé¢å¤çæ¹æ³å¶å°å¯ä»¥ç¨äºæ¶é¤ä¸ä¸¤ä¸ªéå¤çæ¥æ¾ï¼ä½.or_insert()å.or_insert_with()æ¶µçäºå¸¸è§çæ
åµã
# æ å°è¿ä»£
æå ç§è¿ä»£æ å°çæ¹å¼ï¼
- æå¼è¿ä»£ï¼
for (k, v) in mapï¼çæ(K, V)对ãè¿ä¼æ¶èæ å°ã - 对å
±äº«å¼ç¨è¿è¡è¿ä»£ï¼
for (k, v) in &mapï¼çæ(&K, &V)对ã - 对å¯åå¼ç¨è¿è¡è¿ä»£ï¼
for (k, v) in &mut mapï¼çæ(&K, &mut V)对ãï¼åæ ·ï¼æ æ³å¯¹åå¨å¨æ å°ä¸çé®è¿è¡å¯å访é®ï¼å 为æ¡ç®æ¯æ ¹æ®é®æ¥ç»ç»çãï¼
ä¸åéç±»ä¼¼ï¼æ å°æ.iter()å.iter_mut()æ¹æ³ï¼å®ä»¬è¿åæå¼ç¨çè¿ä»£å¨ï¼å°±å对&mapæ&mut mapè¿è¡è¿ä»£ä¸æ ·ãæ¤å¤ï¼
map.keys()ï¼è¿åä¸ä¸ªä» 对é®è¿è¡å¼ç¨çè¿ä»£å¨ãmap.values()ï¼è¿åä¸ä¸ªå¯¹å¼è¿è¡å¼ç¨çè¿ä»£å¨ãmap.values_mut()ï¼è¿åä¸ä¸ªå¯¹å¼è¿è¡å¯åå¼ç¨çè¿ä»£å¨ã
ææHashMapè¿ä»£å¨ä»¥ä»»æé¡ºåºè®¿é®æ å°çæ¡ç®ãBTreeMapè¿ä»£å¨æé®ç顺åºè®¿é®å®ä»¬ã
# HashSet<T> å BTreeSet<T>
éåæ¯ä¸ºå¿«éæåæµè¯èç»ç»çå¼çéåï¼
let b1 = large_vector.contains(&"needle"); // æ
¢ï¼æ£æ¥æ¯ä¸ªå
ç´
let b2 = large_hash_set.contains(&"needle"); // å¿«ï¼å叿¥æ¾
2
éå䏿°¸è¿ä¸ä¼å å«åä¸ä¸ªå¼çå¤ä¸ªå¯æ¬ã
æ å°åéåæä¸åçæ¹æ³ï¼ä½å¨åºå±ï¼éåå°±åæ¯åªæé®è没æé®å¼å¯¹çæ å°ãå®é
ä¸ï¼Rustç两ç§éåç±»åHashSet<T>åBTreeSet<T>ï¼æ¯å¯¹HashMap<T, ()>åBTreeMap<T, ()>çç®åå
è£
ã
HashSet::new()ãBTreeSet::new()ï¼å建æ°çéåãiter.collect()ï¼å¯ç¨äºä»ä»»ä½è¿ä»£å¨å建æ°çéåã妿è¿ä»£å¨çæçä»»ä½å¼åºç°å¤æ¬¡ï¼éå¤çå¼å°è¢«ä¸¢å¼ãHashSet::with_capacity(n)ï¼å建ä¸ä¸ªç©ºçHashSetï¼è³å°æå®¹çº³n个å¼ç空é´ã
HashSet<T>åBTreeSet<T>æææç¸åçåºæ¬æ¹æ³ï¼
set.len()ï¼è¿åéåä¸çå¼çæ°éãset.is_empty()ï¼å¦æéåä¸å å«ä»»ä½å ç´ ï¼åè¿åtrueãset.contains(&value)ï¼å¦æéåå å«ç»å®å¼ï¼åè¿åtrueãset.insert(value)ï¼åéå䏿·»å ä¸ä¸ªå¼ãå¦ææ·»å äºä¸ä¸ªå¼ï¼åè¿åtrueï¼å¦æè¯¥å¼å·²ç»æ¯éåçæåï¼åè¿åfalseãset.remove(&value)ï¼ä»éåä¸å é¤ä¸ä¸ªå¼ã妿å é¤äºä¸ä¸ªå¼ï¼åè¿åtrueï¼å¦æè¯¥å¼æ¬æ¥å°±ä¸æ¯éåçæåï¼åè¿åfalseãset.retain(test)ï¼å é¤æææªéè¿ç»å®æµè¯çå ç´ ãteståæ°æ¯ä¸ä¸ªå®ç°äºFnMut(&T) -> boolç彿°æéå ã对äºéåä¸çæ¯ä¸ªå ç´ ï¼é½ä¼è°ç¨test(&value)ï¼å¦æè¿åfalseï¼åä»éåä¸å é¤è¯¥å ç´ å¹¶éæ¾å ¶å åãé¤äºæ§è½æ¹é¢ï¼è¿ç±»ä¼¼äºç¼åï¼set = set.into_iter().filter(test).collect();
䏿 å°ä¸æ ·ï¼éè¿å¼ç¨æ¥æ¾å¼çæ¹æ³å¯¹äºå¯ä»¥ä»Tåç¨çç±»åæ¯æ³åçã详ç»ä¿¡æ¯ï¼è¯·åè§ âBorrow and BorrowMutâï¼BorrowåBorrowMutï¼ã
# éåè¿ä»£
æä¸¤ç§è¿ä»£éåçæ¹å¼ï¼
- æå¼è¿ä»£ï¼
for v in setï¼çæéåçæåï¼å¹¶æ¶èéåï¼ã - æå
±äº«å¼ç¨è¿ä»£ï¼
for v in &setï¼çæå¯¹éåæåçå ±äº«å¼ç¨ã
䏿¯ææå¯åå¼ç¨è¿ä»£éåãæ æ³è·å对åå¨å¨éåä¸çå¼çå¯åå¼ç¨ã
set.iter()ï¼è¿åä¸ä¸ªå¯¹éåæåè¿è¡å¼ç¨çè¿ä»£å¨ã
HashSetè¿ä»£å¨ä¸HashMapè¿ä»£å¨ä¸æ ·ï¼ä»¥ä»»æé¡ºåºçæå®ä»¬çå¼ãBTreeSetè¿ä»£å¨æé¡ºåºçæå¼ï¼å°±åæåºåçåé䏿 ·ã
# å½ç¸çç弿差弿¶
éåæä¸äºç¹æ®çæ¹æ³ï¼åªæå¨ä½ å ³å¿ âç¸çâ å¼ä¹é´ç差弿¶æéè¦ä½¿ç¨ã
è¿æ ·çå·®å¼ç¡®å®ç»å¸¸åå¨ãä¾å¦ï¼ä¸¤ä¸ªç¸åçStringå¼ï¼å®ä»¬çå符åå¨å¨å
åä¸çä¸åä½ç½®ï¼
let s1 = "hello".to_string();
let s2 = "hello".to_string();
println!("{:p}", &s1 as &str); // 0x7f8b32060008
println!("{:p}", &s2 as &str); // 0x7f8b32060010
2
3
4
éå¸¸ï¼æä»¬å¹¶ä¸å¨æè¿äºã
ä½å¦æä½ ç¡®å®å¨æï¼å¯ä»¥ä½¿ç¨ä»¥ä¸æ¹æ³è®¿é®åå¨å¨éåä¸çå®é
å¼ã妿éåä¸å
å«å¹é
çå¼ï¼æ¯ä¸ªæ¹æ³é½è¿åä¸ä¸ªOptionç±»åçå¼ï¼ä¸å¼ä¸ºNoneï¼
set.get(&value)ï¼è¿å对éåä¸çäºvalueçæåçå ±äº«å¼ç¨ï¼å¦ææçè¯ï¼ãè¿åOption<&T>ãset.take(&value)ï¼ä¸set.remove(&value)类似ï¼ä½å®è¿å被å é¤çå¼ï¼å¦ææçè¯ï¼ãè¿åOption<T>ãset.replace(value)ï¼ä¸set.insert(value)类似ï¼ä½å¦æéåä¸å·²ç»å å«çäºvalueçå¼ï¼è¿ä¸ªæ¹æ³ä¼æ¿æ¢å¹¶è¿åæ§å¼ãè¿åOption<T>ã
# éåçæ´ä½æä½
å°ç®å为æ¢ï¼æä»¬çå°ç大夿°éåæ¹æ³é½éä¸å¨å个éåä¸çå个å¼ä¸ãéå乿坹æ´ä¸ªéåè¿è¡æä½çæ¹æ³ï¼
set1.intersection(&set2)ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼å®ä¼éååæ¶åå¨äºset1åset2ä¸çææå¼ãä¾å¦ï¼å¦ææä»¬æ³æå°æææ¢ä¸èå¤ç§ææ¯è¯¾åä¸ç«ç®ç§å¦è¯¾çå¦ççååï¼æä»¬å¯ä»¥è¿æ ·åï¼
for student in &brain_class {
if rocket_class.contains(student) {
println!("{}", student);
}
}
2
3
4
5
æè ï¼æ´ç®ççåæ³ï¼
for student in brain_class.intersection(&rocket_class) {
println!("{}", student);
}
2
3
令人æè®¶çæ¯ï¼æä¸ä¸ªè¿ç®ç¬¦ä¹è½å®ç°è¿ä¸ªåè½ã&set1 & &set2ä¼è¿åä¸ä¸ªæ°éåï¼å®æ¯set1åset2ç交éãè¿æ¯äºè¿å¶æä½ä¸è¿ç®ç¬¦ï¼åºç¨äºä¸¤ä¸ªå¼ç¨ãå®ä¼æ¾åºåæ¶å¨set1åset2ä¸çå¼ï¼
let overachievers = &brain_class & &rocket_class;
set1.union(&set2)ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼å®ä¼éååå¨äºset1æset2ä¸ï¼æè åæ¶åå¨äºä¸¤è ä¸çå¼ã&set1 | &set2ä¼è¿åä¸ä¸ªå 嫿æè¿äºå¼çæ°éåãå®ä¼æ¾åºå¨set1æset2ä¸çå¼ãset1.difference(&set2)ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼å®ä¼éååå¨äºset1ä½ä¸åå¨äºset2ä¸çå¼ã&set1 - &set2ä¼è¿åä¸ä¸ªå 嫿æè¿äºå¼çæ°éåãset1.symmetric_difference(&set2)ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼å®ä¼éååå¨äºset1æset2ä¸ï¼ä½ä¸åæ¶åå¨äºä¸¤è ä¸çå¼ã&set1 ^ &set2ä¼è¿åä¸ä¸ªå 嫿æè¿äºå¼çæ°éåã
è¿æä¸ä¸ªç¨äºæµè¯éåä¹é´å ³ç³»çæ¹æ³ï¼
set1.is_disjoint(set2)ï¼å¦æset1åset2没æå ±åçå¼ï¼å³å®ä»¬ç交é为空ï¼åè¿åtrueãset1.is_subset(set2)ï¼å¦æset1æ¯set2çåéï¼å³set1ä¸çææå¼ä¹é½å¨set2ä¸ï¼åè¿åtrueãset1.is_superset(set2)ï¼ä¸is_subsetç¸åï¼å¦æset1æ¯set2çè¶ éï¼åè¿åtrueã
éå乿¯æä½¿ç¨==å!=è¿è¡ç¸çæ§æµè¯ï¼å¦æä¸¤ä¸ªéåå
å«ç¸åçå¼ï¼åå®ä»¬ç¸çã
# åå¸
std::hash::Hashæ¯æ ååºä¸ç¨äºå¯åå¸ç±»åçç¹æ§ãHashMapçé®åHashSetçå
ç´ å¿
须忶å®ç°HashåEqã
大夿°å®ç°äºEqçå
置类åä¹å®ç°äºHashãæ´æ°ç±»åãcharåString齿¯å¯åå¸çï¼åªè¦å
ç»ãæ°ç»ãåçååéçå
ç´ æ¯å¯åå¸çï¼å®ä»¬ä¹æ¯å¯åå¸çã
æ ååºçä¸ä¸ªå忝ï¼ä¸ä¸ªå¼æ 论åå¨å¨åªéæå¦ä½æåå®ï¼é½åºè¯¥å
·æç¸åçåå¸ç ãå æ¤ï¼ä¸ä¸ªå¼ç¨ä¸å
¶æå¼ç¨çå¼å
·æç¸åçåå¸ç ï¼ä¸ä¸ªBoxä¸å
¶è£
ç®±çå¼å
·æç¸åçåå¸ç ãä¸ä¸ªåévecä¸å
å«å
¶æææ°æ®çåç&vec[..]å
·æç¸åçåå¸ç ãä¸ä¸ªStringä¸å
·æç¸åå符ç&strå
·æç¸åçåå¸ç ã
ç»æä½åæä¸¾é»è®¤ä¸å®ç°Hashï¼ä½å¯ä»¥æ´¾çå®ç°ï¼
/// 大è±åç©é¦èåçç¼å·ã
#[derive(Clone, PartialEq, Eq, Hash)]
enum MuseumNumber {
...
}
2
3
4
5
åªè¦ç±»åçåæ®µé½æ¯å¯åå¸çï¼è¿æ ·å°±è½æ£å¸¸å·¥ä½ã
å¦æä½ æå¨ä¸ºä¸ä¸ªç±»åå®ç°PartialEqï¼ä¹åºè¯¥æå¨å®ç°Hashãä¾å¦ï¼å设æä»¬æä¸ä¸ªè¡¨ç¤ºæ ä»·åå²çå®çç±»åï¼
struct Artifact {
id: MuseumNumber,
name: String,
cultures: Vec<Culture>,
date: RoughTime,
...
}
2
3
4
5
6
7
å¦æä¸¤ä¸ªArtifactå
·æç¸åçidï¼å认为å®ä»¬ç¸çï¼
impl PartialEq for Artifact {
fn eq(&self, other: &Artifact) -> bool {
self.id == other.id
}
}
impl Eq for Artifact {}
2
3
4
5
6
ç±äºæä»¬ä»
æ ¹æ®idæ¥æ¯è¾Artifactï¼æä»¥å¿
须以ç¸åçæ¹å¼å¯¹å®ä»¬è¿è¡åå¸ï¼
use std::hash::{Hash, Hasher};
impl Hash for Artifact {
fn hash<H: Hasher>(&self, hasher: &mut H) {
// å°åå¸å§æç»MuseumNumberã
self.id.hash(hasher);
}
}
2
3
4
5
6
7
8
ï¼å¦åï¼HashSet<Artifact>å°æ æ³æ£å¸¸å·¥ä½ï¼ä¸ææåå¸è¡¨ä¸æ ·ï¼å®è¦æ±å¦æa == bï¼åhash(a) == hash(b)ãï¼
è¿ä½¿æä»¬è½å¤å建ä¸ä¸ªArtifactçHashSetï¼
let mut collection = HashSet::<Artifact>::new();
å¦è¿æ®µä»£ç æç¤ºï¼å³ä½¿ä½ æå¨å®ç°Hashï¼ä¹ä¸éè¦äºè§£ä»»ä½åå¸ç®æ³çç¥è¯ã.hash()æ¥æ¶ä¸ä¸ªæåHasherçå¼ç¨ï¼Hasher代表åå¸ç®æ³ãä½ åªéå°ä¸==è¿ç®ç¬¦ç¸å
³çæææ°æ®æä¾ç»è¿ä¸ªHasherãHasher伿 ¹æ®ä½ æä¾çæ°æ®è®¡ç®åºä¸ä¸ªåå¸ç ã
# 使ç¨èªå®ä¹åå¸ç®æ³
hashæ¹æ³æ¯æ³åçï¼æä»¥åé¢å±ç¤ºçHashå®ç°å¯ä»¥å°æ°æ®æä¾ç»ä»»ä½å®ç°äºHasherçç±»åãè¿å°±æ¯Rustæ¯æå¯ææåå¸ç®æ³çæ¹å¼ã
第ä¸ä¸ªç¹æ§std::hash::BuildHasherï¼æ¯ç¨äºè¡¨ç¤ºåå¸ç®æ³åå§ç¶æçç±»åçç¹æ§ãæ¯ä¸ªHasher齿¯ä¸æ¬¡æ§çï¼å°±åè¿ä»£å¨ä¸æ ·ï¼ä½ 使ç¨ä¸æ¬¡å就丢å¼å®ãBuildHasheræ¯å¯å¤ç¨çã
æ¯ä¸ªHashMapé½å
å«ä¸ä¸ªBuildHasherï¼æ¯æ¬¡éè¦è®¡ç®åå¸ç æ¶é½ä¼ä½¿ç¨å®ãBuildHasherå¼å
å«åå¸ç®æ³æ¯æ¬¡è¿è¡æéçé®ãåå§ç¶ææå
¶ä»åæ°ã
计ç®åå¸ç ç宿´æµç¨å¦ä¸ï¼
use std::hash::{Hash, Hasher, BuildHasher};
fn compute_hash<B, T>(builder: &B, value: &T) -> u64
where
B: BuildHasher,
T: Hash
{
let mut hasher = builder.build_hasher(); // 1. å¯å¨ç®æ³
value.hash(&mut hasher); // 2. åå
¶æä¾æ°æ®
hasher.finish() // 3. å®æè®¡ç®ï¼çæä¸ä¸ªu64ç±»åçå¼
}
2
3
4
5
6
7
8
9
10
11
HashMapæ¯æ¬¡éè¦è®¡ç®åå¸ç æ¶é½ä¼è°ç¨è¿ä¸ä¸ªæ¹æ³ãææè¿äºæ¹æ³é½æ¯å
èçï¼æä»¥é度é常快ã
Rustçé»è®¤åå¸ç®æ³æ¯ä¸ç§å为SipHash - 1 - 3çç¥åç®æ³ãSipHashé度å¾å¿«ï¼å¹¶ä¸å¨æå°ååå¸å²çªæ¹é¢è¡¨ç°åºè²ãå®é ä¸ï¼å®æ¯ä¸ç§å å¯ç®æ³ï¼ç®åè¿æ²¡æå·²ç¥çæææ¹æ³æ¥çæSipHash - 1 - 3å²çªãåªè¦ä¸ºæ¯ä¸ªåå¸è¡¨ä½¿ç¨ä¸åçãä¸å¯é¢æµçé®ï¼Rustå°±å¯ä»¥æµå¾¡ä¸ç§ç§°ä¸ºHashDoSçæç»æå¡æ»å»ï¼å¨è¿ç§æ»å»ä¸ï¼æ»å»è æ æå©ç¨åå¸å²çªæ¥è§¦åæå¡å¨çæåæ§è½ã
ä½ä¹è®¸ä½ çåºç¨ç¨åºä¸éè¦è¿æ ·çå®å
¨æ§ãå¦æä½ åå¨çæ¯è®¸å¤å°é®ï¼æ¯å¦æ´æ°æé常ççåç¬¦ä¸²ï¼æå¯è½å®ç°ä¸ç§æ´å¿«çåå¸å½æ°ï¼ä¸è¿è¦ä»¥çºç²HashDoSå®å
¨æ§ä¸ºä»£ä»·ãfnvåºå®ç°äºä¸ç§è¿æ ·çç®æ³ï¼å³Fowler - Noll - Voï¼FNVï¼åå¸ãè¦å°è¯ä½¿ç¨å®ï¼å¨ä½ çCargo.tomlæä»¶ä¸æ·»å è¿ä¸è¡ï¼
[dependencies]
fnv = "1.0"
2
ç¶åä»fnv导å
¥æ å°åéåç±»åï¼
use fnv::{FnvHashMap, FnvHashSet};
ä½ å¯ä»¥ç¨è¿ä¸¤ç§ç±»åç´æ¥æ¿æ¢HashMapåHashSetãæ¥çfnvæºä»£ç å¯ä»¥åç°å®ä»¬çå®ä¹æ¹å¼ï¼
/// 使ç¨é»è®¤FNVåå¸å¨ç`HashMap`ã
pub type FnvHashMap<K, V> = HashMap<K, V, FnvBuildHasher>;
/// 使ç¨é»è®¤FNVåå¸å¨ç`HashSet`ã
pub type FnvHashSet<T> = HashSet<T, FnvBuildHasher>;
2
3
4
æ åçHashMapåHashSeté忥åä¸ä¸ªå¯éçé¢å¤ç±»ååæ°ï¼ç¨äºæå®åå¸ç®æ³ï¼FnvHashMapåFnvHashSetæ¯HashMapåHashSetçæ³åç±»åå«åï¼ä¸ºè¯¥åæ°æå®äºFNVåå¸å¨ã
# æ åéåä¹å¤
å¨Rustä¸å建ä¸ä¸ªæ°çèªå®ä¹éåç±»åä¸å¨å
¶ä»è¯è¨ä¸å¤§è´ç¸åãä½ éè¿ç»åè¯è¨æä¾çé¨åæ¥ç»ç»æ°æ®ï¼ç»æä½ãæä¸¾ãæ åéåãOptionãBoxççãä¾å¦ï¼åè§ âGeneric Enumsâï¼æ³åæä¸¾ï¼ä¸å®ä¹çBinaryTree<T>ç±»åã
å¦æä½ ä¹ æ¯å¨C++ä¸ä½¿ç¨åå§æéãæå¨å å管çãå®ä½æ°å¯¹è±¡åæ¾å¼è°ç¨ææå½æ°æ¥å®ç°æ°æ®ç»æä»¥è·å¾æä½³æ§è½ï¼ä½ æ çä¼è§å¾å®å ¨çRustç¸å½åéãææè¿äºå·¥å ·æ¬è´¨ä¸é½æ¯ä¸å®å ¨çãå¨Rustä¸å®ä»¬æ¯å¯ç¨çï¼ä½åªæå¨ä½ éæ©ä½¿ç¨ä¸å®å ¨ä»£ç æ¶æè¡ã第22ç« å±ç¤ºäºå¦ä½ä½¿ç¨ï¼å ¶ä¸å æ¬ä¸ä¸ªä½¿ç¨ä¸äºä¸å®å ¨ä»£ç æ¥å®ç°ä¸ä¸ªå®å ¨çèªå®ä¹éåç示ä¾ã
ç®åï¼æä»¬åªéäº«åæ åéååå ¶å®å ¨ã髿çAPI带æ¥ç便å©ãä¸Rustæ ååºç许å¤é¨å䏿 ·ï¼å®ä»¬ç设计ç®çæ¯å°½å¯è½åå°ç¼åä¸å®å ¨ä»£ç çéæ±ã