第17ç« åç¬¦ä¸²åææ¬
# 第17ç« åç¬¦ä¸²åææ¬
å符串æ¯ä¸ç§ç®åçæ°æ®ç»æï¼æ 论å®ä¼ éå°åªéï¼é½ä¼´éç大ééå¤çå¤çè¿ç¨ã宿¯éèä¿¡æ¯çç»ä½³è½½ä½ã
â ââè¾ä¼¦Â·ä½©å©æ¯ï¼è¦å¥#34
卿¬ä¹¦ä¸ï¼æä»¬ä¸ç´å¨ä½¿ç¨Rustçä¸»è¦ææ¬ç±»åï¼Stringãstråcharãå¨ âå符串类åâ ä¸ï¼æä»¬æè¿°äºå符åå符串åé¢å¼çè¯æ³ï¼å¹¶å±ç¤ºäºå符串å¨å
åä¸ç表示æ¹å¼ã卿¬ç« ä¸ï¼æä»¬å°æ´è¯¦ç»å°ä»ç»ææ¬å¤çã
卿¬ç« ä¸ï¼
- æä»¬ä¼ä»ç»ä¸äºUnicodeçèæ¯ç¥è¯ï¼è¿æå©äºä½ çè§£æ ååºç设计ã
- æä»¬å°æè¿°
charç±»åï¼å®è¡¨ç¤ºå个Unicodeç ç¹ã - æä»¬å°æè¿°
Stringåstrç±»åï¼å®ä»¬åå«è¡¨ç¤ºæ¥ææææååç¨çUnicodeå符åºåãè¿äºç±»åå ·æåç§åæ ·çæ¹æ³ï¼ç¨äºæå»ºãæç´¢ãä¿®æ¹åè¿ä»£å ¶å 容ã - æä»¬å°ä»ç»Rustçåç¬¦ä¸²æ ¼å¼ååè½ï¼ä¾å¦
println!åformat!å®ãä½ å¯ä»¥ç¼åèªå·±ç宿¥å¤çæ ¼å¼åå符串ï¼å¹¶æ©å±å®ä»¬ä»¥æ¯æèªå·±çç±»åã - æä»¬å°æ¦è¿°Rust对æ£å表达å¼çæ¯æã
- æåï¼æä»¬å°è®¨è®ºUnicodeè§èåçéè¦æ§ï¼å¹¶å±ç¤ºå¦ä½å¨Rustä¸è¿è¡è§èåã
# ä¸äºUnicodeèæ¯ç¥è¯
æ¬ä¹¦æ¯å ³äºRustçï¼è䏿¯å ³äºUnicodeçï¼å·²ç»æä¸é¨çä¹¦ç±æ¥ä»ç»Unicodeã使¯Rustçå符ååç¬¦ä¸²ç±»åæ¯å´ç»Unicode设计çã以䏿¯ä¸äºæå©äºçè§£RustçUnicodeç¥è¯ã
# ASCIIãLatin-1åUnicode
UnicodeåASCIIå¨ASCIIçææç ç¹ï¼ä»0å°0x7fï¼ä¸æ¯å¹é
çï¼ä¾å¦ï¼ä¸¤è
é½å°å符*çç ç¹æå®ä¸º42ã类似å°ï¼Unicodeå°0å°0xffçç ç¹åé
ç»ä¸ISO/IEC 8859 - 1å符éç¸åçå符ï¼ISO/IEC 8859 - 1æ¯ASCIIçä¸ä¸ªå
«ä½è¶
éï¼ç¨äºè¥¿æ¬§è¯è¨ãUnicodeå°è¿ä¸ªç ç¹èå´ç§°ä¸ºLatin - 1ç åï¼æä»¥æä»¬å°ä½¿ç¨æ´å½¢è±¡çåç§°Latin - 1æ¥æä»£ISO/IEC 8859 - 1ã
ç±äºUnicodeæ¯Latin - 1çè¶ éï¼å°Latin - 1转æ¢ä¸ºUnicodeçè³ä¸éè¦æ¥æ¾è¡¨ï¼
fn latin1_to_char(latin1: u8) -> char {
latin1 as char
}
2
3
å设ç ç¹å¨Latin - 1èå´å ï¼åå转æ¢ä¹å¾ç®åï¼
fn char_to_latin1(c: char) -> Option<u8> {
if c as u32 <= 0xff {
Some(c as u8)
} else {
None
}
}
2
3
4
5
6
7
# UTF-8
RustçStringåstrç±»å使ç¨UTF - 8ç¼ç 形弿¥è¡¨ç¤ºææ¬ãUTF - 8å°ä¸ä¸ªå符ç¼ç 为1å°4个åèçåºåï¼å¾17-1ï¼ã
å¾17-1. UTF-8ç¼ç
æ ¼å¼è¯å¥½çUTF - 8åºåæä¸¤ä¸ªéå¶ã第ä¸ï¼å¯¹äºä»»ä½ç»å®çç ç¹ï¼åªææççç¼ç æè¢«è®¤ä¸ºæ¯æ ¼å¼è¯å¥½çï¼ä½ ä¸è½ç¨4个åèæ¥ç¼ç ä¸ä¸ªç¨3个åèå°±è½è¡¨ç¤ºçç ç¹ãè¿æ¡è§åç¡®ä¿äºå¯¹äºç»å®çç ç¹åªæä¸ç§UTF - 8ç¼ç ã第äºï¼æ ¼å¼è¯å¥½çUTF - 8ä¸è½å¯¹0xd800å°0xdfffæè¶ è¿0x10ffffçæ°åè¿è¡ç¼ç ï¼è¿äºè¦ä¹æ¯ä¸ºéå符ç®çä¿ççï¼è¦ä¹å®å ¨è¶ åºäºUnicodeçèå´ã
å¾17-2å±ç¤ºäºä¸äºç¤ºä¾ã
å¾17-2. UTF-8示ä¾
注æï¼å³ä½¿èè¹è¡¨æ 符å·çç¼ç ä¸ï¼å ¶é¦åè对ç ç¹åªè´¡ç®äºé¶ï¼ä½å®ä»ç¶éè¦ä¸ä¸ª4åèçç¼ç ï¼3åèçUTF - 8ç¼ç åªè½è¡¨ç¤º16ä½çç ç¹ï¼è0x1f980æ¯17ä½é¿ã
ä¸é¢æ¯ä¸ä¸ªå å«ä¸åé¿åº¦ç¼ç å符çå符串示ä¾ï¼
assert_eq!("ãã©ã : udon".as_bytes(), &[
0xe3, 0x81, 0x86, // ã
0xe3, 0x81, 0xa9, // ã©
0xe3, 0x82, 0x93, // ã
0x3a, 0x20, 0x75, 0x64, 0x6f, 0x6e // : udon
]);
2
3
4
5
6
å¾17-2è¿å±ç¤ºäºUTF - 8çä¸äºé常æç¨çç¹æ§ï¼
- ç±äºUTF - 8å°0å°0x7fçç ç¹ç¼ç 为0å°0x7fçåèï¼æä»¥å
å«ASCIIææ¬çåèèå´æ¯ææçUTF - 8ãå¹¶ä¸ï¼å¦æä¸ä¸ªUTF - 8å符串åªå
å«ASCIIå符ï¼åä¹äº¦ç¶ï¼å
¶UTF - 8ç¼ç æ¯ææçASCIIãä½Latin - 1å¹¶é妿¤ï¼ä¾å¦ï¼Latin - 1å°
éç¼ç 为åè0xe9ï¼èUTF - 8ä¼å°å ¶è§£é为ä¸ä¸ª3åèç¼ç çé¦åèã - ä»ä»»ä½ä¸ä¸ªåèçé«ä½æ¯ç¹ï¼ä½ å¯ä»¥ç«å³å¤æå®æ¯æä¸ªå符çUTF - 8ç¼ç çå¼å§ï¼è¿æ¯ç¼ç ä¸é´çä¸ä¸ªåèã
- ä» éè¿ç¼ç çé¦åèçå导æ¯ç¹ï¼ä½ å°±è½ç¥éæ´ä¸ªç¼ç çé¿åº¦ã
- ç±äºæ²¡æç¼ç è¶ è¿4åèï¼å¤çUTF - 8æ¶æ°¸è¿ä¸éè¦æ è¾¹çç循ç¯ï¼å¨å¤çä¸å¯ä¿¡æ°æ®æ¶è¿å¾æç¨ã
- 卿 ¼å¼è¯å¥½çUTF - 8ä¸ï¼å³ä½¿ä»åèä¸é´çä»»æä½ç½®å¼å§ï¼ä½ 乿»è½æç¡®å°å¤æå符ç¼ç çèµ·æ¢ä½ç½®ãUTF - 8çé¦åèååç»åèæ»æ¯ä¸åçï¼æä»¥ä¸ä¸ªç¼ç ä¸å¯è½å¨å¦ä¸ä¸ªç¼ç çä¸é´å¼å§ãé¦åèå³å®äºç¼ç çæ»é¿åº¦ï¼æä»¥ä¸ä¸ªç¼ç ä¸å¯è½æ¯å¦ä¸ä¸ªç¼ç çåç¼ãè¿æå¾å¤å¥½å¤ãä¾å¦ï¼å¨UTF - 8åç¬¦ä¸²ä¸æç´¢ASCIIåé符å符ï¼åªéè¦ç®åå°æ«æåé符çåèå³å¯ã宿°¸è¿ä¸ä¼ä½ä¸ºå¤åèç¼ç çä¸é¨ååºç°ï¼æä»¥æ ¹æ¬ä¸éè¦è·è¸ªUTF - 8çç»æãåæ ·ï¼å¨ä¸ä¸ªåç¬¦ä¸²ä¸æç´¢å¦ä¸ä¸ªåè串çç®æ³ï¼å³ä½¿æäºç®æ³çè³ä¸ä¼æ£æ¥è¢«æç´¢ææ¬çæ¯ä¸ªåèï¼ä¹å¯ä»¥ç´æ¥ç¨äºUTF - 8åç¬¦ä¸²ï¼æ éä¿®æ¹ã
è½ç¶å¯å宽度ç¼ç æ¯åºå®å®½åº¦ç¼ç æ´å¤æï¼ä½è¿äºç¹æ§ä½¿UTF - 8æ¯ä½ æ³è±¡çæ´å®¹æä½¿ç¨ãæ ååºä¼ä¸ºä½ å¤ç大é¨åç¸å ³æä½ã
# ææ¬æ¹å
åæä¸åæ¯ã西éå°åæ¯åæ³°è¯è¿æ ·çæåæ¯ä»å·¦å°å³ä¹¦åçï¼èåå¸ä¼¯æ¥è¯åé¿æä¼¯è¯è¿æ ·çæå忝ä»å³å°å·¦ä¹¦åçãUnicodeæç §å符æ£å¸¸ä¹¦åæé 读ç顺åºåå¨åç¬¦ï¼æä»¥å å«å¸ä¼¯æ¥è¯ææ¬çå符串çèµ·å§åèï¼ç¼ç çæ¯æ£å¸¸ä¹¦åæ¶æå³è¾¹çå符ï¼
assert_eq!("××× ×¢×¨× ".chars().next(), Some('×¢'));
# å符ï¼charï¼
Rustä¸çcharæ¯ä¸ä¸ª32ä½çå¼ï¼ç¨äºåå¨ä¸ä¸ªUnicodeç ç¹ãcharçå¼è¢«ä¿è¯å¨0å°0xd7ffæ0xe000å°0x10ffffçèå´å
ï¼ææå建åæä½charå¼çæ¹æ³é½ç¡®ä¿è¿ä¸ç¹ãcharç±»åå®ç°äºCopyåCloneï¼ä»¥åææå¸¸è§çæ¯è¾ãåå¸åæ ¼å¼åç¹æ§ã
å符串åçå¯ä»¥ä½¿ç¨slice.chars()çæä¸ä¸ªå符è¿ä»£å¨ï¼
assert_eq!("ã«ã ".chars().next(), Some('ã«'));
卿¥ä¸æ¥çæè¿°ä¸ï¼åéchçç±»åå§ç»æ¯charã
# å符åç±»
charç±»åæä¸äºæ¹æ³ï¼ç¨äºå°å符å类为å 个常è§çç±»å«ï¼å¦è¡¨17-1æç¤ºãè¿äºåç±»å®ä¹åæ¥èªUnicodeã
表17-1. charç±»åçåç±»æ¹æ³
| æ¹æ³ | æè¿° | ç¤ºä¾ |
|---|---|---|
ch.is_numeric() | ä¸ä¸ªæ°åå符ãè¿å æ¬Unicodeéç¨ç±»å«ä¸çâæ°åï¼æ°åâåâæ°åï¼åæ¯âï¼ä½ä¸å æ¬âæ°åï¼å ¶ä»â | '4'.is_numeric()'O'.is_numeric()'â§'.is_numeric() |
ch.is_alphabetic() | ä¸ä¸ªåæ¯å符ï¼Unicodeçâåæ¯âæ´¾ç屿§ | 'q'.is_alphabetic()'ä¸'.is_alphabetic() |
ch.is_alphanumeric() | å¦åæè¿°ï¼è¦ä¹æ¯æ°åï¼è¦ä¹æ¯åæ¯ | '9'.is_alphanumeric()'é'.is_alphanumeric()!'*'.is_alphanumeric() |
ch.is_whitespace() | ä¸ä¸ªç©ºç½å符ï¼Unicodeåç¬¦å±æ§âWSpace=Yâ | '\n'.is_whitespace()'\u{A0}'.is_whitespace()' '.is_whitespace() |
ch.is_control() | ä¸ä¸ªæ§å¶å符ï¼Unicodeçâå ¶ä»ï¼æ§å¶âéç¨ç±»å« | '\n'.is_control()'\u{85}'.is_control() |
è¿æä¸ç»å¹¶è¡çæ¹æ³ï¼ä»
éç¨äºASCIIå符ï¼å¯¹äºä»»ä½éASCIIå符è¿åfalseï¼è¡¨17-2ï¼ã
表17-2. charç±»åçASCIIåç±»æ¹æ³
| æ¹æ³ | æè¿° | ç¤ºä¾ |
|---|---|---|
ch.is_ascii() | ä¸ä¸ªASCIIå符ï¼ç ç¹å¨0å°127ï¼å«ï¼ä¹é´çå符 | 'n'.is_ascii()!'ñ'.is_ascii() |
ch.is_ascii_alphabetic() | ä¸ä¸ªASCII大åæå°å忝ï¼èå´æ¯'A'..='Z'æ'a'..='z' | 'n'.is_ascii_alphabetic()!'1'.is_ascii_alphabetic()!'ñ'.is_ascii_alphabetic() |
ch.is_ascii_digit() | ä¸ä¸ªASCIIæ°åï¼èå´æ¯'0'..='9' | '8'.is_ascii_digit()!'-'.is_ascii_digit()!'â§'.is_ascii_digit() |
ch.is_ascii_hexdigit() | èå´å¨'0'..='9'ã'A'..='F'æ'a'..='f'å
çä»»ä½å符 | - |
ch.is_ascii_alphanumeric() | ä¸ä¸ªASCIIæ°åæASCII大åæå°å忝 | 'q'.is_ascii_alphanumeric()'0'.is_ascii_alphanumeric() |
ch.is_ascii_control() | ä¸ä¸ªASCIIæ§å¶å符ï¼å
æ¬DEL | '\n'.is_ascii_control()'\x7f'.is_ascii_control() |
ch.is_ascii_graphic() | ä»»ä½è½å¨é¡µé¢ä¸çä¸ç迹çASCIIåç¬¦ï¼æ¢ä¸æ¯ç©ºæ ¼ä¹ä¸æ¯æ§å¶å符 | 'Q'.is_ascii_graphic()'~'.is_ascii_graphic()!' '.is_ascii_graphic() |
ch.is_ascii_uppercase()ch.is_ascii_lowercase() | ASCII大ååå°å忝 | 'z'.is_ascii_lowercase()'Z'.is_ascii_uppercase() |
ch.is_ascii_punctuation() | 任使¢ä¸æ¯åæ¯ä¹ä¸æ¯æ°åçASCIIå¾å½¢å符 | - |
ch.is_ascii_whitespace() | ä¸ä¸ªASCII空ç½å符ï¼ç©ºæ ¼ãæ°´å¹³å¶è¡¨ç¬¦ãæ¢è¡ç¬¦ãæ¢é¡µç¬¦æå车符 | ' '.is_ascii_whitespace()'\n'.is_ascii_whitespace()!'\u{A0}'.is_ascii_whitespace() |
ææis_ascii_...æ¹æ³å¨u8åèç±»åä¸ä¹å¯ç¨ï¼
assert!(32u8.is_ascii_whitespace());
assert!(b'9'.is_ascii_digit());
2
å¨ä½¿ç¨è¿äºå½æ°å®ç°ç°æè§èï¼å¦ç¼ç¨è¯è¨æ åææä»¶æ ¼å¼ï¼æ¶è¦å°å¿ï¼å 为ä¸åè§èçåç±»æ¹å¼å¯è½ä¼ææäººçå·®å¼ãä¾å¦ï¼æ³¨æis_whitespaceåis_ascii_whitespaceå¨å¤çæäºåç¬¦æ¶ææä¸åï¼
let line_tab = '\u{000b}'; // 'line tab'ï¼ä¹ç§°ä¸º'vertical tab'
assert_eq!(line_tab.is_whitespace(), true);
assert_eq!(line_tab.is_ascii_whitespace(), false);
2
3
char::is_ascii_whitespace彿°å®ç°äºè®¸å¤ç½ç»æ åä¸å¸¸è§ç空ç½å符å®ä¹ï¼èchar::is_whitespaceéµå¾ªUnicodeæ åã
# å¤çæ°å
å¤çæ°åæ¶ï¼ä½ å¯ä»¥ä½¿ç¨ä»¥ä¸æ¹æ³ï¼
ch.to_digit(radix)ï¼å¤æchæ¯å¦æ¯radixè¿å¶çæ°åã妿æ¯ï¼è¿åSome(num)ï¼å ¶ä¸numæ¯ä¸ä¸ªu32ç±»åçå¼ãå¦åï¼è¿åNoneãè¿ä¸ªæ¹æ³åªè¯å«ASCIIæ°åï¼ä¸å æ¬char::is_numericæ¶µççæ´å¹¿æ³çå符类å«ãradixåæ°çåå¼èå´æ¯2å°36ã对äºå¤§äº10çè¿å¶ï¼ASCIIåæ¯ï¼æ 论大å°åï¼é½è¢«è§ä¸ºå¼ä¸º10å°35çæ°åãstd::char::from_digit(num, radix)ï¼è¿æ¯ä¸ä¸ªèªç±å½æ°ï¼å¦æå¯è½çè¯ï¼å®å°u32ç±»åçæ°åå¼num转æ¢ä¸ºcharã妿numå¯ä»¥ç¨radixè¿å¶è¡¨ç¤ºä¸ºå个æ°åï¼from_digitè¿åSome(ch)ï¼å ¶ä¸chå°±æ¯è¿ä¸ªæ°åãå½radix大äº10æ¶ï¼chå¯è½æ¯å°å忝ãå¦åï¼è¿åNoneãè¿æ¯to_digitçååæä½ã妿std::char::from_digit(num, radix)è¿åSome(ch)ï¼é£ä¹ch.to_digit(radix)å°±è¿åSome(num)ã妿chæ¯ASCIIæ°åæå°å忝ï¼åä¹äº¦ç¶ãch.is_digit(radix)ï¼å¦æchæ¯radixè¿å¶çASCIIæ°åï¼è¿åtrueãè¿çåäºch.to_digit(radix) != Noneãä¾å¦ï¼
assert_eq!('F'.to_digit(16), Some(15));
assert_eq!(std::char::from_digit(15, 16), Some('f'));
assert!(char::is_digit('f', 16));
2
3
# å符大å°å转æ¢
å¤çå符大å°åæ¶ï¼
ch.is_lowercase()ãch.is_uppercase()ï¼å¤æchæ¯å°åè¿æ¯å¤§å忝å符ãè¿äºæ¹æ³éµå¾ªUnicodeçâå°åâåâ大åâæ´¾ç屿§ï¼å æ¤å®ä»¬æ¶µçäºåå¸è 忝å西éå°åæ¯è¿æ ·çéæä¸åæ¯ï¼å¹¶ä¸å¯¹ASCIIå符ä¹è½ç»åºé¢æçç»æãch.to_lowercase()ãch.to_uppercase()ï¼æ ¹æ®Unicodeé»è®¤ç大å°å转æ¢ç®æ³ï¼è¿åçæchçå°åæå¤§åçæå符çè¿ä»£å¨ï¼
let mut upper = 's'.to_uppercase();
assert_eq!(upper.next(), Some('S'));
assert_eq!(upper.next(), None);
2
3
è¿äºæ¹æ³è¿åè¿ä»£å¨è䏿¯å个å符ï¼å 为Unicodeä¸ç大å°å转æ¢å¹¶ä¸æ»æ¯ä¸å¯¹ä¸çè¿ç¨ï¼
// å¾·è¯åæ¯âsharp Sâç大å形弿¯âSSâï¼
let mut upper = 'Ã'.to_uppercase();
assert_eq!(upper.next(), Some('S'));
assert_eq!(upper.next(), Some('S'));
assert_eq!(upper.next(), None);
// Unicodeè§å®å°å¸¦ç¹çåè³å
¶å¤§å忝âİâå°å为âiâï¼åé¢è·ç`'\u{307}'`ï¼COMBINING DOT ABOVEï¼ï¼ä»¥ä¾¿åç»å转æ¢ä¸ºå¤§åæ¶è½ä¿çè¿ä¸ªç¹ã
let ch = 'İ'; // `'\u{130}'`
let mut lower = ch.to_lowercase();
assert_eq!(lower.next(), Some('i'));
assert_eq!(lower.next(), Some('\u{307}'));
assert_eq!(lower.next(), None);
2
3
4
5
6
7
8
9
10
11
12
ä¸ºäºæ¹ä¾¿ä½¿ç¨ï¼è¿äºè¿ä»£å¨å®ç°äºstd::fmt::Displayç¹æ§ï¼æä»¥ä½ å¯ä»¥ç´æ¥å°å®ä»¬ä¼ éç»println!æwrite!å®ã
# 䏿´æ°çç¸äºè½¬æ¢
Rustçasè¿ç®ç¬¦å¯ä»¥å°char转æ¢ä¸ºä»»ä½æ´æ°ç±»åï¼ä¼èªå¨å±è½é«ä½æ¯ç¹ä½ï¼
assert_eq!('B' as u32, 66);
assert_eq!('é¥' as u8, 66); // é«ä½æ¯ç¹è¢«æªæ
assert_eq!('äº' as i8, -116); // åç
2
3
asè¿ç®ç¬¦å¯ä»¥å°ä»»ä½u8å¼è½¬æ¢ä¸ºcharï¼å¹¶ä¸charä¹å®ç°äºFrom<u8>ã使¯æ´å®½çæ´æ°ç±»åå¯è½è¡¨ç¤ºæ æçç ç¹ï¼æä»¥å¯¹äºè¿äºç±»åï¼ä½ å¿
须使ç¨std::char::from_u32ï¼å®è¿åOption<char>ï¼
assert_eq!(char::from(66), 'B');
assert_eq!(std::char::from_u32(0x9942), Some('é¥'));
assert_eq!(std::char::from_u32(0xd800), None); // 为UTF - 16ä¿ç
2
3
# String å str
RustçStringåstrç±»åä¿è¯åªå
嫿 ¼å¼è¯å¥½çUTF - 8ç¼ç ãæ ååºéè¿éå¶å建Stringåstrå¼çæ¹å¼ä»¥å对å®ä»¬æ§è¡çæä½ï¼ç¡®ä¿å¨å¼å
¥è¿äºå¼æ¶å®ä»¬çæ ¼å¼æ¯è¯å¥½çï¼å¹¶ä¸å¨åç»æä½ä¸ä¿æè¯å¥½æ ¼å¼ãå®ä»¬ææçæ¹æ³é½ç»´æ¤è¿ä¸ä¿è¯ï¼å¯¹å®ä»¬è¿è¡çä»»ä½å®å
¨æä½é½ä¸ä¼å¼å
¥æ ¼å¼é误çUTF - 8ãè¿ç®åäºå¤çææ¬ç代ç ã
Rustæ ¹æ®æ¹æ³æ¯å¦éè¦å¯è°æ´å¤§å°çç¼å²åºï¼æè
æ¯å¦ä»
å¯¹ææ¬è¿è¡åå°æä½ï¼å°ææ¬å¤çæ¹æ³æ¾å¨stræStringç±»åä¸ãç±äºStringå¯ä»¥è§£å¼ç¨ä¸º&strï¼æä»¥å¨strä¸å®ä¹çæ¯ä¸ªæ¹æ³ä¹å¯ä»¥ç´æ¥å¨Stringä¸ä½¿ç¨ãæ¬èå°æ ¹æ®å¤§è´åè½å¯¹è¿ä¸¤ç§ç±»åçæ¹æ³è¿è¡åç»ä»ç»ã
è¿äºæ¹æ³éè¿åèåç§»éå¯¹ææ¬è¿è¡ç´¢å¼ï¼å¹¶ä»¥åè为å使µéææ¬é¿åº¦ï¼è䏿¯ä»¥å符为åä½ãå®é ä¸ï¼èèå°Unicodeçç¹æ§ï¼æå符索å¼å¹¶ä¸åçèµ·æ¥é£ä¹æç¨ï¼èåèåç§»éæ´å¿«ä¸æ´ç®åãå¦æä½ å°è¯ä½¿ç¨è½å¨æä¸ªå符çUTF - 8ç¼ç ä¸é´çåèåç§»éï¼æ¹æ³ä¼å¼åææ ï¼panicï¼ï¼æä»¥ä½ ä¸ä¼ä»¥è¿ç§æ¹å¼å¼å ¥æ ¼å¼é误çUTF - 8ã
String被å®ç°ä¸ºå¯¹Vec<u8>çå
è£
ï¼ä»¥ç¡®ä¿åéçå
容å§ç»æ¯æ ¼å¼è¯å¥½çUTF - 8ãRustæ°¸è¿ä¸ä¼æ´æ¹Stringç表示形å¼ä½¿å
¶å徿´å¤æï¼æä»¥ä½ å¯ä»¥è®¤ä¸ºStringå
·æä¸Vecç¸åçæ§è½ç¹å¾ã
å¨ä»¥ä¸è§£éä¸ï¼åéçç±»åå¦è¡¨17-3æç¤ºã 表17-3. è§£éä¸ä½¿ç¨çåéç±»å
| åé | åå®ç±»å |
|---|---|
string | String |
slice | &str æå¯è§£å¼ç¨ä¸º &str çç±»åï¼å¦ String æ Rc<String> |
ch | char |
n | usizeï¼è¡¨ç¤ºé¿åº¦ |
i, j | usizeï¼è¡¨ç¤ºåèåç§»é |
range | usize ç±»ååèåç§»éçèå´ï¼æ¢å¯ä»¥æ¯å®å
¨éå®çï¼å¦ i..jï¼ä¹å¯ä»¥æ¯é¨åéå®çï¼å¦ i..ã..j æ .. |
pattern | ä»»ææ¨¡å¼ç±»åï¼charãStringã&strã&[char] æ FnMut(char) -> bool |
æä»¬å°å¨ âæç´¢ææ¬ç模å¼â ä¸æè¿°æ¨¡å¼ç±»åã
# å建Stringå¼
å建String弿å ç§å¸¸è§çæ¹æ³ï¼
String::new()ï¼è¿åä¸ä¸ªå ¨æ°ç空å符串ã宿²¡æå¨å ä¸åé ç¼å²åºï¼ä½ä¼æ ¹æ®éè¦è¿è¡åé ãString::with_capacity(n)ï¼è¿åä¸ä¸ªå ¨æ°ç空å符串ï¼å¹¶é¢å åé ä¸ä¸ªè³å°è½å®¹çº³nåèçç¼å²åºãå¦æä½ äºå ç¥éè¦æå»ºçå符串çé¿åº¦ï¼è¿ä¸ªæé 彿°å¯ä»¥è®©ä½ ä»ä¸å¼å§å°±æ£ç¡®è®¾ç½®ç¼å²åºç大å°ï¼è䏿¯å¨æå»ºå符串çè¿ç¨ä¸è°æ´ç¼å²åºå¤§å°ã妿å符串çé¿åº¦è¶ è¿nåèï¼å®ä»ç¶ä¼æ ¹æ®éè¦æ©å±ç¼å²åºãä¸åé类似ï¼åç¬¦ä¸²ä¹æcapacityãreserveåshrink_to_fitæ¹æ³ï¼ä½é常é»è®¤çåé é»è¾å°±è¶³å¤äºãstr_slice.to_string()ï¼åé ä¸ä¸ªæ°çStringï¼å ¶å 容æ¯str_sliceç坿¬ã卿¬ä¹¦ä¸ï¼æä»¬ä¸ç´å¨ä½¿ç¨ç±»ä¼¼"literal text".to_string()è¿æ ·ç表达å¼ï¼ä»å符串åé¢éå建Stringãiter.collect()ï¼éè¿è¿æ¥è¿ä»£å¨ä¸çé¡¹æ¥æé ä¸ä¸ªå符串ï¼è¿äºé¡¹å¯ä»¥æ¯charã&stræStringç±»åçå¼ãä¾å¦ï¼è¦ä»å符串ä¸å 餿æç©ºæ ¼ï¼å¯ä»¥è¿æ ·åï¼
let spacey = "man hat tan";
let spaceless: String = spacey.chars().filter(|c|!c.is_whitespace()).collect();
assert_eq!(spaceless, "manhattan");
2
3
以è¿ç§æ¹å¼ä½¿ç¨collectï¼å©ç¨äºString对std::iter::FromIteratorç¹æ§çå®ç°ã
slice.to_owned()ï¼è¿åsliceç坿¬ï¼ä½ä¸ºæ°åé çStringãstrç±»åä¸è½å®ç°Cloneç¹æ§ï¼å ä¸ºè¯¥ç¹æ§è¦æ±å¯¹&strè°ç¨cloneæ¶è¿åstrå¼ï¼ä½stræ¯æª Sized ç±»åãç¶èï¼&strå®ç°äºToOwnedï¼è¿ä½¿å¾å®ç°è å¯ä»¥æå®å ¶æ¥ææææççæç±»åã
# ç®åæ£æ¥
è¿äºæ¹æ³ç¨äºä»å符串åçä¸è·ååºæ¬ä¿¡æ¯ï¼
slice.len()ï¼è¿åsliceçé¿åº¦ï¼ä»¥åè为åä½ãslice.is_empty()ï¼å¦æslice.len() == 0ï¼è¿åtrueãslice[range]ï¼è¿ååç¨sliceç»å®é¨åçåçãé¨åéå®åä¸éå®èå´é½æ¯å 许çï¼ä¾å¦ï¼
let full = "bookkeeping";
assert_eq!(&full[..4], "book");
assert_eq!(&full[5..], "eeping");
assert_eq!(&full[2..4], "ok");
assert_eq!(full[..].len(), 11);
assert_eq!(full[5..].contains("boo"), false);
2
3
4
5
6
注æï¼ä½ ä¸è½åslice[i]è¿æ ·ç¨å个ä½ç½®å¯¹å符串åçè¿è¡ç´¢å¼ãå¨ç»å®çåèåç§»éå¤è·åå个å符æç¹éº»ç¦ï¼ä½ å¿
é¡»å¨åçä¸çæä¸ä¸ªcharsè¿ä»£å¨ï¼å¹¶è®©å®è§£æä¸ä¸ªå符çUTF - 8ç¼ç ï¼
let parenthesized = "Rust (é)";
assert_eq!(parenthesized[6..].chars().next(), Some('é'));
2
ä¸è¿ï¼ä½ å¾å°éè¦è¿æ ·åãRustææ´å¥½çæ¹æ³æ¥è¿ä»£åçï¼æä»¬å°å¨ âè¿ä»£ææ¬â ä¸ä»ç»ã
slice.split_at(i)ï¼è¿åä¸ä¸ªç±ä¸¤ä¸ªå ±äº«åçç»æçå ç»ï¼è¿ä¸¤ä¸ªåçåä»sliceåç¨ï¼ä¸ä¸ªæ¯å°åèåç§»éiä¹åçé¨åï¼å¦ä¸ä¸ªæ¯iä¹åçé¨åãæ¢å¥è¯è¯´ï¼å®è¿å(slice[..i], slice[i..])ãslice.is_char_boundary(i)ï¼å¦æåèåç§»éiè½å¨å符边çä¹é´ï¼å æ¤éåä½ä¸ºsliceçåç§»éï¼åè¿åtrueã
èªç¶å°ï¼åçå¯ä»¥è¿è¡ç¸çæ§æ¯è¾ãæåºåå叿ä½ãæåºæ¯è¾åªæ¯å°å符串è§ä¸ºUnicodeç ç¹çåºåï¼å¹¶æåå ¸é¡ºåºè¿è¡æ¯è¾ã
# 追å åæå ¥ææ¬
以䏿¹æ³ç¨äºåString䏿·»å ææ¬ï¼
string.push(ch)ï¼å°å符ch追å å°stringçæ«å°¾ãstring.push_str(slice)ï¼å°sliceçå ¨é¨å 容追å å°stringãstring.extend(iter)ï¼å°è¿ä»£å¨iterçæç项追å å°stringãè¿ä»£å¨å¯ä»¥çæcharãstræStringç±»åçå¼ãè¿äºæ¯String对std::iter::Extendç¹æ§çå®ç°ï¼
let mut also_spaceless = "con".to_string();
also_spaceless.extend("tri but ion".split_whitespace());
assert_eq!(also_spaceless, "contribution");
2
3
string.insert(i, ch)ï¼å¨stringçåèåç§»éiå¤æå ¥å个å符chãè¿éè¦å°iä¹åçææå符ååç§»å¨ï¼ä¸ºchè ¾åºç©ºé´ï¼æä»¥ç¨è¿ç§æ¹å¼æå»ºåç¬¦ä¸²çæ¶é´å¤æåº¦å¯è½ä¸å符串é¿åº¦çå¹³æ¹ææ£æ¯ãstring.insert_str(i, slice)ï¼å¯¹sliceæ§è¡ç¸åçæä½ï¼åæ ·å卿§è½æ¹é¢çé®é¢ã
Stringå®ç°äºstd::fmt::Writeï¼è¿æå³çwrite!åwriteln!å®å¯ä»¥å°æ ¼å¼åçææ¬è¿½å å°Stringä¸ï¼
use std::fmt::Write;
let mut letter = String::new();
writeln!(letter, "Whose {} these are I think I know", "rutabagas")?;
writeln!(letter, "His house is in the village though;")?;
assert_eq!(letter, "Whose rutabagas these are I think I know\nHis house is in the village though;\n");
2
3
4
5
6
ç±äºwrite!åwriteln!æ¯ä¸ºåå
¥è¾åºæµè设计çï¼å®ä»¬ä¼è¿åä¸ä¸ªResultï¼å¦æå¿½ç¥è¿ä¸ªç»æï¼Rust伿¥éãè¿æ®µä»£ç 使ç¨?æä½ç¬¦æ¥å¤çå®ï¼ä½å®é
ä¸åå
¥Stringæ¯ä¸ä¼åºéçï¼æä»¥å¨è¿ç§æ
åµä¸è°ç¨.unwrap()ä¹å¯ä»¥ã
ç±äºStringå®ç°äºAdd<&str>åAddAssign<&str>ï¼ä½ å¯ä»¥ç¼åå¦ä¸ä»£ç ï¼
let left = "partners".to_string();
let mut right = "crime".to_string();
assert_eq!(left + " in " + &right, "partners in crime");
right += " doesn't pay";
assert_eq!(right, "crime doesn't pay");
2
3
4
5
å½åºç¨äºå符串æ¶ï¼+æä½ç¬¦æå¼è·åå
¶å·¦æä½æ°ï¼æä»¥å®å®é
ä¸å¯ä»¥å°è¯¥Stringéç¨ä½å æ³çç»æãå æ¤ï¼å¦æå·¦æä½æ°çç¼å²åºè¶³å¤å¤§ï¼è½å¤å®¹çº³ç»æï¼å°±ä¸éè¦è¿è¡åé
ã
ä¸å¤ªå¯¹ç§°çæ¯ï¼+çå·¦æä½æ°ä¸è½æ¯&strï¼æä»¥ä½ ä¸è½è¿æ ·åï¼
let parenthetical = "(" + string + ")";
ä½ å¿ é¡»è¿æ ·åï¼
let parenthetical = "(".to_string() + &string + ")";
ç¶èï¼è¿ä¸ªéå¶ç¡®å®ä¸é¼å±ä»åååæå»ºå符串ãè¿ç§æ¹æ³æ§è½è¾å·®ï¼å ä¸ºææ¬å¿ é¡»ä¸æå°åç¼å²åºæ«å°¾ç§»å¨ã
ä¸è¿ï¼éè¿ä»ååå追å å°çæ®µæ¥æå»ºå符串æ¯é«æçãStringçè¡ä¸ºä¸åé类似ï¼å½éè¦æ´å¤å®¹éæ¶ï¼å
¶ç¼å²åºå¤§å°æ»æ¯è³å°ç¿»åãè¿ä½¿å¾éæ°å¤å¶çå¼é䏿ç»å¤§å°ææ¯ä¾ãå³ä¾¿å¦æ¤ï¼ä½¿ç¨String::with_capacityä»ä¸å¼å§å°±å建å
·æåéç¼å²åºå¤§å°çå符串ï¼å¯ä»¥å®å
¨é¿å
è°æ´å¤§å°ï¼å¹¶ä¸å¯ä»¥åå°å¯¹å åé
å¨çè°ç¨æ¬¡æ°ã
# å é¤åæ¿æ¢ææ¬
Stringæä¸äºç¨äºå 餿æ¬çæ¹æ³ï¼è¿äºæ¹æ³ä¸ä¼å½±åå符串ç容éï¼å¦æä½ éè¦éæ¾å
åï¼å¯ä»¥ä½¿ç¨shrink_to_fitï¼ï¼
string.clear()ï¼å°stringé置为空å符串ãstring.truncate(n)ï¼ä¸¢å¼åèåç§»énä¹åçææå符ï¼ä½¿stringçé¿åº¦æå¤ä¸ºnã妿stringçé¿åº¦å°äºnåèï¼åæ¤æä½æ æãstring.pop()ï¼å¦æstringææåä¸ä¸ªå符ï¼åå°å ¶å é¤å¹¶ä½ä¸ºOption<char>è¿åãstring.remove(i)ï¼ä»stringä¸å é¤åèåç§»éiå¤çå符并è¿åå®ï¼å°åé¢çå符ååç§»å¨ãè¿ä¸æ¥çæ¶é´å¤æåº¦ä¸åé¢åç¬¦çæ°éæçº¿æ§å ³ç³»ãstring.drain(range)ï¼è¿åç»å®åèç´¢å¼èå´çè¿ä»£å¨ï¼å½è¿ä»£å¨è¢«ä¸¢å¼æ¶ï¼ä¼å é¤è¿äºå符ãèå´ä¹åçå符ä¼ååç§»å¨ï¼
let mut choco = "chocolate".to_string();
assert_eq!(choco.drain(3..6).collect::<String>(), "col");
assert_eq!(choco, "choate");
2
3
å¦æä½ åªæ³å é¤è¯¥èå´ï¼å¯ä»¥ç«å³ä¸¢å¼è¿ä»£å¨ï¼èæ éä»ä¸æåä»»ä½é¡¹ï¼
let mut winston = "Churchill".to_string();
winston.drain(2..6);
assert_eq!(winston, "Chill");
2
3
string.replace_range(range, replacement)ï¼ç¨ç»å®çæ¿æ¢å符串åçæ¿æ¢stringä¸çç»å®èå´ãåççé¿åº¦ä¸ä¸å®ä¸è¢«æ¿æ¢çèå´ç¸åï¼ä½é¤éè¢«æ¿æ¢çèå´ä¸ç´å°stringçæ«å°¾ï¼å¦åè¿å°éè¦ç§»å¨è¯¥èå´ä¹åçææåèï¼
let mut beverage = "a piña colada".to_string();
beverage.replace_range(2..7, "kahlua"); // 'ñ' å 两个åèï¼
assert_eq!(beverage, "a kahlua colada");
2
3
# æç´¢åè¿ä»£ç约å®
Rustæ ååºä¸ç¨äºæç´¢ææ¬åè¿ä»£ææ¬ç彿°éµå¾ªä¸äºå½å约å®ï¼ä»¥ä¾¿äºè®°å¿ï¼
- rï¼å¤§å¤æ°æä½ä»ææ¬çå¼å¤´å°ç»å°¾è¿è¡å¤çï¼ä½å称以
rå¼å¤´çæä½åä»ç»å°¾å°å¼å¤´å¤çãä¾å¦ï¼rsplitæ¯splitä»åååå¤çççæ¬ãå¨æäºæ åµä¸ï¼æ¹åæ¹åä¸ä» ä¼å½±åçæå¼ç顺åºï¼è¿ä¼å½±å弿¬èº«ãå¾17-3ä¸ç示ä¾å±ç¤ºäºè¿ç§æ åµã - nï¼å称以
nç»å°¾çè¿ä»£å¨å°èªèº«éå¶ä¸ºç»å®æ°éçå¹é 项ã - _indicesï¼å称以
_indicesç»å°¾çè¿ä»£å¨ï¼é¤äºçææ£å¸¸çè¿ä»£å¼å¤ï¼è¿ä¼çæå®ä»¬å¨åçä¸åºç°çåèåç§»éã
æ ååºå¹¶æ²¡æä¸ºæ¯ä¸ªæä½æä¾ææå¯è½çç»åãä¾å¦ï¼è®¸å¤æä½ä¸éè¦nåä½ï¼å 为æåç»æè¿ä»£å°±è¶³å¤ç®åäºã
# æç´¢ææ¬ç模å¼
彿 ååºå½æ°éè¦æç´¢ãå¹é ãæåæä¿®åªææ¬æ¶ï¼å®æ¥åå ç§ä¸åçç±»åæ¥è¡¨ç¤ºè¦æ¥æ¾çå 容ï¼
let haystack = "One fine day, in the middle of the night";
assert_eq!(haystack.find(','), Some(12));
assert_eq!(haystack.find("night"), Some(35));
assert_eq!(haystack.find(char::is_whitespace), Some(3));
2
3
4
è¿äºç±»å被称为模å¼ï¼å¤§å¤æ°æä½é½æ¯æå®ä»¬ï¼
assert_eq!("## Elephants"
.trim_start_matches(|ch: char| ch == '#' || ch.is_whitespace()),
"Elephants");
2
3
æ ååºæ¯æåç§ä¸»è¦ç模å¼ç±»åï¼
- ä¸ä¸ª
charç±»åçæ¨¡å¼å¹é 该å符ã - ä¸ä¸ª
Stringã&stræ&&strç±»åçæ¨¡å¼å¹é ä¸è¯¥æ¨¡å¼ç¸ççåå符串ã - ä¸ä¸ª
FnMut(char) -> boolç±»åçéå ä½ä¸ºæ¨¡å¼ï¼å¹é éå è¿åtrueçå个å符ã - ä¸ä¸ª
&[char]ç±»åçæ¨¡å¼ï¼ä¸æ¯&strï¼èæ¯charå¼çåçï¼å¹é å表ä¸åºç°çä»»ä½å个å符ã请注æï¼å¦æä½ å°å表å为æ°ç»åé¢éï¼å¯è½éè¦è°ç¨as_ref()æ¥ç¡®ä¿ç±»åæ£ç¡®ï¼
let code = "\t function noodle() { ";
assert_eq!(code.trim_start_matches([' ', '\t'].as_ref()), "function noodle() { ");
// æ´ç®çççæåæ³ï¼&[' ', '\t'][..]
2
3
å¦åï¼Rustä¼å¯¹åºå®å¤§å°çæ°ç»ç±»å&[char; 2]æå°å°æï¼éæ¾çæ¯å®ä¸æ¯ä¸ç§æ¨¡å¼ç±»åã
卿 ååºèªèº«ç代ç ä¸ï¼æ¨¡å¼æ¯ä»»ä½å®ç°äºstd::str::Patternç¹æ§çç±»åãPatternçç»èç®åè¿ä¸ç¨³å®ï¼æä»¥å¨ç¨³å®ççRustä¸ï¼ä½ ä¸è½ä¸ºèªå·±çç±»åå®ç°å®ï¼ä½è¿ä¸ºå°æ¥æ¯ææ£å表达å¼åå
¶ä»å¤ææ¨¡å¼æå¼äºå¤§é¨ãRustä¿è¯ç°å¨æ¯æç模å¼ç±»å卿ªæ¥ä»ç¶å¯ç¨ã
# æç´¢åæ¿æ¢
Rustæä¸äºæ¹æ³ç¨äºå¨åçä¸æç´¢æ¨¡å¼ï¼å¹¶å¯è½ç¨æ°ææ¬æ¿æ¢å®ä»¬ï¼
slice.contains(pattern)ï¼å¦æsliceä¸å å«ä¸patternå¹é çå 容ï¼åè¿åtrueãslice.starts_with(pattern)ãslice.ends_with(pattern)ï¼å¦æsliceçèµ·å§æç»å°¾ææ¬ä¸patternå¹é ï¼åè¿åtrueï¼
assert!("2017".starts_with(char::is_numeric));
slice.find(pattern)ãslice.rfind(pattern)ï¼å¦æsliceä¸å å«ä¸patternå¹é çå 容ï¼åè¿åSome(i)ï¼å ¶ä¸iæ¯æ¨¡å¼åºç°çåèåç§»éãfindæ¹æ³è¿å第ä¸ä¸ªå¹é 项ï¼rfindè¿åæåä¸ä¸ªï¼
let quip = "We also know there are known unknowns";
assert_eq!(quip.find("know"), Some(8));
assert_eq!(quip.rfind("know"), Some(31));
assert_eq!(quip.find("ya know"), None);
assert_eq!(quip.rfind(char::is_uppercase), Some(0));
2
3
4
5
slice.replace(pattern, replacement)ï¼è¿åä¸ä¸ªæ°çStringï¼éè¿ç«å³ç¨replacementæ¿æ¢patternçææå¹é 项æ¥å½¢æï¼
assert_eq!("The only thing we have to fear is fear itself"
.replace("fear", "spin"),
"The only thing we have to spin is spin itself");
assert_eq!("`Borrow` and `BorrowMut`"
.replace(|ch: char|!ch.is_alphanumeric(), ""),
"BorrowandBorrowMut");
2
3
4
5
6
ç±äºæ¿æ¢æ¯ç«å³è¿è¡çï¼.replace()å¨å¤çéå å¹é
æ¶çè¡ä¸ºå¯è½ä¼è®©äººæå¤ãè¿éæå个"aba"模å¼çå®ä¾ï¼ä½å¨æ¿æ¢äºç¬¬ä¸ä¸ªå第ä¸ä¸ªä¹åï¼ç¬¬äºä¸ªå第å个就ä¸åå¹é
äºï¼
assert_eq!("cabababababbage"
.replace("aba", "***"),
"c***b***babbage")
2
3
slice.replacen(pattern, replacement, n)ï¼ä¸replaceæ¹æ³ç±»ä¼¼ï¼ä½æå¤åªæ¿æ¢ån个å¹é 项ã
# è¿ä»£ææ¬
æ ååºæä¾äºå ç§è¿ä»£åçææ¬çæ¹å¼ãå¾17-3å±ç¤ºäºä¸äºç¤ºä¾ã
ä½ å¯ä»¥å°splitåmatchç³»åæ¹æ³è§ä¸ºå½¼æ¤çè¡¥å
ï¼splitå¾å°çæ¯å¹é
项ä¹é´çèå´ã
å¾17-3. è¿ä»£åççä¸äºæ¹å¼
è¿äºæ¹æ³ä¸ç大夿°è¿åçè¿ä»£å¨æ¯å¯å转çï¼ä¹å°±æ¯è¯´ï¼å®ä»¬å®ç°äºDoubleEndedIteratorï¼ï¼è°ç¨å®ä»¬ç.rev()éé
卿¹æ³ï¼ä½ ä¼å¾å°ä¸ä¸ªçæç¸å项ä½é¡ºåºç¸åçè¿ä»£å¨ã
slice.chars()ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼ç¨äºéåsliceä¸çå符ãslice.char_indices()ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼éåsliceä¸çå符åå ¶åèåç§»éï¼
assert_eq!("élan".char_indices().collect::<Vec<_>>(),
vec![(0, 'é'), // æä¸ä¸ªä¸¤åèçUTF - 8ç¼ç
(2, 'l'),
(3, 'a'),
(4, 'n')]);
2
3
4
5
注æï¼è¿ä¸.chars().enumerate()å¹¶ä¸çæï¼å ä¸ºå®æä¾çæ¯æ¯ä¸ªå符å¨åçä¸çåèåç§»éï¼èä¸ä»
ä»
æ¯å¯¹å符è¿è¡ç¼å·ã
slice.bytes()ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼éåsliceä¸çå个åèï¼å±ç¤ºUTF - 8ç¼ç ï¼
assert_eq!("élan".bytes().collect::<Vec<_>>(),
vec![195, 169, b'l', b'a', b'n']);
2
slice.lines()ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼éåsliceä¸çè¡ãè¡ä»¥"\n"æ"\r\n"ç»å°¾ãçæçæ¯ä¸ªé¡¹é½æ¯ä»sliceåç¨ç&strãè¿äºé¡¹ä¸å æ¬è¡çç»æ¢å符ãslice.split(pattern)ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼éåsliceä¸ç±patternå¹é 项åéçé¨åãå¨ç´§é»çå¹é 项ä¹é´ï¼ä»¥ååçå¼å¤´åç»å°¾çå¹é 项å¤ï¼ä¼çæç©ºå符串ã妿patternæ¯&strç±»åï¼è¿åçè¿ä»£å¨æ¯ä¸å¯å转çãè¿ç§æ¨¡å¼æ ¹æ®æ«ææ¹åçä¸åï¼å¯è½ä¼äº§çä¸åçå¹é åºåï¼èå¯å转è¿ä»£å¨ä¸å è®¸è¿æ ·åãç¸åï¼ä½ å¯ä»¥ä½¿ç¨æ¥ä¸æ¥è¦ä»ç»çrsplitæ¹æ³ãslice.rsplit(pattern)ï¼æ¤æ¹æ³ä¸split类似ï¼ä½ä»sliceçæ«å°¾å¼å§æ«æï¼ææ¤é¡ºåºçæå¹é 项ãslice.split_terminator(pattern)ãslice.rsplit_terminator(pattern)ï¼è¿ä¸¤ä¸ªæ¹æ³ä¸splitårsplit类似ï¼ä¸åä¹å¤å¨äºpattern被è§ä¸ºç»æ¢ç¬¦ï¼è䏿¯åé符ï¼å¦æpatternå¨sliceçæ«å°¾å¹é ï¼è¿ä»£å¨ä¸ä¼åsplitårsplit飿 ·çæä¸ä¸ªè¡¨ç¤ºè¯¥å¹é 项ä¸åçæ«å°¾ä¹é´ç©ºå符串ç空åçãä¾å¦ï¼
// è¿éç':'å符æ¯åéç¬¦ãæ³¨ææåç""ã
assert_eq!("jimb:1000:Jim Blandy:".split(':').collect::<Vec<_>>(),
vec!["jimb", "1000", "Jim Blandy", ""]);
// è¿éç'\n'å符æ¯ç»æ¢ç¬¦ã
assert_eq!("127.0.0.1 localhost\n127.0.0.1 www.reddit.com\n"
.split_terminator('\n').collect::<Vec<_>>(),
vec!["127.0.0.1 localhost", "127.0.0.1 www.reddit.com"]);
// 注æï¼æ²¡ææåç""ï¼
2
3
4
5
6
7
8
slice.splitn(n, pattern)ãslice.rsplitn(n, pattern)ï¼è¿ä¸¤ä¸ªæ¹æ³ä¸splitårsplit类似ï¼åªæ¯å®ä»¬å°å符串æå¤å岿n个åçï¼å¨patternçån - 1个æån - 1个å¹é 项å¤è¿è¡åå²ãslice.split_whitespace()ãslice.split_ascii_whitespace()ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼éåsliceä¸ç±ç©ºç½å符åéçé¨åãå¤ä¸ªè¿ç»ç空ç½å符被è§ä¸ºå个åé符ãå°¾éç空ç½å符å°è¢«å¿½ç¥ãsplit_whitespaceæ¹æ³ä½¿ç¨charç±»åçis_whitespaceæ¹æ³å®ç°çUnicode空ç½å符å®ä¹ãsplit_ascii_whitespaceæ¹æ³å使ç¨char::is_ascii_whitespaceï¼å®åªè¯å«ASCII空ç½å符ã
let poem = "This is just to say\nI have eaten\n the plums\nagain\n ";
assert_eq!(poem.split_whitespace().collect::<Vec<_>>(),
vec!["This", "is", "just", "to", "say", "I", "have", "eaten", "the", "plums", "again"]);
2
3
slice.matches(pattern)ï¼è¿åä¸ä¸ªè¿ä»£å¨ï¼éåsliceä¸ä¸patternå¹é çå 容ãslice.rmatches(pattern)ä¸ä¹ç¸åï¼ä½ä»æ«å°¾å¼å§è¿ä»£ãslice.match_indices(pattern)ãslice.rmatch_indices(pattern)ï¼è¿ä¸¤ä¸ªæ¹æ³ä¸matches类似ï¼ä¸åä¹å¤å¨äºçæç项æ¯(offset, match)对ï¼å ¶ä¸offsetæ¯å¹é å¼å§çåèåç§»éï¼matchæ¯å¹é çåçã
# ä¿®åª
ä¿®åªå符串æçæ¯ä»å符串çå¼å¤´æç»å°¾å 餿æ¬ï¼é常å é¤çæ¯ç©ºç½å符ã卿¸ ç仿件ä¸è¯»åçè¾å ¥æ¶ï¼è¿ä¸ªæä½å¾æç¨ï¼å ä¸ºç¨æ·å¯è½ä¸ºäºä¾¿äºé 读è缩è¿äºææ¬ï¼æè ä¸å°å¿å¨ä¸è¡çæ«å°¾çä¸äºå°¾éç空ç½å符ã
slice.trim()ï¼è¿åsliceçä¸ä¸ªååçï¼è¯¥ååçä¼çç¥ææå导åå°¾éç空ç½å符ãslice.trim_start()ä» çç¥å导空ç½å符ï¼slice.trim_end()ä» çç¥å°¾é空ç½å符ï¼
assert_eq!("\t* .rs ".trim(), "* .rs");
assert_eq!("\t* .rs ".trim_start(), "* .rs ");
assert_eq!("\t* .rs ".trim_end(), "\t* .rs");
2
3
slice.trim_matches(pattern)ï¼è¿åsliceçä¸ä¸ªååçï¼è¯¥ååçä¼çç¥å¼å¤´åç»å°¾ææä¸patternå¹é çå 容ãtrim_start_matchesåtrim_end_matchesæ¹æ³åå«ä» 对å导æå°¾éçå¹é 项æ§è¡ç¸åæä½ï¼
assert_eq!("001990".trim_start_matches('0'), "1990");
# å符串ç大å°å转æ¢
slice.to_uppercase()åslice.to_lowercase()æ¹æ³ä¼è¿åä¸ä¸ªæ°åé
çå符串ï¼å
¶ä¸å
å«slice转æ¢ä¸ºå¤§åæå°ååçææ¬ãç»æçé¿åº¦å¯è½ä¸sliceä¸åï¼è¯¦ç»ä¿¡æ¯è¯·åè§ âå符ç大å°å转æ¢âã
# ä»å符串解æå ¶ä»ç±»å
Rust为ä»å符串解æå¼ä»¥åçæå¼çææ¬è¡¨ç¤ºæä¾äºæ åç¹æ§ã
妿ä¸ä¸ªç±»åå®ç°äºstd::str::FromStrç¹æ§ï¼é£ä¹å®å°±æä¾äºä¸ç§ä»å符串åçè§£æå¼çæ åæ¹å¼ï¼
pub trait FromStr: Sized {
type Err;
fn from_str(s: &str) -> Result<Self, Self::Err>;
}
2
3
4
ææå¸¸è§çåºæ¬ç±»åé½å®ç°äºFromStrï¼
use std::str::FromStr;
assert_eq!(usize::from_str("3628800"), Ok(3628800));
assert_eq!(f64::from_str("128.5625"), Ok(128.5625));
assert_eq!(bool::from_str("true"), Ok(true));
assert!(f64::from_str("not a float at all").is_err());
assert!(bool::from_str("TRUE").is_err());
2
3
4
5
6
charç±»åä¹ä¸ºåªæä¸ä¸ªå符çå符串å®ç°äºFromStrï¼
assert_eq!(char::from_str("é"), Ok('é'));
assert!(char::from_str("abcdefg").is_err());
2
std::net::IpAddrç±»åï¼ä¸ä¸ªè¡¨ç¤ºIPv4æIPv6äºèç½å°åçæä¸¾ï¼ä¹å®ç°äºFromStrï¼
use std::net::IpAddr;
let address =
IpAddr::from_str("fe80::0000:3ea9:f4ff:fe34:7a50")?;
assert_eq!(address,
IpAddr::from([0xfe80, 0, 0, 0, 0x3ea9, 0xf4ff, 0xfe34, 0x7a50]));
2
3
4
5
å符串åçæä¸ä¸ªparseæ¹æ³ï¼å®å¯ä»¥å°åçè§£æä¸ºä½ æ³è¦çä»»ä½ç±»åï¼åææ¯è¯¥ç±»åå®ç°äºFromStrãä¸Iterator::collectç±»ä¼¼ï¼ææ¶ä½ éè¦æç¡®æå®æ³è¦çç±»åï¼æä»¥parse并䏿»æ¯æ¯ç´æ¥è°ç¨from_stræ´æè¯»ï¼
let address = "fe80::0000:3ea9:f4ff:fe34:7a50".parse::<IpAddr>()?;
# å°å ¶ä»ç±»å转æ¢ä¸ºå符串
å°éææ¬å¼è½¬æ¢ä¸ºåç¬¦ä¸²ä¸»è¦æä¸ç§æ¹å¼ï¼
- å
·æèªç¶ç人类å¯è¯»æå°å½¢å¼çç±»åå¯ä»¥å®ç°
std::fmt::Displayç¹æ§ï¼è¿ä½¿ä½ è½å¤å¨format!å®ä¸ä½¿ç¨{}æ ¼å¼è¯´æç¬¦ï¼
assert_eq!(format!("{}, wow", "doge"), "doge, wow");
assert_eq!(format!("{}", true), "true");
assert_eq!(format!("({:.3}, {:.3})", 0.5, f64::sqrt(3.0) / 2.0),
"(0.500, 0.866)");
// 使ç¨ä¸é¢å®ä¹çaddress
let formatted_addr: String = format!("{}", address);
assert_eq!(formatted_addr, "fe80::3ea9:f4ff:fe34:7a50");
2
3
4
5
6
7
Rustçææåºæ¬æ°å¼ç±»åé½å®ç°äºDisplayï¼å符ãå符串ååç乿¯å¦æ¤ãæºè½æéç±»åBox<T>ãRc<T>åArc<T>妿Tæ¬èº«å®ç°äºDisplayï¼å®ä»¬ä¹ä¼å®ç°Displayï¼å®ä»¬çæ¾ç¤ºå½¢å¼å°±æ¯å
¶å¼ç¨å¯¹è±¡çæ¾ç¤ºå½¢å¼ãåVecåHashMapè¿æ ·ç容卿²¡æå®ç°Displayï¼å 为è¿äºç±»å没æåä¸çèªç¶äººç±»å¯è¯»å½¢å¼ã
- 妿ä¸ä¸ªç±»åå®ç°äº
Displayï¼æ ååºä¼èªå¨ä¸ºå®å®ç°std::str::ToStringç¹æ§ï¼å½ä½ ä¸éè¦format!ççµæ´»æ§æ¶ï¼å ¶å¯ä¸çæ¹æ³to_string伿´æ¹ä¾¿ï¼
// æ¥ç»ä¸é¢ç代ç
assert_eq!(address.to_string(),
"fe80::3ea9:f4ff:fe34:7a50");
2
3
ToStringç¹æ§å¨Displayç¹æ§ä¹åå¼å
¥ï¼çµæ´»æ§è¾å·®ã对äºä½ èªå·±çç±»åï¼é常åºè¯¥å®ç°Displayè䏿¯ToStringã
- æ ååºä¸çæ¯ä¸ªå
Œ
±ç±»åé½å®ç°äº
std::fmt::Debugï¼å®æ¥åä¸ä¸ªå¼å¹¶å°å ¶æ ¼å¼å为对ç¨åºåæå¸®å©çå符串ã使ç¨Debugçæå符串æç®åçæ¹æ³æ¯éè¿format!å®ç{:?}æ ¼å¼è¯´æç¬¦ï¼
// æ¥ç»ä¸é¢ç代ç
let addresses = vec![address,
IpAddr::from_str("192.168.0.1")?];
assert_eq!(format!("{:?}", addresses),
"[fe80::3ea9:f4ff:fe34:7a50, 192.168.0.1]");
2
3
4
5
è¿å©ç¨äºå¯¹ä»»ä½å®ç°äºDebugçTï¼Vec<T>çéç¨Debugå®ç°ãRustçææéåç±»åé½æè¿æ ·çå®ç°ã
ä½ ä¹åºè¯¥ä¸ºèªå·±çç±»åå®ç°Debugãé常æå¥½è®©Rustæ´¾çä¸ä¸ªå®ç°ï¼å°±åæä»¬å¨ç¬¬12ç« ä¸ºComplexç±»åæåç飿 ·ï¼
#[derive(Copy, Clone, Debug)]
struct Complex {
re: f64,
im: f64
}
2
3
4
5
DisplayåDebugæ ¼å¼åç¹æ§åªæ¯format!å®åå
¶ç¸å
³å®ç¨äºå°å¼æ ¼å¼åä¸ºææ¬çå ä¸ªç¹æ§ä¸ç两个ãæä»¬å°å¨ âæ ¼å¼åå¼â ä¸ä»ç»å
¶ä»ç¹æ§ï¼å¹¶è§£éå¦ä½å®ç°å®ä»¬ã
# åç¨ä¸ºå ¶ä»ç±»ä¼¼ææ¬çç±»å
ä½ å¯ä»¥éè¿å ç§ä¸åçæ¹å¼åç¨åççå 容ï¼
- åçåå符串å®ç°äº
AsRef<str>ãAsRef<[u8]>ãAsRef<Path>åAsRef<OsStr>ãè®¸å¤æ ååºå½æ°ä½¿ç¨è¿äºç¹æ§ä½ä¸ºå ¶åæ°ç±»åçéå®ï¼æä»¥ä½ å¯ä»¥ç´æ¥å°åçååç¬¦ä¸²ä¼ éç»å®ä»¬ï¼å³ä½¿å®ä»¬çæ£éè¦çæ¯å ¶ä»ç±»åãæ´å¤è¯¦ç»è§£é请åè§ âAsRefåAsMutâã - åçåå符串è¿å®ç°äº
std::borrow::Borrow<str>ç¹æ§ãHashMapåBTreeMap使ç¨Borrowç¹æ§ï¼ä½¿Stringè½å¤å¾å¥½å°ä½ä¸ºè¡¨ä¸çé®ã详ç»ä¿¡æ¯è¯·åè§ âBorrowåBorrowMutâã
# 以UTF-8å½¢å¼è®¿é®ææ¬
æ ¹æ®ä½ æ¯æ³è·åææ¬åèçæææè¿æ¯ä» åç¨å®ä»¬ï¼æä¸¤ç§ä¸»è¦æ¹å¼æ¥è®¿é®è¡¨ç¤ºææ¬çåèï¼
slice.as_bytes()ï¼ä»¥&[u8]çå½¢å¼åç¨sliceçåèãç±äºè¿ä¸æ¯å¯åå¼ç¨ï¼sliceå¯ä»¥åå®å ¶åèå°å§ç»ä¿ææ ¼å¼è¯å¥½çUTF-8ç¼ç ãstring.into_bytes()ï¼è·åstringçæææï¼å¹¶æå¼è¿åä¸ä¸ªå å«è¯¥å符串åèçVec<u8>ãè¿æ¯ä¸ç§ä½ææ¬ç转æ¢ï¼å 为å®åªæ¯å°å符串ä¸ç´ç¨ä½ç¼å²åºçVec<u8>移交åºå»ãç±äºstringä¸ååå¨ï¼è¿äºåèä¹å°±æ éç»§ç»ä¿ææ ¼å¼è¯å¥½çUTF-8ç¼ç ï¼è°ç¨è å¯ä»¥éæä¿®æ¹Vec<u8>ã
# ä»UTF-8æ°æ®çæææ¬
å¦æä½ æä¸æ®µä½ 认为å
å«UTF-8æ°æ®çåèï¼æ ¹æ®ä½ å¤çéè¯¯çæ¹å¼ï¼æå ç§å°å
¶è½¬æ¢ä¸ºStringæåççæ¹æ³ï¼
str::from_utf8(byte_slice)ï¼æ¥åä¸ä¸ª&[u8]åèåçå¹¶è¿åä¸ä¸ªResultï¼å¦æbyte_sliceå 嫿 ¼å¼è¯å¥½çUTF-8ç¼ç ï¼åè¿åOk(&str)ï¼å¦åè¿åé误ãString::from_utf8(vec)ï¼å°è¯ä»æå¼ä¼ éçVec<u8>æé ä¸ä¸ªå符串ã妿vecä¸ä¿åçæ¯æ ¼å¼è¯å¥½çUTF-8ç¼ç ï¼from_utf8ä¼è¿åOk(string)ï¼å ¶ä¸stringè·åäºvecçæææå¹¶å°å ¶ç¨ä½èªèº«çç¼å²åºãè¿ä¸ªè¿ç¨ä¸ä¼è¿è¡å åé æææ¬å¤å¶ã妿åè䏿¯ææçUTF-8ç¼ç ï¼æ¤æ¹æ³è¿åErr(e)ï¼å ¶ä¸eæ¯FromUtf8Erroré误å¼ãè°ç¨e.into_bytes()ä¼å°åå§åévecè¿åç»ä½ ï¼æä»¥å¨è½¬æ¢å¤±è´¥æ¶ï¼åéä¸ä¼ä¸¢å¤±ï¼
let good_utf8: Vec<u8> = vec![0xe9, 0x8c, 0x86];
assert_eq!(String::from_utf8(good_utf8).ok(), Some("é".to_string()));
let bad_utf8: Vec<u8> = vec![0x9f, 0xf0, 0xa6, 0x80];
let result = String::from_utf8(bad_utf8);
assert!(result.is_err());
// ç±äºString::from_utf8失败ï¼å®æ²¡ææ¶èåå§åéï¼å¹¶ä¸é误å¼å°å
¶å®å¥½æ æå°è¿åç»æä»¬ã
assert_eq!(result.unwrap_err().into_bytes(), vec![0x9f, 0xf0, 0xa6, 0x80]);
2
3
4
5
6
7
8
String::from_utf8_lossy(byte_slice)ï¼å°è¯ä»&[u8]å ±äº«åèåçæé ä¸ä¸ªStringæ&strãè¿ç§è½¬æ¢æ»æ¯ä¼æåï¼å®ä¼ç¨Unicodeæ¿æ¢åç¬¦æ¿æ¢ä»»ä½æ ¼å¼é误çUTF-8ç¼ç é¨åãè¿å弿¯ä¸ä¸ªCow<str>ï¼å¦æbyte_sliceå 嫿 ¼å¼è¯å¥½çUTF-8ç¼ç ï¼å®ä¼ç´æ¥åç¨byte_sliceä¸ç&strï¼å¦åï¼å®ä¼æ¥æä¸ä¸ªæ°åé çStringï¼å ¶ä¸æ ¼å¼é误çåèå·²è¢«æ¿æ¢å符å代ãå æ¤ï¼å½byte_sliceæ ¼å¼è¯å¥½æ¶ï¼ä¸ä¼è¿è¡å åé æå¤å¶ãæä»¬å°å¨ âæ¨è¿åé â 䏿´è¯¦ç»å°è®¨è®ºCow<str>ãString::from_utf8_uncheckedï¼å¦æä½ ç¡®å®ä½ çVec<u8>å 嫿 ¼å¼è¯å¥½çUTF-8ç¼ç ï¼é£ä¹ä½ å¯ä»¥è°ç¨è¿ä¸ªä¸å®å ¨å½æ°ãå®åªæ¯å°Vec<u8>å è£ æä¸ä¸ªStringå¹¶è¿åï¼æ ¹æ¬ä¸ä¼æ£æ¥åèãä½ éè¦ç¡®ä¿æ²¡æå°æ ¼å¼é误çUTF-8å¼å ¥ç³»ç»ï¼è¿å°±æ¯ä¸ºä»ä¹è¿ä¸ªå½æ°è¢«æ 记为ä¸å®å ¨çåå ãstr::from_utf8_uncheckedï¼ç±»ä¼¼å°ï¼è¿ä¸ªå½æ°æ¥åä¸ä¸ª&[u8]å¹¶å°å ¶ä½ä¸º&strè¿åï¼è䏿£æ¥å®æ¯å¦å 嫿 ¼å¼è¯å¥½çUTF-8ç¼ç ãä¸String::from_utf8_unchecked䏿 ·ï¼ä½ è¦è´è´£ç¡®ä¿è¿æ ·åæ¯å®å ¨çã
# æ¨è¿åé
åè®¾ä½ å¸æç¨åºåç¨æ·ææå¼ãå¨Unixç³»ç»ä¸ï¼ä½ å¯ä»¥è¿æ ·åï¼
fn get_name() -> String {
std::env::var("USER") // Windows使ç¨"USERNAME"
.unwrap_or("whoever you are".to_string())
}
println!("Greetings, {}!", get_name());
2
3
4
5
6
对äºUnixç¨æ·ï¼è¿ä¼ç¨ä»ä»¬çç¨æ·ååä»ä»¬ææå¼ã对äºWindowsç¨æ·å没æè®¾ç½®ç¨æ·åçç¨æ·ï¼å®ä¼æä¾å¤ç¨çéç¨ææ¬ã
std::env::var彿°è¿åä¸ä¸ªStringï¼å¹¶ä¸æå
åççç±è¿æ ·åï¼æä»¬å¨æ¤ä¸æ·±å
¥è®¨è®ºï¼ãä½è¿æå³çå¤ç¨çéç¨ææ¬ä¹å¿
é¡»ä½ä¸ºStringè¿åãè¿æç¹ä»¤äººå¤±æï¼å½get_nameè¿åä¸ä¸ªéæå符串æ¶ï¼æ ¹æ¬ä¸éè¦è¿è¡åé
ã
é®é¢çå
³é®å¨äºï¼ææ¶get_nameçè¿åå¼åºè¯¥æ¯ä¸ä¸ªæ¥ææææçStringï¼ææ¶åºè¯¥æ¯ä¸ä¸ª&'static strï¼èå¨è¿è¡ç¨åºä¹åæä»¬æ æ³ç¥é伿¯åªä¸ç§ãè¿ç§å¨æç¹æ§æç¤ºæä»¬å¯ä»¥èè使ç¨std::borrow::Cowï¼å³åæ¶å¤å¶ç±»åï¼å®å¯ä»¥æææ¥ææææçæ°æ®æåç¨çæ°æ®ã
æ£å¦å¨ âåç¨åToOwnedçåºç¨ï¼ä¸èµ·ç¼çCowâ ä¸æè§£éçï¼Cow<'a, T>æ¯ä¸ä¸ªæä¸¾ï¼æä¸¤ä¸ªåä½ï¼OwnedåBorrowedãBorrowedææä¸ä¸ªå¼ç¨&'a Tï¼Ownedææ&Tçæ¥ææææççæ¬ï¼å¯¹äº&stræ¯Stringï¼å¯¹äº&[i32]æ¯Vec<i32>ï¼ä¾æ¤ç±»æ¨ãæ 论Cow<'a, T>æ¯Ownedè¿æ¯Borrowedï¼å®æ»æ¯å¯ä»¥ä¸ºä½ æä¾ä¸ä¸ª&T以ä¾ä½¿ç¨ãå®é
ä¸ï¼Cow<'a, T>å¯ä»¥è§£å¼ç¨ä¸º&Tï¼å
¶è¡ä¸ºç±»ä¼¼äºä¸ç§æºè½æéã
å°get_nameä¿®æ¹ä¸ºè¿åä¸ä¸ªCowï¼ä»£ç å¦ä¸ï¼
use std::borrow::Cow;
fn get_name() -> Cow<'static, str> {
std::env::var("USER")
.map(|v| Cow::Owned(v))
.unwrap_or(Cow::Borrowed("whoever you are"))
}
2
3
4
5
6
7
妿æå读åäº"USER"ç¯å¢åéï¼mapä¼å°å¾å°çStringä½ä¸ºCow::Ownedè¿åãå¦æè¯»å失败ï¼unwrap_orä¼å°å
¶éæç&strä½ä¸ºCow::Borrowedè¿åãè°ç¨è
å¯ä»¥ä¿æä¸åï¼
println!("Greetings, {}!", get_name());
åªè¦Tå®ç°äºstd::fmt::Displayç¹æ§ï¼æ¾ç¤ºCow<'a, T>䏿¾ç¤ºTä¼äº§çç¸åçç»æã
å½ä½ å¯è½éè¦ä¹å¯è½ä¸éè¦ä¿®æ¹åç¨çæäºææ¬æ¶ï¼Cowä¹å¾æç¨ãå½ä¸éè¦ä¿®æ¹æ¶ï¼ä½ å¯ä»¥ç»§ç»åç¨å®ã使¯Cowçåæ¶å¤å¶è¡ä¸ºå¯ä»¥æ ¹æ®éè¦ä¸ºä½ æä¾å¼çæ¥ææææçå¯å坿¬ãCowçto_mutæ¹æ³ä¼ç¡®ä¿Cowæ¯Cow::Ownedï¼å¿
è¦æ¶åºç¨å¼çToOwnedå®ç°ï¼ç¶åè¿å对该å¼çå¯åå¼ç¨ã
æä»¥ï¼å¦æä½ åç°é¨åç¨æ·ï¼ä½ä¸æ¯ææç¨æ·ï¼æä»ä»¬å¸æè¢«ç§°å¼ç头è¡ï¼ä½ å¯ä»¥è¿æ ·åï¼
fn get_title() -> Option<&'static str> { ... }
let mut name = get_name();
if let Some(title) = get_title() {
name.to_mut().push_str(", ");
name.to_mut().push_str(title);
}
println!("Greetings, {}!", name);
2
3
4
5
6
7
8
è¿å¯è½ä¼äº§çå¦ä¸è¾åºï¼
$ cargo run
Greetings, jimb, Esq.!
$
2
3
è¿éç好夿¯ï¼å¦æget_name()è¿åä¸ä¸ªéæå符串ä¸get_titleè¿åNoneï¼Cowä¼ç´æ¥å°éæåç¬¦ä¸²ä¼ éç»println!ãä½ æåå°æ¨è¿äºåé
ï¼ç´å°çæ£æå¿
è¦æ¶æè¿è¡ï¼åæ¶ä»£ç ä»ç¶å¾ç®æ´ã
ç±äºCowç»å¸¸ç¨äºåç¬¦ä¸²ï¼æ ååºå¯¹Cow<'a, str>æä¸äºç¹æ®æ¯æã宿ä¾äºä»Stringå&strçFromåInto转æ¢ï¼æä»¥ä½ å¯ä»¥æ´ç®æ´å°ç¼åget_nameï¼
fn get_name() -> Cow<'static, str> {
std::env::var("USER")
.map(|v| v.into())
.unwrap_or("whoever you are".into())
}
2
3
4
5
Cow<'a, str>ä¹å®ç°äºstd::ops::Addåstd::ops::AddAssignï¼æä»¥è¦ç»ååæ·»å 头è¡ï¼ä½ å¯ä»¥è¿æ ·åï¼
if let Some(title) = get_title() {
name += ", ";
name += title;
}
2
3
4
æè
ï¼ç±äºStringå¯ä»¥ä½ä¸ºwrite!å®çç®æ ï¼
use std::fmt::Write;
if let Some(title) = get_title() {
write!(name.to_mut(), ", {}", title).unwrap();
}
2
3
4
åä¹å䏿 ·ï¼å¨å°è¯ä¿®æ¹Cowä¹åä¸ä¼è¿è¡åé
ã
请记ä½ï¼å¹¶éæ¯ä¸ªCow<..., str>é½å¿
é¡»æ¯'staticçï¼ä½ å¯ä»¥ä½¿ç¨Cowåç¨ä¹å计ç®å¥½çææ¬ï¼ç´å°éè¦å¤å¶çé£ä¸å»ã
# å符串ä½ä¸ºéç¨éå
Stringå®ç°äºstd::default::Defaultåstd::iter::Extendï¼defaultè¿åä¸ä¸ªç©ºå符串ï¼extendå¯ä»¥å°å符ãå符串åçãCow<..., str>æå符串追å å°åç¬¦ä¸²çæ«å°¾ãè¿ä¸Rustçå
¶ä»éåç±»åï¼å¦VecåHashMapï¼ä¸ºéç¨æé æ¨¡å¼ï¼å¦collectåpartitionï¼å®ç°çç¹æ§ç»åç¸åã
&strç±»åä¹å®ç°äºDefaultï¼è¿åä¸ä¸ªç©ºåçãè¿å¨ä¸äºç¹æ®æ
åµä¸å¾æç¨ï¼ä¾å¦ï¼å®å
è®¸ä½ ä¸ºå
å«å符串åççç»æä½æ´¾çDefaultå®ç°ã
# æ ¼å¼åå¼
卿¬ä¹¦ä¸ï¼æä»¬ä¸ç´å¨ä½¿ç¨åprintln!è¿æ ·çææ¬æ ¼å¼åå®ï¼
println!("{:.3}µs: relocated {} at {:#x} to {:#x}, {} bytes",
0.84391, "object",
140737488346304_usize, 6299664_usize, 64);
2
3
ä¸è¿°è°ç¨ä¼äº§çå¦ä¸è¾åºï¼
0.844µs: relocated object at 0x7fffffffdcc0 to 0x602010, 64 bytes
å符串åé¢å¼å
å½è¾åºç模æ¿ï¼æ¨¡æ¿ä¸çæ¯ä¸ª{...}é½ä¼è¢«åé¢åæ°çæ ¼å¼å形弿¿æ¢ã模æ¿å符串å¿
é¡»æ¯å¸¸éï¼è¿æ ·Rustæè½å¨ç¼è¯æ¶æ ¹æ®åæ°çç±»åè¿è¡æ£æ¥ãæ¯ä¸ªåæ°é½å¿
须被使ç¨ï¼å¦åRust伿¥åç¼è¯æ¶é误ã
æ ååºä¸çå 个åè½é½ä½¿ç¨è¿ç§æ ¼å¼åå符串çå°è¯è¨ï¼
format!å®ä½¿ç¨å®æ¥æå»ºStringãprintln!åprint!å®å°æ ¼å¼ååçææ¬åå ¥æ åè¾åºæµãwriteln!åwrite!å®å°å ¶åå ¥æå®çè¾åºæµãpanic!å®ä½¿ç¨å®æ¥æå»ºä¸ä¸ªï¼çæ³æ åµä¸ä¿¡æ¯ä¸°å¯çï¼è¡¨ç¤ºç»æ¢å¼å¸¸ç表达å¼ã
Rustçæ ¼å¼ååè½è®¾è®¡ä¸ºå¼æ¾å¼çãä½ å¯ä»¥éè¿å®ç°std::fmt模åä¸çæ ¼å¼åç¹æ§ï¼æ©å±è¿äºå®ä»¥æ¯æèªå·±çç±»åãä½ è¿å¯ä»¥ä½¿ç¨format_args!å®åstd::fmt::Argumentsç±»åï¼ä½¿èªå·±ç彿°å宿¯æè¿ç§æ ¼å¼åè¯è¨ã
æ ¼å¼å宿»æ¯åç¨åæ°çå ±äº«å¼ç¨ï¼å®ä»¬ä»ä¸è·ååæ°çæææï¼ä¹ä¸ä¼å¯¹å ¶è¿è¡ä¿®æ¹ã
模æ¿ä¸ç{...}å½¢å¼ç§°ä¸ºæ ¼å¼åæ°ï¼å
¶å½¢å¼ä¸º{which:how}ãè¿ä¸¤é¨å齿¯å¯éçï¼{}ä¹ç»å¸¸è¢«ä½¿ç¨ã
whichå¼ç¨äºéæ©æ¨¡æ¿åé¢çåªä¸ªåæ°åºè¯¥å æ®è¯¥åæ°çä½ç½®ãä½ å¯ä»¥éè¿ç´¢å¼æåç§°éæ©åæ°ãæ²¡æwhichå¼çåæ°ä¼ç®åå°ä»å·¦å°å³ä¸åæ°é
对ã
howå¼è¡¨ç¤ºåæ°åºè¯¥å¦ä½æ ¼å¼åï¼æ¯å¦éè¦å¤å°å¡«å
ã精度æ¯å¤å°ã使ç¨åªç§æ°ååºæ°ççã妿åå¨howå¼ï¼åå
¶åé¢çåå·æ¯å¿
éçã表17-4å±ç¤ºäºä¸äºç¤ºä¾ã
表17-4. æ ¼å¼åå符串示ä¾
| 模æ¿å符串 | åæ°å表 | ç»æ |
|---|---|---|
| "number of {}: {}" | "elephants", 19 | "number of elephants: 19" |
| "from {1} to {0}" | "the grave", "the cradle" | "from the cradle to the grave" |
| "v = {:?}" | vec![0,1,2,5,12,29] | "v = [0, 1, 2, 5, 12, 29]" |
| "name = {:?}" | "Nemo" | "name = "Nemo"" |
| "{:8.2} km/s" | 11.186 | " 11.19 km/s" |
| "{:20} {:02x} {:02 x}" | "adc #42", 105, 42 | "adc #42 69 2a" |
| "{1:02x} {2:02x} {0}" | "adc #42", 105, 42 | "69 2a adc #42" |
| "{lsb:02x} {msb:02x} {insn}" | insn="adc #42", lsb=105, msb=42 | "69 2a adc #42" |
| "{:02?}" | [110, 11, 9] | "[110, 11, 09]" |
| "{:02x?}" | [110, 11, 9] | "[6e, 0b, 09]" |
å¦æä½ æ³å¨è¾åºä¸å
å«{æ}å符ï¼å¨æ¨¡æ¿ä¸æè¿äºå符å åå³å¯ï¼
assert_eq!(format!("{{a, c}} â {{a, b, c}}"),
"{a, c} â {a, b, c}");
2
# æ ¼å¼åææ¬å¼
æ ¼å¼åå&stræStringï¼char被å½ä½åå符å符串å¤çï¼è¿æ ·çææ¬ç±»åæ¶ï¼åæ°çhow弿å 个é¨åï¼å为å¯éï¼
- ææ¬é¿åº¦éå¶ï¼å¦æåæ°çé¿åº¦è¶ è¿æ¤éå¶ï¼Rust伿ªæå®ãå¦ææªæå®éå¶ï¼Rustä¼ä½¿ç¨å®æ´çææ¬ã
- æå°å段宽度ï¼å¨è¿è¡ä»»ä½æªæä¹åï¼å¦æåæ°çé¿åº¦å°äºæ¤å®½åº¦ï¼Rustä¼ï¼é»è®¤ï¼å¨å³ä¾§ç¨ï¼é»è®¤çï¼ç©ºæ ¼è¿è¡å¡«å ï¼ä½¿å ¶è¾¾å°è¯¥å段宽度ã妿çç¥æ¤é项ï¼Rustä¸ä¼å¯¹åæ°è¿è¡å¡«å ã
- 坹齿¹å¼ï¼å¦æéè¦å¯¹åæ°è¿è¡å¡«å
以满足æå°åæ®µå®½åº¦ï¼æ¤é项æå®ææ¬åºå¨å段ä¸çä½ç½®ã
<ã^å>åå«å°ææ¬ç½®äºèµ·å§ãä¸é´åæ«å°¾ä½ç½®ã - å¡«å å符ï¼ç¨äºå¡«å è¿ç¨çå符ã妿çç¥ï¼Rust使ç¨ç©ºæ ¼ãå¦æä½ æå®äºå¡«å å符ï¼åè¿å¿ é¡»æå®å¯¹é½æ¹å¼ã
表17-5å±ç¤ºäºä¸äºç¤ºä¾ï¼è¯´æäºå¦ä½ç¼åæ ¼å¼åæä»¤ä»¥åå®ä»¬çææãææç¤ºä¾é½ä½¿ç¨ç¸åçå
«ä¸ªå符çåæ°"bookends"ã
表17-5. ææ¬çæ ¼å¼åå符串æä»¤
| 使ç¨çç¹æ§ | 模æ¿å符串 | ç»æ |
|---|---|---|
| é»è®¤ | {} | "bookends" |
| æå°å段宽度 | {:4} | "bookends" |
{:12} | "bookends " | |
| ææ¬é¿åº¦éå¶ | {:.4} | "book" |
{:.12} | "bookends" | |
| åæ®µå®½åº¦ãé¿åº¦éå¶ | {:12.20} | "bookends " |
{:4.20} | "bookends" | |
{:4.6} | "booken" | |
{:6.4} | "book " | |
| 左对é½ã宽度 | {:<12} | "bookends " |
| å± ä¸ã宽度 | {:^12} | " bookends " |
| å³å¯¹é½ã宽度 | {:>12} | " bookends" |
ç¨=å¡«å
ãå±
ä¸ã宽度 | {:=^12} | "==bookends==" |
ç¨*å¡«å
ãå³å¯¹é½ã宽度ãéå¶ | {:*>12.4} | "********book" |
Rustçæ ¼å¼åå¨å¯¹å®½åº¦ççè§£æ¯è¾ç®åï¼å®å设æ¯ä¸ªå符å ç¨ä¸åï¼ä¸èèç»åå符ãåè§çååãé¶å®½ç©ºæ ¼æUnicodeçå ¶ä»å¤ææ åµãä¾å¦ï¼
assert_eq!(format!("{:4}", "th\u{e9}"), "th\u{e9} ");
assert_eq!(format!("{:4}", "the\u{301}"), "the\u{301}");
2
è½ç¶Unicodeè§å®è¿äºå符串é½çåäºthéï¼ä½Rustçæ ¼å¼åå¨ä¸ç¥éå\u{301}ï¼ç»åå°é³ç¬¦ï¼è¿æ ·çå符éè¦ç¹æ®å¤çãå®å¯¹ç¬¬ä¸ä¸ªå符串çå¡«å
æ¯æ£ç¡®çï¼ä½è®¤ä¸ºç¬¬äºä¸ªå符串宽度为ååï¼å æ¤æ²¡ææ·»å å¡«å
ãè½ç¶å¾å®¹æçåºRustå¨è¿ç§ç¹å®æ
åµä¸å¯ä»¥å¦ä½æ¹è¿ï¼ä½å¯¹ææUnicodeèæ¬è¿è¡çæ£çå¤è¯è¨ææ¬æ ¼å¼åæ¯ä¸é¡¹è°å·¨çä»»å¡ï¼æå¥½ä¾é å¹³å°çç¨æ·çé¢å·¥å
·å
æ¥å¤çï¼æè
çæHTMLåCSSï¼è®©ç½é¡µæµè§å¨æ¥æ´çãæä¸ä¸ªå¾å欢è¿çåºunicode-widthå¯ä»¥å¤çè¿æ¹é¢çä¸äºé®é¢ã
é¤äº&stråStringï¼ä½ è¿å¯ä»¥ç´æ¥å°å
·æææ¬å¼ç¨çæºè½æéç±»åï¼å¦Rc<String>æCow<'a, str>ï¼ä¼ éç»æ ¼å¼åå®ã
ç±äºæä»¶åè·¯å¾ä¸ä¸å®æ¯æ ¼å¼è¯å¥½çUTF-8ï¼std::path::Pathä¸å®å
¨æ¯ææ¬ç±»åï¼ä½ ä¸è½ç´æ¥å°std::path::Pathä¼ éç»æ ¼å¼åå®ãä¸è¿ï¼Pathçdisplayæ¹æ³è¿åçå¼å¯ä»¥è¿è¡æ ¼å¼åï¼å®ä¼ä»¥éåå¹³å°çæ¹å¼å¤çç¸å
³é®é¢ï¼
println!("processing file: {}", path.display());
# æ ¼å¼åæ°å
彿 ¼å¼ååæ°æ¯åusizeæf64è¿æ ·çæ°å¼ç±»åæ¶ï¼åæ°çhow弿以ä¸å 个é¨åï¼å为å¯éï¼
- å¡«å å对é½ï¼ä¸ææ¬ç±»åçå¤çæ¹å¼ç¸åã
+å符ï¼è¦æ±å³ä½¿åæ°ä¸ºæ£æ°ï¼ä¹å§ç»æ¾ç¤ºå ¶ç¬¦å·ã#å符ï¼è¦æ±æ·»å æç¡®çåºæ°åç¼ï¼å¦0xæ0bãè§æ¬å表æåçâ表示æ³â项ã0å符ï¼è¦æ±éè¿å¨æ°ååæ·»å å坼鶿¥æ»¡è¶³æå°å段宽度ï¼è䏿¯ä½¿ç¨é常çå¡«å æ¹å¼ã- æå°å段宽度ï¼å¦ææ ¼å¼ååçæ°å宽度å°äºæ¤å¼ï¼Rustä¼ï¼é»è®¤ï¼å¨å·¦ä¾§ç¨ï¼é»è®¤çï¼ç©ºæ ¼è¿è¡å¡«å ï¼ä½¿å ¶è¾¾å°ç»å®ç宽度ã
- æµ®ç¹ååæ°ç精度ï¼è¡¨ç¤ºRuståºå¨å°æ°ç¹åå å«å¤å°ä½æ°åãRust伿 ¹æ®éè¦è¿è¡åèäºå ¥æè¡¥é¶ï¼ä»¥ç²¾ç¡®çæè¿ä¹å¤å°æ°ä½ãå¯¹äºæ´ååæ°ï¼ç²¾åº¦ä¼è¢«å¿½ç¥ ã
- 表示æ³ï¼å¯¹äºæ´åï¼
b表示äºè¿å¶ï¼oè¡¨ç¤ºå «è¿å¶ï¼xæXåå«è¡¨ç¤ºä½¿ç¨å°åæå¤§å忝çåå è¿å¶ãå¦æä½ å å«äº#å符ï¼è¿äºä¼æ·»å æç¡®çRust飿 ¼çåºæ°åç¼0bã0oã0xæ0Xãå¯¹äºæµ®ç¹åï¼åºæ°eæEè¦æ±ä½¿ç¨ç§å¦è®¡æ°æ³ï¼å¸¦æè§èåçç³»æ°ï¼ç¨eæEè¡¨ç¤ºææ°ãå¦æä½ æªæå®ä»»ä½è¡¨ç¤ºæ³ï¼Rustä¼ä»¥åè¿å¶æ ¼å¼åæ°åã
表17-6å±ç¤ºäºä¸äºæ ¼å¼åi32å¼1234ç示ä¾ã
表17-6. æ´æ°çæ ¼å¼åå符串æä»¤
| 使ç¨çç¹æ§ | 模æ¿å符串 | ç»æ |
|---|---|---|
| é»è®¤ | {} | "1234" |
| å¼ºå¶æ¾ç¤ºç¬¦å· | {:+} | "+1234" |
| æå°å段宽度 | {:12} | " 1234" |
{:2} | "1234" | |
| 符å·ã宽度 | {:+12} | " +1234" |
| å导é¶ã宽度 | {:012} | "000000001234" |
| 符å·ãå导é¶ã宽度 | {:+012} | "+00000001234" |
| 左对é½ã宽度 | {:<12} | "1234 " |
| å± ä¸ã宽度 | {:^12} | " 1234 " |
| å³å¯¹é½ã宽度 | {:>12} | " 1234" |
| 左对é½ã符å·ã宽度 | {:<+12} | "+1234 " |
| å± ä¸ã符å·ã宽度 | {:^+12} | " +1234 " |
| å³å¯¹é½ã符å·ã宽度 | {:>+12} | " +1234" |
ç¨=å¡«å
ãå±
ä¸ã宽度 | {:=^12} | "====1234====" |
| äºè¿å¶è¡¨ç¤ºæ³ | {:b} | "10011010010" |
| 宽度ãå «è¿å¶è¡¨ç¤ºæ³ | {:12o} | " 2322" |
| 符å·ã宽度ãåå è¿å¶è¡¨ç¤ºæ³ | {:+12x} | " +4d2" |
| 符å·ã宽度ã大ååå è¿å¶è¡¨ç¤ºæ³ | {:+12X} | " +4D2" |
| 符å·ãæç¡®çåºæ°åç¼ã宽度ãåå è¿å¶ | {:+#12x} | " +0x4d2" |
| 符å·ãåºæ°ãå导é¶ã宽度ãåå è¿å¶ | {:+#012x} | "+0x0000004d2" |
{:+#06x} | "+0x4d2" |
æå两个示ä¾è¡¨æï¼æå°å段宽度éç¨äºæ´ä¸ªæ°åï¼å æ¬ç¬¦å·ãåºæ°åç¼çãè´æ°æ»æ¯å å«å®ä»¬ç符å·ï¼ç»æä¸âå¼ºå¶æ¾ç¤ºç¬¦å·â示ä¾ä¸ç类似ã
å½ä½ è¦æ±æ·»å å坼鶿¶ï¼å¯¹é½åå¡«å å符ä¼è¢«å¿½ç¥ï¼å 为é¶ä¼æ©å±æ°å以填满æ´ä¸ªå段ã
使ç¨åæ°1234.5678ï¼æä»¬å¯ä»¥å±ç¤ºæµ®ç¹åç¹æçææï¼è¡¨17-7ï¼ã
表17-7. æµ®ç¹æ°çæ ¼å¼åå符串æä»¤
| 使ç¨çç¹æ§ | 模æ¿å符串 | ç»æ |
|---|---|---|
| é»è®¤ | {} | "1234.5678" |
| 精度 | {:.2} | "1234.57" |
{:.6} | "1234.567800" | |
| æå°å段宽度 | {:12} | " 1234.5678" |
| æå°å段宽度ã精度 | {:12.2} | " 1234.57" |
{:12.6} | " 1234.567800" | |
| å导é¶ãæå°å段宽度ã精度 | {:012.6} | "01234.567800" |
| ç§å¦è®¡æ°æ³ | {:e} | "1.2345678e3" |
| ç§å¦è®¡æ°æ³ã精度 | {:.3e} | "1.235e3" |
| ç§å¦è®¡æ°æ³ãæå°å段宽度ã精度 | {:12.3e} | " 1.235e3" |
{:12.3E} | " 1.235E3" |
# æ ¼å¼åå ¶ä»ç±»å
é¤äºåç¬¦ä¸²åæ°åï¼ä½ è¿å¯ä»¥æ ¼å¼åå ¶ä»å ç§æ ååºç±»åï¼
- é误类åé½å¯ä»¥ç´æ¥æ ¼å¼åï¼è¿ä½¿å¾å°å®ä»¬å
å«å¨éè¯¯æ¶æ¯ä¸åå¾å¾å®¹æãæ¯ä¸ªé误类åé½åºè¯¥å®ç°
std::error::Errorç¹æ§ï¼è¯¥ç¹æ§æ©å±äºé»è®¤çæ ¼å¼åç¹æ§std::fmt::Displayãå æ¤ï¼ä»»ä½å®ç°äºErrorçç±»åé½å¯ä»¥ç´æ¥è¿è¡æ ¼å¼åã - ä½ å¯ä»¥æ ¼å¼åç½ç»åè®®å°åç±»åï¼å¦
std::net::IpAddråstd::net::SocketAddrã - å¸å°å¼
trueåfalseä¹å¯ä»¥æ ¼å¼åï¼ä¸è¿é常è¿äºå符串并ä¸éåç´æ¥å±ç¤ºç»ç»ç«¯ç¨æ·ã
ä½ åºè¯¥ä½¿ç¨ä¸æ ¼å¼åå符串æ¶ç¸åçæ ¼å¼åæ°ãé¿åº¦éå¶ãåæ®µå®½åº¦å坹齿§å¶ç工使¹å¼ä¸é¢æä¸è´ã
# 为è°è¯èæ ¼å¼åå¼
为äºå¸®å©è°è¯åè®°å½æ¥å¿ï¼{:?}忰以ä¸ç§å¯¹ç¨åºåæå¸®å©çæ¹å¼æ ¼å¼åRustæ ååºä¸çä»»ä½å
Œ
±ç±»åãä½ å¯ä»¥ä½¿ç¨å®æ¥æ£æ¥åéãåçãå
ç»ãåå¸è¡¨ã线ç¨ä»¥åå
¶ä»æ°ç¾ç§ç±»åã
ä¾å¦ï¼ä½ å¯ä»¥è¿æ ·åï¼
use std::collections::HashMap;
let mut map = HashMap::new();
map.insert("Portland", (45.5237606, -122.6819273));
map.insert("Taipei", (25.0375167, 121.5637));
println!("{:?}", map);
2
3
4
5
6
è¿æ®µä»£ç çè¾åºä¸ºï¼
{"Taipei": (25.0375167, 121.5637), "Portland": (45.5237606, -122.6819273)}
HashMapå(f64, f64)ç±»åå·²ç»ç¥éå¦ä½èªè¡æ ¼å¼åï¼æ éä½ é¢å¤è´¹åã
å¦æä½ å¨æ ¼å¼åæ°ä¸å
å«#å符ï¼Rustä¼å¯¹å¼è¿è¡æ¼äº®æå°ãå°ä¸è¿°ä»£ç æ¹ä¸ºprintln!("{:#?}", map)ï¼ä¼å¾å°å¦ä¸è¾åºï¼
{
"Taipei": (
25.0375167,
121.5637
),
"Portland": (
45.5237606,
-122.6819273
)
}
2
3
4
5
6
7
8
9
10
è¿äºç¡®åçæ ¼å¼å¹¶ä¸ä¿è¯ä¸æä¸åï¼ææ¶ä¼å¨ä¸åçRustçæ¬ä¹é´ææååã
è°è¯æ ¼å¼åé常以åè¿å¶æå°æ°åï¼ä½ä½ å¯ä»¥å¨é®å·åå ä¸xæXæ¥è¦æ±ä»¥åå
è¿å¶æå°ãå导é¶ååæ®µå®½åº¦è¯æ³ä¹åæ ·éç¨ãä¾å¦ï¼ä½ å¯ä»¥è¿æ ·åï¼
println!("ordinary: {:02?}", [9, 15, 240]);
println!("hex: {:02x?}", [9, 15, 240]);
2
è¿æ®µä»£ç çè¾åºä¸ºï¼
ordinary: [09, 15, 240]
hex: [09, 0f, f0]
2
å¦åæè¿°ï¼ä½ å¯ä»¥ä½¿ç¨#[derive(Debug)]è¯æ³ï¼ä½¿ä½ èªå·±çç±»åè½å¤ä¸{:?}ä¸èµ·ä½¿ç¨ï¼
#[derive(Copy, Clone, Debug)]
struct Complex {
re: f64,
im: f64
}
2
3
4
5
æäºè¿ä¸ªå®ä¹åï¼æä»¬å¯ä»¥ä½¿ç¨{:?}æ ¼å¼æ¥æå°Complexå¼ï¼
let third = Complex { re: -0.5, im: f64::sqrt(0.75) };
println!("{:?}", third);
2
è¿æ®µä»£ç çè¾åºä¸ºï¼
Complex { re: -0.5, im: 0.8660254037844386 }
è¿å¯¹äºè°è¯æ¥è¯´å·²ç»è¶³å¤ï¼ä½å¦æ{}è½ä»¥æ´ä¼ ç»ç形弿å°å®ä»¬ï¼æ¯å¦-0.5 + 0.8660254037844386iï¼é£å°±æ´å¥½äºãå¨âæ ¼å¼åä½ èªå·±çç±»åâä¸ï¼æä»¬å°å±ç¤ºå¦ä½å®ç°è¿ä¸ç¹ã
# 为è°è¯èæ ¼å¼åæé
é常æ
åµä¸ï¼å¦æä½ å°ä»»ä½ç±»åçæéï¼å¼ç¨ãBoxãRcçï¼ä¼ éç»æ ¼å¼åå®ï¼å®åªä¼è·éæéå¹¶æ ¼å¼åå
¶å¼ç¨çå¯¹è±¡ï¼æéæ¬èº«å¹¶ä¸åå
³æ³¨ãä½å¨è°è¯æ¶ï¼ææ¶æ¥çæéä¼å¾æå¸®å©ï¼å°åå¯ä»¥ä½ä¸ºå个å¼ç大è´âåç§°âï¼å¨æ£æ¥å
·æå¾ªç¯æå
±äº«çç»ææ¶ï¼è¿å¯è½ä¼å¾æå¯åæ§ã
{:p}表示æ³å°å¼ç¨ãBoxåå
¶ä»ç±»ä¼¼æéçç±»åæ ¼å¼å为å°åï¼
use std::rc::Rc;
let original = Rc::new("mazurka".to_string());
let cloned = original.clone();
let impostor = Rc::new("mazurka".to_string());
println!("text: {}, {}, {}", original, cloned, impostor);
println!("pointers: {:p}, {:p}, {:p}", original, cloned, impostor);
2
3
4
5
6
7
8
è¿æ®µä»£ç çè¾åºä¸ºï¼
text: mazurka, mazurka, mazurka
pointers: 0x7f99af80e000, 0x7f99af80e000, 0x7f99af80e030
2
å½ç¶ï¼æ¯æ¬¡è¿è¡æ¶å
·ä½çæéå¼ä¼ææä¸åï¼ä½å³ä¾¿å¦æ¤ï¼éè¿æ¯è¾å°åå¯ä»¥æ¸
æ¥å°çåºï¼å两个æéå¼ç¨çæ¯åä¸ä¸ªStringï¼è第ä¸ä¸ªæéæåä¸ä¸ªä¸åçå¼ã
å°åçèµ·æ¥å¾å¾åä¸å åå
è¿å¶æ°åï¼æä»¥æ´ç²¾ç»çå¯è§åå¯è½ä¼å¾æç¨ï¼ä½{:p}è¿ç§æ¹å¼ä»ç¶æ¯ä¸ç§ç®åææçå¿«éè§£å³æ¹æ¡ã
# éè¿ç´¢å¼æåç§°å¼ç¨åæ°
æ ¼å¼åæ°å¯ä»¥æ¾å¼éæ©å®ä½¿ç¨çåæ°ãä¾å¦ï¼
assert_eq!(format!("{1},{0},{2}", "zeroth", "first", "second"),
"first,zeroth,second");
2
ä½ å¯ä»¥å¨åå·åå 嫿 ¼å¼åæ°ï¼
assert_eq!(format!("{2:#06x},{1:b},{0:=>10}", "first", 10, 100),
"0x0064,1010,=====first");
2
ä½ è¿å¯ä»¥éè¿åç§°éæ©åæ°ãè¿ä½¿å¾å å«è®¸å¤åæ°çå¤ææ¨¡æ¿æ´æè¯»ãä¾å¦ï¼
assert_eq!(format!("{description:.<25}{quantity:2} @ {price:5.2}",
price = 3.25,
quantity = 3,
description = "Maple Turmeric Latte"),
"Maple Turmeric Latte ..... 3 @ 3.25");
2
3
4
5
ï¼è¿éçå½ååæ°ç±»ä¼¼äºPythonä¸çå ³é®ååæ°ï¼ä½è¿åªæ¯æ ¼å¼åå®çä¸ä¸ªç¹æ®åè½ï¼å¹¶éRust彿°è°ç¨è¯æ³çä¸é¨åãï¼
ä½ å¯ä»¥å¨åä¸ªæ ¼å¼åå®ç使ç¨ä¸æ··å使ç¨ç´¢å¼ãå½ååä½ç½®ï¼å³æ²¡æç´¢å¼æåç§°ï¼åæ°ãä½ç½®åæ°ä¼ä»å·¦å°å³ä¸åæ°é 对ï¼å°±å¥½åç´¢å¼åå½ååæ°ä¸åå¨ä¸æ ·ï¼
assert_eq!(format!("{mode} {2} {} {}",
"people", "eater", "purple", mode = "flying"),
"flying purple people eater");
2
3
å½ååæ°å¿ é¡»åºç°å¨åæ°åè¡¨çæ«å°¾ã
# å¨æå®½åº¦å精度
åæ°çæå°åæ®µå®½åº¦ãææ¬é¿åº¦éå¶åæ°å精度ä¸å¿ æ»æ¯åºå®å¼ï¼ä½ å¯ä»¥å¨è¿è¡æ¶éæ©å®ä»¬ã
æä»¬ä¹åçå°è¿è¿æ ·ç表达å¼ï¼å®å°å符串å 容å¨ä¸ä¸ª20å符宽çåæ®µä¸å³å¯¹é½ï¼
format!("{:>20}", content)
ä½å¦æä½ æ³å¨è¿è¡æ¶éæ©å段宽度ï¼å¯ä»¥è¿æ ·åï¼
format!("{:>1$}", content, get_width())
å°æå°å段宽度åæ1$ï¼è¿åè¯format!使ç¨ç¬¬äºä¸ªåæ°çå¼ä½ä¸ºå®½åº¦ãè¿éå¼ç¨çåæ°å¿
é¡»æ¯usizeç±»åãä½ ä¹å¯ä»¥éè¿åç§°å¼ç¨åæ°ï¼
format!("{:>width$}", content, width = get_width())
åæ ·çæ¹æ³ä¹éç¨äºææ¬é¿åº¦éå¶ï¼
format!("{:>width$.limit$}", content,
width = get_width(), limit = get_limit())
2
ä½ è¿å¯ä»¥ç¨*ä»£æ¿ææ¬é¿åº¦éå¶ææµ®ç¹ç²¾åº¦ï¼è¿è¡¨ç¤ºå°ä¸ä¸ä¸ªä½ç½®åæ°ä½ä¸ºç²¾åº¦ãä¸é¢ç代ç å°contentæå¤è£åªä¸ºget_limit()个å符ï¼
format!("{:.*}", get_limit(), content)
ç¨ä½ç²¾åº¦çåæ°å¿
é¡»æ¯usizeç±»åãç®å没æå¯¹åºå段宽度çç±»ä¼¼è¯æ³ã
# æ ¼å¼åä½ èªå·±çç±»å
æ ¼å¼åå®ä½¿ç¨std::fmt模åä¸å®ä¹çä¸ç»ç¹æ§å°å¼è½¬æ¢ä¸ºææ¬ãä½ å¯ä»¥éè¿èªå·±å®ç°è¿äºç¹æ§ä¸çä¸ä¸ªæå¤ä¸ªï¼è®©Rustçæ ¼å¼åå®è½å¤æ ¼å¼åä½ èªå·±çç±»åã
æ ¼å¼åæ°ç表示æ³è¡¨æäºå ¶åæ°ç±»åå¿ é¡»å®ç°çç¹æ§ï¼å¦è¡¨17-8æç¤ºã 表17-8. æ ¼å¼åå符串æä»¤è¡¨ç¤ºæ³
| è¡¨ç¤ºæ³ | ç¤ºä¾ | ç¹æ§ | ç®ç |
|---|---|---|---|
| æ | {} | std::fmt::Display | ææ¬ãæ°åãé误ï¼éç¨ç¹æ§ |
b | {bits:#b} | std::fmt::Bin | 以äºè¿å¶è¡¨ç¤ºæ°å |
o | {:#5o} | std::fmt::Oct | ä»¥å «è¿å¶è¡¨ç¤ºæ°å |
x | {:4x} | std::fmt::LowerHex | 以åå è¿å¶è¡¨ç¤ºæ°åï¼å°å忝 |
X | {:016X} | std::fmt::UpperHex | 以åå è¿å¶è¡¨ç¤ºæ°åï¼å¤§å忝 |
e | {:.3e} | std::fmt::LowerExp | 以ç§å¦è®¡æ°æ³è¡¨ç¤ºæµ®ç¹æ° |
E | {:.3E} | std::fmt::UpperExp | 以ç§å¦è®¡æ°æ³è¡¨ç¤ºæµ®ç¹æ°ï¼å¤§åE |
? | {:#?} | std::fmt::Debug | ç¨äºå¼åè è°è¯çè§å¾ |
p | {:p} | std::fmt::Pointer | å°æéæ ¼å¼å为å°åï¼ç¨äºå¼åè |
å½ä½ å¨ç±»åå®ä¹ä¸ä½¿ç¨#[derive(Debug)]屿§ï¼ä»¥ä¾¿è½å¤ä½¿ç¨{:?}æ ¼å¼åæ°æ¶ï¼ä½ å®é
䏿¯è®©Rustä¸ºä½ å®ç°std::fmt::Debugç¹æ§ã
æææ ¼å¼åç¹æ§é½å
·æç¸åçç»æï¼ä»
åç§°ä¸åãæä»¬ä»¥std::fmt::Display为ä¾ï¼
trait Display {
fn fmt(&self, dest: &mut std::fmt::Formatter) -> std::fmt::Result;
}
2
3
fmtæ¹æ³ç任塿¯çæselfçæ£ç¡®æ ¼å¼å表示ï¼å¹¶å°å
¶å符åå
¥destãé¤äºä½ä¸ºè¾åºæµä¹å¤ï¼deståæ°è¿å
å«ä»æ ¼å¼åæ°è§£æåºç详ç»ä¿¡æ¯ï¼å¦å¯¹é½æ¹å¼åæå°å段宽度ã
ä¾å¦ï¼å¨æ¬ç« å颿们æå°ï¼å¦æComplexå¼è½ä»¥é常ça + bi形弿å°ä¼æ´å¥½ãä¸é¢æ¯ä¸ä¸ªå®ç°æ¤åè½çDisplayå®ç°ï¼
use std::fmt;
impl fmt::Display for Complex {
fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
let im_sign = if self.im < 0.0 { '-' } else { '+' };
write!(dest, "{} {} {}i", self.re, im_sign, f64::abs(self.im))
}
}
2
3
4
5
6
7
8
è¿éå©ç¨äºFormatteræ¬èº«å°±æ¯ä¸ä¸ªè¾åºæµçäºå®ï¼æä»¥write!å®å¯ä»¥ä¸ºæä»¬å®æå¤§é¨åå·¥ä½ãæäºè¿ä¸ªå®ç°åï¼æä»¬å¯ä»¥è¿æ ·åï¼
let one_twenty = Complex { re: -0.5, im: 0.866 };
assert_eq!(format!("{}", one_twenty), "-0.5 + 0.866i");
let two_forty = Complex { re: -0.5, im: -0.866 };
assert_eq!(format!("{}", two_forty), "-0.5 - 0.866i");
2
3
4
5
ææ¶ä»¥æåæ 形弿¾ç¤ºå¤æ°ä¼å¾æå¸®å©ï¼æ³è±¡å¨å¤å¹³é¢ä¸ä»åç¹å°è¯¥å¤æ°ç»ä¸æ¡çº¿ï¼æåæ å½¢å¼ç»åºè¿æ¡çº¿çé¿åº¦ä»¥åå®ä¸æ£x轴顺æ¶éæ¹åç夹è§ãæ ¼å¼åæ°ä¸ç#å符é常ç¨äºéæ©æç§æ¿ä»£æ¾ç¤ºå½¢å¼ï¼Displayå®ç°å¯ä»¥å°å
¶è§ä¸ºä½¿ç¨æåæ å½¢å¼ç请æ±ï¼
impl fmt::Display for Complex {
fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
let (re, im) = (self.re, self.im);
if dest.alternate() {
let abs = f64::sqrt(re * re + im * im);
let angle = f64::atan2(im, re) / std::f64::consts::PI * 180.0;
write!(dest, "{} â {}°", abs, angle)
} else {
let im_sign = if im < 0.0 { '-' } else { '+' };
write!(dest, "{} {} {}i", re, im_sign, f64::abs(im))
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
使ç¨è¿ä¸ªå®ç°ï¼
let ninety = Complex { re: 0.0, im: 2.0 };
assert_eq!(format!("{}", ninety), "0 + 2i");
assert_eq!(format!("{:#}", ninety), "2 â 90°");
2
3
è½ç¶æ ¼å¼åç¹æ§çfmtæ¹æ³è¿åä¸ä¸ªfmt::Resultå¼ï¼ä¸ç§ç¹å®äºæ¨¡åçResultç±»åï¼ï¼ä½ä½ åºè¯¥åªä¼ æFormatteræä½ä¸çé误ï¼å°±åfmt::Displayå®ç°ä¸è°ç¨write!æ¶é£æ ·ï¼ä½ çæ ¼å¼å彿°æ¬èº«ç»ä¸è½äº§çé误ãè¿ä½¿å¾åformat!è¿æ ·çå®å¯ä»¥ç´æ¥è¿åä¸ä¸ªStringï¼è䏿¯Result<String, ...>ï¼å ä¸ºå°æ ¼å¼ååçææ¬è¿½å å°String䏿°¸è¿ä¸ä¼å¤±è´¥ãè¿ä¹ç¡®ä¿äºä½ ä»write!æwriteln!å¾å°çä»»ä½é误é½åæ äºåºå±I/Oæµçå®é
é®é¢ï¼è䏿¯æ ¼å¼åé®é¢ã
Formatterè¿æè®¸å¤å
¶ä»æç¨çæ¹æ³ï¼å
æ¬ä¸äºç¨äºå¤çåæ å°ãå表çç»æåæ°æ®çæ¹æ³ï¼è¿éæä»¬ä¸åä»ç»ï¼ä½ å¯ä»¥æ¥é
å¨çº¿ææ¡£è·å宿´è¯¦ç»ä¿¡æ¯ã
# å¨èªå·±ç代ç ä¸ä½¿ç¨æ ¼å¼åè¯è¨
ä½ å¯ä»¥éè¿ä½¿ç¨Rustçformat_args!å®åstd::fmt::Argumentsç±»åï¼ç¼åèªå·±ç彿°å宿¥æ¥åæ ¼å¼æ¨¡æ¿ååæ°ãä¾å¦ï¼åè®¾ä½ çç¨åºå¨è¿è¡æ¶éè¦è®°å½ç¶ææ¶æ¯ï¼å¹¶ä¸ä½ å¸æä½¿ç¨Rustçææ¬æ ¼å¼åè¯è¨æ¥çæè¿äºæ¶æ¯ã以䏿¯ä¸ä¸ªç®åç示ä¾ï¼
fn logging_enabled() -> bool { ... }
use std::fs::OpenOptions;
use std::io::Write;
fn write_log_entry(entry: std::fmt::Arguments) {
if logging_enabled() {
// ç®åå
ç®åå¤çï¼æ¯æ¬¡é½æå¼æä»¶
let mut log_file = OpenOptions::new()
.append(true)
.create(true)
.open("log-file-name")
.expect("failed to open log file");
log_file.write_fmt(entry)
.expect("failed to write to log");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ä½ å¯ä»¥è¿æ ·è°ç¨write_log_entryï¼
write_log_entry(format_args!("Hark! {:?}\n ", mysterious_value));
å¨ç¼è¯æ¶ï¼format_args!å®ä¼è§£ææ¨¡æ¿å符串ï¼å¹¶æ ¹æ®åæ°çç±»åè¿è¡æ£æ¥ï¼å¦ææä»»ä½é®é¢ä¼æ¥åé误ãå¨è¿è¡æ¶ï¼å®ä¼è®¡ç®åæ°çå¼ï¼å¹¶æå»ºä¸ä¸ªArgumentså¼ï¼å
¶ä¸å
嫿 ¼å¼åææ¬æéçææä¿¡æ¯ï¼æ¨¡æ¿çé¢è§£æå½¢å¼ï¼ä»¥å坹忰å¼çå
±äº«å¼ç¨ã
æå»ºä¸ä¸ªArgumentså¼çææ¬å¾ä½ï¼å®åªæ¯æ¶éä¸äºæéãæ¤æ¶è¿ä¸ä¼è¿è¡æ ¼å¼åå·¥ä½ï¼åªæ¯æ¶éåç»æ ¼å¼åæéçä¿¡æ¯ãè¿ä¸ç¹å¾éè¦ï¼å¦ææªå¯ç¨æ¥å¿è®°å½ï¼é£ä¹å°æ°å转æ¢ä¸ºåè¿å¶ãå¡«å
å¼çæä½æè±è´¹çæ¶é´é½å°è¢«æµªè´¹ã
Fileç±»åå®ç°äºstd::io::Writeç¹æ§ï¼å
¶write_fmtæ¹æ³æ¥åä¸ä¸ªArgumentå¹¶è¿è¡æ ¼å¼åï¼ç¶åå°ç»æåå
¥åºå±æµãä¸é¢è°ç¨write_log_entryç代ç çèµ·æ¥ä¸å¤ªç¾è§ï¼è¿æ¶å®å°±å¯ä»¥åæ¥ä½ç¨äºï¼
macro_rules! log { // å¨å®å®ä¹ä¸ï¼åç§°åä¸éè¦!
($format:tt, $($arg:expr),*) => (
write_log_entry(format_args!($format, $($arg),*))
)
}
2
3
4
5
æä»¬å°å¨ç¬¬21ç« è¯¦ç»ä»ç»å®ãç®åï¼ä½ åªéç¸ä¿¡è¿ä¸ªå®ä¹äºä¸ä¸ªæ°çlog!å®ï¼å®ä¼å°åæ°ä¼ éç»format_args!ï¼ç¶å对çæçArgumentså¼è°ç¨ä½ çwrite_log_entry彿°ãåprintln!ãwriteln!åformat!è¿æ ·çæ ¼å¼åå®ï¼åç大è´ç¸åã
ä½ å¯ä»¥è¿æ ·ä½¿ç¨log!ï¼
log!("O day and night, but this is wondrous strange! {:?}\n ", mysterious_value);
è¿æ ·çèµ·æ¥ä¼æ´å¥½ä¸äºã
# æ£å表达å¼
å¤é¨çregexåºæ¯Rust宿¹çæ£å表达å¼åºã宿ä¾äºå¸¸è§çæç´¢åå¹é
彿°ï¼å¯¹Unicodeæå¾å¥½çæ¯æï¼åæ¶ä¹å¯ä»¥æç´¢åèå符串ãè½ç¶å®ä¸æ¯æå
¶ä»æ£å表达å¼å
ä¸å¸¸è§çä¸äºç¹æ§ï¼å¦ååå¼ç¨åç¯è§æ¨¡å¼ï¼ä½è¿äºç®å使å¾regexåºè½å¤ç¡®ä¿æç´¢æ¶é´ä¸è¡¨è¾¾å¼ç大å°ä»¥å被æç´¢ææ¬çé¿åº¦å线æ§å
³ç³»ãè¿äºä¿è¯ï¼ä»¥åå
¶ä»ç¹æ§ï¼ä½¿å¾å³ä½¿å¨ä½¿ç¨ä¸å¯ä¿¡çè¡¨è¾¾å¼æç´¢ä¸å¯ä¿¡çææ¬æ¶ï¼regexåºä¹æ¯å®å
¨å¯ç¨çã
卿¬ä¹¦ä¸ï¼æä»¬åªå¯¹regexåºè¿è¡æ¦è¿°ï¼å
·ä½ç»èä½ åºè¯¥æ¥é
å
¶å¨çº¿ææ¡£ã
è½ç¶regexåºä¸å¨æ ååºstdä¸ï¼ä½å®ç±è´è´£stdçRuståºå¢éç»´æ¤ãè¦ä½¿ç¨regexåºï¼å¨ä½ çCargo.tomlæä»¶ç[dependencies]é¨åæ·»å 以ä¸å
容ï¼
regex = "1"
卿¥ä¸æ¥çå 容ä¸ï¼æä»¬åè®¾ä½ å·²ç»å®æäºä¸è¿°ä¿®æ¹ã
# æ£å表达å¼çåºæ¬ç¨æ³
Regexå¼è¡¨ç¤ºä¸ä¸ªå·²è§£æå¥½ãå¯ä½¿ç¨çæ£å表达å¼ãRegex::newæé 彿°å°è¯å°&strè§£æä¸ºæ£å表达å¼ï¼å¹¶è¿åä¸ä¸ªResultï¼
use regex::Regex;
// è¯ä¹åçæ¬å·ï¼å¦0.2.1ã
// å¯è½å
å«é¢åå¸çæ¬åç¼ï¼å¦0.2.1-alphaã
// ï¼ä¸ºç®æ´èµ·è§ï¼ä¸å
å«æå»ºå
æ°æ®åç¼ãï¼
//
// 注æä½¿ç¨r"... "åå§åç¬¦ä¸²è¯æ³ï¼ä»¥é¿å
åææ 带æ¥ç麻ç¦ã
let semver = Regex::new(r"(\d+)\.(\d+)\.(\d+)(-[-.[[:alnum:]]*)?")?;
// ç®åæç´¢ï¼è¿åå¸å°ç»æã
let haystack = r#"regex = "0.2.5""#;
assert!(semver.is_match(haystack));
2
3
4
5
6
7
8
9
10
Regex::capturesæ¹æ³å¨åç¬¦ä¸²ä¸æç´¢ç¬¬ä¸ä¸ªå¹é
项ï¼å¹¶è¿åä¸ä¸ªregex::Captureså¼ï¼è¯¥å¼ä¿åäºè¡¨è¾¾å¼ä¸æ¯ä¸ªç»çå¹é
ä¿¡æ¯ï¼
// ä½ å¯ä»¥è·åæè·ç»
let captures = semver.captures(haystack)
.ok_or("semver regex should have matched")?;
assert_eq!(&captures[0], "0.2.5");
assert_eq!(&captures[1], "0");
assert_eq!(&captures[2], "2");
assert_eq!(&captures[3], "5");
2
3
4
5
6
7
å¦æè¯·æ±çç»æªå¹é
ï¼å¯¹Captureså¼è¿è¡ç´¢å¼ä¼å¯¼è´ç¨åºææ
ï¼panicï¼ãè¦æµè¯ç¹å®çç»æ¯å¦å¹é
ï¼å¯ä»¥è°ç¨Captures::getï¼å®ä¼è¿åä¸ä¸ªOption<regex::Match>ãMatchå¼è®°å½äºå个ç»çå¹é
æ
åµï¼
assert_eq!(captures.get(4), None);
assert_eq!(captures.get(3).unwrap().start(), 13);
assert_eq!(captures.get(3).unwrap().end(), 14);
assert_eq!(captures.get(3).unwrap().as_str(), "5");
2
3
4
ä½ å¯ä»¥è¿ä»£å符串ä¸çææå¹é 项ï¼
let haystack = "In the beginning, there was 1.0.0. \
For a while, we used 1.0.1-beta, \
but in the end, we settled on 1.2.4.";
let matches: Vec<&str> = semver.find_iter(haystack)
.map(|match_| match_.as_str())
.collect();
assert_eq!(matches, vec!["1.0.0", "1.0.1-beta", "1.2.4"]);
2
3
4
5
6
7
find_iterè¿ä»£å¨ä¼ä»å符串å¼å¤´å°ç»å°¾ï¼ä¸ºè¡¨è¾¾å¼çæ¯ä¸ªä¸éå å¹é
项çæä¸ä¸ªMatchå¼ãcaptures_iteræ¹æ³ç±»ä¼¼ï¼ä½ä¼çæè®°å½æææè·ç»çCaptureså¼ãå½éè¦æ¥åæè·ç»æ¶ï¼æç´¢é度ä¼åæ
¢ï¼æä»¥å¦æä½ ä¸éè¦æè·ç»ï¼æå¥½ä½¿ç¨ä¸è¿åå®ä»¬çæ¹æ³ä¹ä¸ã
# å»¶è¿æå»ºæ£å表达å¼å¼
Regex::newæé 彿°å¯è½å¼éè¾å¤§ï¼å¨å¿«éçå¼åæºå¨ä¸ï¼æå»ºä¸ä¸ª1200åç¬¦çæ£å表达å¼å¯è½éè¦è¿ä¸æ¯«ç§ï¼å³ä½¿æ¯ç®åç表达å¼ä¹éè¦å å¾®ç§ãæå¥½é¿å
å¨ç¹éç计ç®å¾ªç¯ä¸æå»ºRegexï¼ç¸åï¼ä½ åºè¯¥åªæå»ºä¸æ¬¡Regexï¼ç¶åéå¤ä½¿ç¨å®ã
lazy_staticåºæä¾äºä¸ç§å¾å¥½çæ¹å¼æ¥å»¶è¿åå§åéæå¼ï¼å¨å®ä»¬ç¬¬ä¸æ¬¡è¢«ä½¿ç¨æ¶æè¿è¡æå»ºãé¦å
ï¼å¨ä½ çCargo.tomlæä»¶ä¸æ·»å ä¾èµï¼
[dependencies]
lazy_static = "1"
2
è¿ä¸ªåºæä¾äºä¸ä¸ªå®æ¥å£°æè¿æ ·çåéï¼
use lazy_static::lazy_static;
lazy_static! {
static ref SEMVER: Regex = Regex::new(r"(\d+)\.(\d+)\.(\d+)(-[-.[[:alnum:]]*)?")
.expect("error parsing regex");
}
2
3
4
5
6
è¿ä¸ªå®å±å¼åä¼å£°æä¸ä¸ªå为SEMVERçéæåéï¼ä½å
¶ç±»åå¹¶ä¸å®å
¨æ¯Regexãå®é
ä¸ï¼å®æ¯ä¸ä¸ªç±å®çæçç±»åï¼å®ç°äºDeref<Target = Regex>ï¼å æ¤å®æ´é²äºä¸Regexç¸åçæææ¹æ³ãå¨ç¬¬ä¸æ¬¡è§£å¼ç¨SEMVERæ¶ï¼ä¼è®¡ç®åå§åå¨çå¼ï¼å¹¶å°ç»æä¿å以ä¾åç»ä½¿ç¨ãç±äºSEMVERæ¯ä¸ä¸ªéæåéï¼èä¸ä»
ä»
æ¯å±é¨åéï¼æä»¥åå§åå¨å¨ç¨åºæ§è¡æé´æå¤è¿è¡ä¸æ¬¡ ã
æäºè¿ä¸ªå£°æåï¼ä½¿ç¨SEMVERå°±å¾ç®åäºï¼
use std::io::BufRead;
let stdin = std::io::stdin();
for line_result in stdin.lock().lines() {
let line = line_result?;
if let Some(match_) = SEMVER.find(&line) {
println!("{}", match_.as_str());
}
}
2
3
4
5
6
7
8
9
ä½ å¯ä»¥å°lazy_static!å£°ææ¾å¨æ¨¡åä¸ï¼çè³æ¾å¨ä½¿ç¨Regexç彿°å
é¨ï¼å¦æè¿æ ·çä½ç¨åæåéçè¯ãæ£å表达å¼å¨æ¯æ¬¡ç¨åºæ§è¡æ¶ä»ç¶åªä¼è¢«ç¼è¯ä¸æ¬¡ã
# è§èå
大夿°ç¨æ·ä¼è®¤ä¸ºæ³è¯ä¸âè¶âè¿ä¸ªè¯âthÃ©âæ¯ç±ä¸ä¸ªåç¬¦ç»æçãç¶èï¼Unicodeå®é 䏿䏤ç§è¡¨ç¤ºè¿ä¸ªææ¬çæ¹å¼ï¼
- å¨ç»åå½¢å¼ä¸ï¼âthéâç±ä¸ä¸ªå符âtâãâhâåâéâç»æï¼å ¶ä¸âÃ©âæ¯ä¸ä¸ªUnicodeå符ï¼ç ç¹ä¸º0xe9ã
- å¨å解形å¼ä¸ï¼âthéâç±å个å符âtâãâhâãâeâåâ\u{301}âç»æï¼è¿éçâeâæ¯æ®éçASCIIåç¬¦ï¼æ²¡æéé³ï¼èç ç¹0x301æ¯âç»åå°é³ç¬¦âå符ï¼å®ä¼ç»è·éå ¶åçä»»ä½å符添å ä¸ä¸ªå°é³ç¬¦ã
Unicodeå¹¶ä¸è®¤ä¸ºâéâçç»å形弿å解形å¼åªä¸ä¸ªæ¯âæ£ç¡®âçï¼èæ¯è®¤ä¸ºå®ä»¬é½æ¯åä¸ä¸ªæ½è±¡å符ççæè¡¨ç¤ºãUnicodeè§å®è¿ä¸¤ç§å½¢å¼é½åºä»¥ç¸åçæ¹å¼æ¾ç¤ºï¼å¹¶ä¸ææ¬è¾å
¥æ¹æ³å¯ä»¥çæä»»æä¸ç§å½¢å¼ï¼æä»¥ç¨æ·é常ä¸ä¼ç¥éä»ä»¬çå°æè¾å
¥çæ¯åªç§å½¢å¼ãï¼Rustå
è®¸ä½ å¨å符串åé¢éä¸ç´æ¥ä½¿ç¨Unicodeåç¬¦ï¼æä»¥å¦æä½ ä¸å
³å¿å¾å°åªç§ç¼ç ï¼ä½ å¯ä»¥ç´æ¥åâthéâãè¿éä¸ºäºæ¸
æ°èµ·è§ï¼æä»¬ä½¿ç¨\u转ä¹ãï¼
ç¶èï¼ä½ä¸ºRustç&stræStringå¼ï¼"th\u{e9}"å"the\u{301}"æ¯å®å
¨ä¸åçãå®ä»¬é¿åº¦ä¸åï¼æ¯è¾ç»æä¸ç¸çï¼åå¸å¼ä¹ä¸åï¼å¹¶ä¸ä¸å
¶ä»å符串æåºæ¶é¡ºåºä¹ä¸åï¼
assert!("th\u{e9}" != "the\u{301}");
assert!("th\u{e9}" > "the\u{301}");
// Hasher设计ç¨äºç´¯ç§¯ä¸ç³»åå¼çåå¸å¼ï¼
// æä»¥åªå¯¹ä¸ä¸ªå¼è¿è¡å叿ç¹éº»ç¦ã
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
fn hash<T: ?Sized + Hash>(t: &T) -> u64 {
let mut s = DefaultHasher::new();
t.hash(&mut s);
s.finish()
}
// è¿äºå¼å¨æªæ¥çRustçæ¬ä¸å¯è½ä¼æ¹åã
assert_eq!(hash("th\u{e9}"), 0x53e2d0734eb1dff3);
assert_eq!(hash("the\u{301}"), 0x90d837f0a0928144);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
æ¾ç¶ï¼å¦æä½ æç®æ¯è¾ç¨æ·æä¾çææ¬ï¼æè å°å ¶ç¨ä½åå¸è¡¨æBæ ä¸çé®ï¼ä½ éè¦é¦å å°æ¯ä¸ªå符串转æ¢ä¸ºæç§è§èå½¢å¼ã
幸è¿çæ¯ï¼Unicode为å符串æå®äºè§èåå½¢å¼ãæ ¹æ®Unicodeçè§åï¼æ¯å½ä¸¤ä¸ªå符串åºè¢«è§ä¸ºçææ¶ï¼å®ä»¬çè§èåå½¢å¼å¨å符å±é¢ä¸æ¯å®å
¨ç¸åçãå½ç¨UTF - 8ç¼ç æ¶ï¼å®ä»¬å¨åèå±é¢ä¸ä¹æ¯å®å
¨ç¸åçãè¿æå³çä½ å¯ä»¥ä½¿ç¨==æ¯è¾è§èååçå符串ï¼å°å®ä»¬ç¨ä½HashMapæHashSetä¸çé®ççï¼å¹¶ä¸ä½ ä¼å¾å°ç¬¦åUnicodeå®ä¹çç¸çæ§å¤æç»æã
ä¸è¿è¡è§èåçè³å¯è½ä¼å¸¦æ¥å®å ¨é®é¢ãä¾å¦ï¼å¦æä½ çç½ç«å¨æäºæ åµä¸å¯¹ç¨æ·åè¿è¡è§èåï¼èå¨å ¶ä»æ åµä¸ä¸è¿è¡ï¼ä½ å¯è½ä¼å¾å°ä¸¤ä¸ªä¸åçç¨æ·ï¼ç¨æ·å齿¯âbananasflambéâï¼ä½ä½ ç代ç çæäºé¨åä¼å°ä»ä»¬è§ä¸ºåä¸ä¸ªç¨æ·ï¼èå ¶ä»é¨åä¼åºåä»ä»¬ï¼ä»è导è´å ¶ä¸ä¸ä¸ªç¨æ·çæé被éè¯¯å°æ©å±å°å¦ä¸ä¸ªç¨æ·ãå½ç¶ï¼æå¾å¤æ¹æ³å¯ä»¥é¿å è¿ç±»é®é¢ï¼ä½åå²è¡¨æï¼ä¹æå¾å¤æ¹æ³ä¼å¯¼è´é®é¢åçã
# è§èåå½¢å¼
Unicodeå®ä¹äºåç§è§èåå½¢å¼ï¼æ¯ç§å½¢å¼é½éç¨äºä¸åçç¨éãæä¸¤ä¸ªé®é¢éè¦èèï¼
- é¦å
ï¼ä½ æ´å¾åäºå符尽å¯è½æ¯ç»åå½¢å¼è¿æ¯å解形å¼ï¼ä¾å¦ï¼è¶åè¯åè¯âPhá»âæç´§åçç»åè¡¨ç¤ºå½¢å¼æ¯ä¸ä¸ªå符çå符串
"Ph\u{1edf}"ï¼å ¶ä¸å£°è°ç¬¦å·âÌâåå é³ç¬¦å·âÌâé½åºç¨äºåºæ¬å符âoâï¼å½¢æä¸ä¸ªUnicodeå符'\u{1edf}'ï¼Unicodeå°å ¶å½å为â带æä¸è§åä¸å¼¯çæä¸å°å忝oâãæåè§£ç表示形å¼å°åºæ¬åæ¯åå ¶ä¸¤ä¸ªç¬¦å·æå为ä¸ä¸ªåç¬çUnicodeå符ï¼âoâãâ\u{31b}âï¼ç»åä¸è§ç¬¦å·ï¼åâ\u{309}âï¼ç»åä¸å¼¯ç¬¦å·ï¼ï¼ç»æä¸ºâPho\u{31b}\u{309}âãï¼æ¯å½ç»å符å·ä½ä¸ºåç¬çå符åºç°ï¼è䏿¯ä½ä¸ºç»åå符çä¸é¨åæ¶ï¼ææè§èåå½¢å¼é½æå®äºå®ä»¬å¿ é¡»åºç°çåºå®é¡ºåºï¼æä»¥å³ä½¿å符æå¤ä¸ªéé³ç¬¦å·ï¼è§èå乿¯æç¡®æå®çãï¼ç»åå½¢å¼éå¸¸å ¼å®¹æ§é®é¢è¾å°ï¼å ä¸ºå®æ´æ¥è¿Unicode建ç«ä¹å大夿°è¯è¨ä½¿ç¨çææ¬è¡¨ç¤ºå½¢å¼ãå®å¯è½ä¹è½æ´å¥½å°ä¸åRustçformat!å®è¿æ ·ç®åçåç¬¦ä¸²æ ¼å¼ååè½é å使ç¨ãå¦ä¸æ¹é¢ï¼å解形å¼å¯è½æ´éåæ¾ç¤ºææ¬ææç´¢ï¼å 为å®ä½¿ææ¬ç详ç»ç»ææ´å æç¡®ã - 第äºä¸ªé®é¢æ¯ï¼å¦æä¸¤ä¸ªå符åºå表示ç¸åçåºæ¬ææ¬ï¼ä½å¨ææ¬æ ¼å¼åæ¹å¼ä¸ææä¸åï¼ä½ æ¯å¸æå°å®ä»¬è§ä¸ºçæè¿æ¯åºåå®ä»¬ï¼Unicode为æ®éæ°åâ5âã䏿 æ°åââµâï¼å³
\u{2075}ï¼å另忰åââ¤âï¼å³\u{2464}ï¼åå«å®ä¹äºå符ï¼ä½å£°æè¿ä¸ä¸ªå符æ¯å ¼å®¹çæçã类似å°ï¼Unicode为è¿åâï¬âï¼\u{fb03}ï¼å®ä¹äºä¸ä¸ªåç¬çå符ï¼ä½å£°æå®ä¸ä¸ä¸ªå符çåºåâffiâæ¯å ¼å®¹çæçãå ¼å®¹æ§çæå¨æç´¢æ¶å¾æç¨ï¼ä½¿ç¨ä» å å«ASCIIå符çâdifficultâè¿è¡æç´¢ï¼åºè¯¥å¹é å å«è¿åâï¬âçå符串âdi\u{fb03}cultâã对åä¸ä¸ªå符串åºç¨å ¼å®¹æ§åè§£ä¼å°è¿åæ¿æ¢ä¸ºä¸ä¸ªæ®é忝âffiâï¼ä½¿æç´¢æ´å®¹æã使¯å°ææ¬è§èåä¸ºå ¼å®¹çæå½¢å¼å¯è½ä¼ä¸¢å¤±éè¦ä¿¡æ¯ï¼æä»¥ä¸åºéæåºç¨ãä¾å¦ï¼å¨å¤§å¤æ°æ åµä¸ï¼å°â2âµâåå¨ä¸ºâ25âæ¯ä¸æ£ç¡®çã
Unicodeè§èåå½¢å¼Cåè§èåå½¢å¼Dï¼NFCåNFDï¼ä½¿ç¨æ¯ä¸ªå符çæå¤§ç»åå½¢å¼åæå¤§å解形å¼ï¼ä½ä¸ä¼å°è¯ç»ä¸å ¼å®¹çæåºåãNFKCåNFKDè§èåå½¢å¼ä¸NFCåNFD类似ï¼ä½ä¼å°ææå ¼å®¹çæåºåè§èå为å®ä»¬æå±ç±»å«çæä¸ªç®å代表形å¼ã
ä¸ç»´ç½èçï¼World Wide Web Consortiumï¼çãä¸ç»´ç½å符模åã建议对ææå 容使ç¨NFCãUnicodeæ è¯ç¬¦å模å¼è¯æ³éå½å»ºè®®å¨ç¼ç¨è¯è¨ä¸å¯¹æ è¯ç¬¦ä½¿ç¨NFKCï¼å¹¶å¨å¿ è¦æ¶æä¾è°æ´å½¢å¼çååã
# unicode-normalization åº
Rustçunicode-normalizationåºæä¾äºä¸ä¸ªç¹æ§ï¼ä¸º&stræ·»å äºæ¹æ³ï¼å¯å°ææ¬è½¬æ¢ä¸ºåç§è§èåå½¢å¼ä¸çä»»æä¸ç§ãè¦ä½¿ç¨å®ï¼å¨ä½ çCargo.tomlæä»¶ç[dependencies]é¨åæ·»å 以ä¸å
容ï¼
unicode-normalization = "0.1.17"
æäºè¿ä¸ªå£°æåï¼&stræåä¸ªæ°æ¹æ³ï¼å®ä»¬ä¼è¿åå符串ç¹å®è§èåå½¢å¼çè¿ä»£å¨ï¼
use unicode_normalization::UnicodeNormalization;
// æ 论左边çå符串使ç¨ä½ç§è¡¨ç¤ºå½¢å¼ï¼ä»
éè¿æ¥çä½ ä¸åºè¯¥è½åè¾¨åºæ¥ï¼ï¼
// è¿äºæè¨é½å°æç«ã
assert_eq!("Phá»"assert_eq!("â Di\u{fb03}culty".nfkc().collect::<String>(), "1
Difficulty");.nfd().collect::<String>(), "Pho\u{31b}\u{309}");
assert_eq!("Phá»".nfc().collect::<String>(), "Ph\u{1edf}");
// è¿é左边çå符串使ç¨äºâffiâè¿åå符ã
assert_eq!("@ Di\u{fb03}culty".nfkc().collect::<String>(), "1 Difficulty");
2
3
4
5
6
7
8
9
10
对ä¸ä¸ªè§èååçåç¬¦ä¸²åæ¬¡ä»¥ç¸åå½¢å¼è¿è¡è§èåï¼ä¿è¯ä¼è¿åç¸åçææ¬ã
è½ç¶è§èåå符串çä»»ä½å串æ¬èº«ä¹æ¯è§èåçï¼ä½ä¸¤ä¸ªè§èåå符串çè¿æ¥ä¸ä¸å®æ¯è§èåçï¼ä¾å¦ï¼ç¬¬äºä¸ªå符串å¯è½ä»¥ç»åå符å¼å¤´ï¼èè¿äºç»åå符åºè¯¥æ¾å¨ç¬¬ä¸ä¸ªå符串æ«å°¾çç»åå符ä¹åã
åªè¦ææ¬å¨è§èåæ¶ä¸ä½¿ç¨æªåé çç ç¹ï¼Unicodeä¿è¯å ¶è§èåå½¢å¼å¨æ åçæªæ¥çæ¬ä¸ä¸ä¼æ¹åãè¿æå³çè§èåå½¢å¼é常å¯ä»¥å®å ¨å°ç¨äºæä¹ åå¨ï¼å³ä½¿Unicodeæ åå¨ä¸æåå±ã