🎃個人專欄:
🐬 算法設計與分析:算法設計與分析_IT閆的博客-CSDN博客
🐳Java基礎:Java基礎_IT閆的博客-CSDN博客
🐋c語言:c語言_IT閆的博客-CSDN博客
🐟MySQL:數據結構_IT閆的博客-CSDN博客
🐠數據結構:??????數據結構_IT閆的博客-CSDN博客
💎C++:C++_IT閆的博客-CSDN博客
🥽C51單片機:C51單片機(STC89C516)_IT閆的博客-CSDN博客
💻基于HTML5的網頁設計及應用:基于HTML5的網頁設計及應用_IT閆的博客-CSDN博客??????
🥏python:python_IT閆的博客-CSDN博客
🐠離散數學:離散數學_IT閆的博客-CSDN博客
??????🥽Linux:????Linux_Y小夜的博客-CSDN博客
🚝Rust:Rust_Y小夜的博客-CSDN博客
歡迎收看,希望對大家有用!
目錄
🎯前言
🎯引入字符串切片
🎯用字符串切片
🎯字符串字面值
🎯前言
????????在引入切片之前,咱們先看一道題,編寫一個函數,該函數接收一個用空格分隔單詞的字符串,并返回在該字符串中找到的第一個單詞。如果函數在該字符串中并未找到空格,則整個字符串就是一個單詞,所以應該返回整個字符串。
可能會有人這樣寫
fn first_word(s: &String) -> usize {let bytes = s.as_bytes();for (i, &item) in bytes.iter().enumerate() {if item == b' ' {return i;}}s.len() }
????????現在有了一個找到字符串中第一個單詞結尾索引的方法,不過這有一個問題。我們返回了一個獨立的?
usize
,不過它只在?&String
?的上下文中才是一個有意義的數字。換句話說,因為它是一個與?String
?相分離的值,無法保證將來它仍然有效。然而,Rust 為這個問題提供了一個解決方法:字符串 slice。
🎯引入字符串切片
String
?中一部分值的引用,它看起來像這樣:let s = String::from("hello world");let hello = &s[0..5];let world = &s[6..11];
????????不同于整個?
String
?的引用,hello
?是一個部分?String
?的引用,由一個額外的?[0..5]
?部分指定。可以使用一個由中括號中的?[starting_index..ending_index]
?指定的 range 創建一個 slice,其中?starting_index
?是 slice 的第一個位置,ending_index
?則是 slice 最后一個位置的后一個值。????????對于 Rust 的?
..
?range 語法,如果想要從索引 0 開始,可以不寫兩個點號之前的值。????????依此類推,如果 slice 包含?
String
?的最后一個字節,也可以舍棄尾部的數字? ? ? ? 提醒:字符串 slice range 的索引必須位于有效的 UTF-8 字符邊界內,如果嘗試從一個多字節字符的中間位置創建字符串 slice,則程序將會因錯誤而退出。
🎯用字符串切片
fn first_word(s: &String) -> &str {let bytes = s.as_bytes();for (i, &item) in bytes.iter().enumerate() {if item == b' ' {return &s[0..i];}}&s[..]
}
????????那個當我們獲取第一個單詞結尾的索引后,接著就清除了字符串導致索引就無效的 bug 嗎?那些代碼在邏輯上是不正確的,但卻沒有顯示任何直接的錯誤。問題會在之后嘗試對空字符串使用第一個單詞的索引時出現。slice 就不可能出現這種 bug 并讓我們更早的知道出問題了 。
Rust 不允許?
clear
?中的可變引用和?word
?中的不可變引用同時存在,因此編譯失敗。
🎯字符串字面值
????????字符串字面值被儲存在二進制文件中。
let s = "Hello, world!";
????????這里?
s
?的類型是?&str
:它是一個指向二進制程序特定位置的 slice。這也就是為什么字符串字面值是不可變的;&str
?是一個不可變引用。字符串切片作為參數傳遞:
????????如果有一個字符串 slice,可以直接傳遞它。如果有一個?
String
,則可以傳遞整個?String
?的 slice 或對?String
?的引用。?????????
String
?引用的函數使得我們的 API 更加通用并且不會丟失任何功能