<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ## 7.6.1 從字符串生成字節切片 假設 s 是一個字符串(本質上是一個字節數組),那么就可以直接通過?`c := []bytes(s)`?來獲取一個字節的切片 c。另外,您還可以通過 copy 函數來達到相同的目的:`copy(dst []byte, src string)`。 同樣的,還可以使用 for-range 來獲得每個元素(Listing 7.13—for_string.go): ~~~ package main import "fmt" func main() { s := "\u00ff\u754c" for i, c := range s { fmt.Printf("%d:%c ", i, c) } } ~~~ 輸出: ~~~ 0:y? 2:界 ~~~ 我們知道,Unicode 字符會占用 2 個字節,有些甚至需要 3 個或者 4 個字節來進行表示。如果發現錯誤的 UTF8 字符,則該字符會被設置為 U+FFFD 并且索引向前移動一個字節。和字符串轉換一樣,您同樣可以使用?`c := []int(s)`?語法,這樣切片中的每個 int 都會包含對應的 Unicode 代碼,因為字符串中的每次字符都會對應一個整數。類似的,您也可以將字符串轉換為元素類型為 rune 的切片:`r := []rune(s)`。 可以通過代碼?`len([]int(s))`?來獲得字符串中字符的數量,但使用?`utf8.RuneCountInString(s)`?效率會更高一點。(參考[count_characters.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/exercises/chapter_4/count_characters.go)) 您還可以將一個字符串追加到某一個字符數組的尾部: ~~~ var b []byte var s string b = append(b, s...) ~~~ ## [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.6.md#762-獲取字符串的某一部分)7.6.2 獲取字符串的某一部分 使用?`substr := str[start:end]`?可以從字符串 str 獲取到從索引 start 開始到?`end-1`?位置的子字符串。同樣的,`str[start:]`?則表示獲取從 start 開始到?`len(str)-1`?位置的子字符串。而?`str[:end]`?表示獲取從 0 開始到?`end-1`的子字符串。 ## [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.6.md#763-字符串和切片的內存結構)7.6.3 字符串和切片的內存結構 在內存中,一個字符串實際上是一個雙字結構,即一個指向實際數據的指針和記錄字符串長度的整數(見圖 7.4)。因為指針對用戶來說是完全不可見,因此我們可以依舊把字符串看做是一個值類型,也就是一個字符數組。 字符串?`string s = "hello"`?和子字符串?`t = s[2:3]`?在內存中的結構可以用下圖表示: [![](https://box.kancloud.cn/2015-10-22_56288784b2451.png)](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/images/7.6_fig7.4.png) ## [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.6.md#764-修改字符串中的某個字符)7.6.4 修改字符串中的某個字符 Go 語言中的字符串是不可變的,也就是說?`str[index]`?這樣的表達式是不可以被放在等號左側的。如果嘗試運行?`str[i] = 'D'`?會得到錯誤:`cannot assign to str[i]`。 因此,您必須先將字符串轉換成字節數組,然后再通過修改數組中的元素值來達到修改字符串的目的,最后將字節數組轉換回字符串格式。 例如,將字符串 "hello" 轉換為 "cello": ~~~ s := "hello" c := []byte(s) c[0] = ’c’ s2 := string(c) // s2 == "cello" ~~~ 所以,您可以通過操作切片來完成對字符串的操作。 ## [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.6.md#765-字節數組對比函數)7.6.5 字節數組對比函數 下面的?`Compare`?函數會返回兩個字節數組字典順序的整數對比結果,即?`0 if a == b, -1 if a < b, 1 if a > b`。 ~~~ func Compare(a, b[]byte) int { for i:=0; i < len(a) && i < len(b); i++ { switch { case a[i] > b[i]: return 1 case a[i] < b[i]: return -1 } } // 數組的長度可能不同 switch { case len(a) < len(b): return -1 case len(a) > len(b): return 1 } return 0 // 數組相等 } ~~~ ## [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.6.md#766-搜索及排序切片和數組)7.6.6 搜索及排序切片和數組 標準庫提供了?`sort`?包來實現常見的搜索和排序操作。您可以使用?`sort`?包中的函數?`func Ints(a []int)`?來實現對 int 類型的切片排序。例如?`sort.Ints(arri)`,其中變量 arri 就是需要被升序排序的數組或切片。為了檢查某個數組是否已經被排序,可以通過函數?`IntsAreSorted(a []int) bool`?來檢查,如果返回 true 則表示已經被排序。 類似的,可以使用函數?`func Float64s(a []float64)`?來排序 float64 的元素,或使用函數?`func Strings(a []string)`排序字符串元素。 想要在數組或切片中搜索一個元素,該數組或切片必須先被排序(因為標準庫的搜索算法使用的是二分法)。然后,您就可以使用函數?`func SearchInts(a []int, n int) int`?進行搜索,并返回對應結果的索引值。 當然,還可以搜索 float64 和字符串: ~~~ func SearchFloat64s(a []float64, x float64) int func SearchStrings(a []string, x string) int ~~~ 您可以通過查看?[官方文檔](http://golang.org/pkg/sort/)?來獲取更詳細的信息。 這就是如何使用?`sort`?包的方法,我們會在第 11.6 節對它的細節進行深入,并實現一個屬于我們自己的版本。 ## [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.6.md#767-append-函數常見操作)7.6.7 append 函數常見操作 我們在第 7.5 節提到的 append 非常有用,它能夠用于各種方面的操作: 1. 將切片 b 的元素追加到切片 a 之后:`a = append(a, b...)` 2. 復制切片 a 的元素到新的切片 b 上: ~~~ b = make([]T, len(a)) copy(b, a) ~~~ 3. 刪除位于索引 i 的元素:`a = append(a[:i], a[i+1:]...)` 4. 切除切片 a 中從索引 i 至 j 位置的元素:`a = append(a[:i], a[j:]...)` 5. 為切片 a 擴展 j 個元素長度:`a = append(a, make([]T, j)...)` 6. 在索引 i 的位置插入元素 x:`a = append(a[:i], append([]T{x}, a[i:]...)...)` 7. 在索引 i 的位置插入長度為 j 的新切片:`a = append(a[:i], append(make([]T, j), a[i:]...)...)` 8. 在索引 i 的位置插入切片 b 的所有元素:`a = append(a[:i], append(b, a[i:]...)...)` 9. 取出位于切片 a 最末尾的元素 x:`x, a = a[len(a)-1], a[:len(a)-1]` 10. 將元素 x 追加到切片 a:`a = append(a, x)` 因此,您可以使用切片和 append 操作來表示任意可變長度的序列。 從數學的角度來看,切片相當于向量,如果需要的話可以定義一個向量作為切片的別名來進行操作。 如果您需要更加完整的方案,可以學習一下 Eleanor McHugh 編寫的幾個包:[slices](http://github.com/feyeleanor/slices)、[chain](http://github.com/feyeleanor/chain)?和?[lists](http://github.com/feyeleanor/lists)。 ## [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.6.md#768-切片和垃圾回收)7.6.8 切片和垃圾回收 切片的底層指向一個數組,該數組的實際體積可能要大于切片所定義的體積。只有在沒有任何切片指向的時候,底層的數組內層才會被釋放,這種特性有時會導致程序占用多余的內存。 **示例**?函數?`FindDigits`?將一個文件加載到內存,然后搜索其中所有的數字并返回一個切片。 ~~~ var digitRegexp = regexp.MustCompile("[0-9]+") func FindDigits(filename string) []byte { b, _ := ioutil.ReadFile(filename) return digitRegexp.Find(b) } ~~~ 這段代碼可以順利運行,但返回的?`[]byte`?指向的底層是整個文件的數據。只要該返回的切片不被釋放,垃圾回收器就不能釋放整個文件所占用的內存。換句話說,一點點有用的數據卻占用了整個文件的內存。 想要避免這個問題,可以通過拷貝我們需要的部分到一個新的切片中: ~~~ func FindDigits(filename string) []byte { b, _ := ioutil.ReadFile(filename) b = digitRegexp.Find(b) c := make([]byte, len(b)) copy(c, b) return c } ~~~ **練習 7.12** 編寫一個函數,要求其接受兩個參數,原始字符串 str 和分割索引 i,然后返回兩個分割后的字符串。 **練習 7.13** 假設有字符串 str,那么?`str[len(str)/2:] + str[:len(str)/2]`?的結果是什么? **練習 7.14** 編寫一個程序,要求能夠反轉字符串,即將 “Google” 轉換成 “elgooG”(提示:使用?`[]byte`?類型的切片)。 如果您使用兩個切片來實現反轉,請再嘗試使用一個切片(提示:使用交換法)。 如果您想要反轉 Unicode 編碼的字符串,請使用?`[]int`?類型的切片。 **練習 7.15** 編寫一個程序,要求能夠遍歷一個數組的字符,并將當前字符和前一個字符不相同的字符拷貝至另一個數組。 **練習 7.16** 編寫一個程序,使用冒泡排序的方法排序一個包含整數的切片(算法的定義可參考?[維基百科](http://en.wikipedia.org/wiki/Bubble_sort))。 **練習 7.17** 在函數式編程語言中,一個 map-function 是指能夠接受一個函數原型和一個列表,并使用列表中的值依次執行函數原型,公式為:`map ( F(), (e1,e2, . . . ,en) ) = ( F(e1), F(e2), ... F(en) )`。 編寫一個函數?`mapFunc`?要求接受以下 2 個參數: * 一個將整數乘以 10 的函數 * 一個整數列表 最后返回保存運行結果的整數列表。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看