mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-08-05 15:12:33 +00:00
ch3-05 review
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
|
||||
標準庫中有四個包對字符串處理尤爲重要:bytes、strings、strconv和unicode包。strings包提供了許多如字符串的査詢、替換、比較、截斷、拆分和合併等功能。
|
||||
|
||||
bytes包也提供了很多類似功能的函數,但是針對和字符串有着相同結構的[]byte類型。因爲字符串是隻讀的,因此逐步構建字符串會導致很多分配和複製。在這種情況下,使用bytes.Buffer類型将會更有效,稍後我們將展示。
|
||||
bytes包也提供了很多類似功能的函數,但是針對和字符串有着相同結構的[]byte類型。因爲字符串是隻讀的,因此逐步構建字符串會導致很多分配和複製。在這種情況下,使用bytes.Buffer類型將會更有效,稍後我們將展示。
|
||||
|
||||
strconv包提供了布爾型、整型數、浮點數和對應字符串間的相互轉換, 還提供了雙引號的字符串面值形式的轉換.
|
||||
strconv包提供了布爾型、整型數、浮點數和對應字符串的相互轉換,還提供了雙引號轉義相關的轉換。
|
||||
|
||||
unicode 包提供了類似 IsDigit, IsLetter, IsUpper, 和 IsLower 等功能, 它們用於給字符分類. 每個函數有一個單一的rune類型的參數, 然後返迴一個布爾值. 像 ToUpper 和 ToLower 之類的轉換函數將用於rune字符的大小寫轉換. 所有的這些函數都是遵循Unicode標準定義的字母,數字等分類規范. strings 包也有類似的函數, 它們是 ToUpper 和 ToLower, 將原始字符串的每個字符都做相應的轉換, 然後返迴新的字符串.
|
||||
unicode包提供了IsDigit、IsLetter、IsUpper和IsLower等類似功能,它們用於給字符分類。每個函數有一個單一的rune類型的參數,然後返迴一個布爾值。而像ToUpper和ToLower之類的轉換函數將用於rune字符的大小寫轉換。所有的這些函數都是遵循Unicode標準定義的字母、數字等分類規范。strings包也有類似的函數,它們是ToUpper和ToLower,將原始字符串的每個字符都做相應的轉換,然後返迴新的字符串。
|
||||
|
||||
下面的 basename 函數的靈感由Unix shell的同名工具而來. 在我們實現的版本中, basename(s) 將看起來像是繫統路徑的前綴刪除, 同時將看似文件類型的後綴名刪除:
|
||||
下面例子的basename函數靈感於Unix shell的同名工具。在我們實現的版本中,basename(s)將看起來像是繫統路徑的前綴刪除,同時將看似文件類型的後綴名部分刪除:
|
||||
|
||||
```Go
|
||||
fmt.Println(basename("a/b/c.go")) // "c"
|
||||
@@ -16,7 +16,7 @@ fmt.Println(basename("c.d.go")) // "c.d"
|
||||
fmt.Println(basename("abc")) // "abc"
|
||||
```
|
||||
|
||||
第一個版本併沒有使用任何庫, 全部手工實現:
|
||||
第一個版本併沒有使用任何庫,全部手工硬編碼實現:
|
||||
|
||||
```Go
|
||||
gopl.io/ch3/basename1
|
||||
@@ -41,7 +41,7 @@ func basename(s string) string {
|
||||
}
|
||||
```
|
||||
|
||||
一個簡化的版本使用了 strings.LastIndex 庫函數:
|
||||
簡化個版本使用了strings.LastIndex庫函數:
|
||||
|
||||
```Go
|
||||
gopl.io/ch3/basename2
|
||||
@@ -56,10 +56,9 @@ func basename(s string) string {
|
||||
}
|
||||
```
|
||||
|
||||
path 和 path/filepath 包提供了關於文件名更一般的函數操作. 使用斜槓分隔路徑可以在任何操作繫統上工作. 斜槓本身不應該用於文件名, 但是在其他一些領域可能是有效的, 例如URL路徑組件. 相比之下, path/filepath 包使用操作繫統本身的路徑規則, 例如 POSIX 繫統使用 /foo/bar, Microsoft Windows 使用 c:\foo\bar 等.
|
||||
path和path/filepath包提供了關於文件路徑名更一般的函數操作。使用斜槓分隔路徑可以在任何操作繫統上工作。斜槓本身不應該用於文件名,但是在其他一些領域可能會用於文件名,例如URL路徑組件。相比之下,path/filepath包則使用操作繫統本身的路徑規則,例如POSIX繫統使用/foo/bar,而Microsoft Windows使用c:\foo\bar等。
|
||||
|
||||
|
||||
讓我們繼續另一個字符串的例子. 任務是將一個表示整值的字符串, 每隔三個字符插入一個逗號, 例如 "12345" 處理後成爲 "12,345". 這個版本隻適用於整數類型; 支持浮點數類型的支持留做練習.
|
||||
讓我們繼續另一個字符串的例子。函數的功能是將一個表示整值的字符串,每隔三個字符插入一個逗號分隔符,例如“12345”處理後成爲“12,345”。這個版本隻適用於整數類型;支持浮點數類型的支持留作練習。
|
||||
|
||||
```Go
|
||||
gopl.io/ch3/comma
|
||||
@@ -74,11 +73,11 @@ func comma(s string) string {
|
||||
}
|
||||
```
|
||||
|
||||
輸入 comma 的參數是一個字符串. 如果輸入字符串的長度小於或等於3的話, 則不需要插入逗號. 否則, comma 將在最後三個字符前切割爲兩個兩個子串, 然後用前面的子串遞歸調用自身.
|
||||
輸入comma函數的參數是一個字符串。如果輸入字符串的長度小於或等於3的話,則不需要插入逗分隔符。否則,comma函數將在最後三個字符前位置將字符串切割爲兩個兩個子串併插入逗號分隔符,然後通過遞歸調用自身來出前面的子串。
|
||||
|
||||
一個字符串包含的字節數組, 一旦創建, 是不可變的. 相比之下, 一個字節切片的原始則可以自由地脩改.
|
||||
一個字符串是包含的隻讀字節數組,一旦創建,是不可變的。相比之下,一個字節slice的元素則可以自由地脩改。
|
||||
|
||||
字符串和字節切片可以相互轉換:
|
||||
字符串和字節slice之間可以相互轉換:
|
||||
|
||||
```Go
|
||||
s := "abc"
|
||||
@@ -86,9 +85,9 @@ b := []byte(s)
|
||||
s2 := string(b)
|
||||
```
|
||||
|
||||
從概念上講, []byte(s) 轉換是分配了一個新的字節數組保存了字符串數據的拷貝, 然後引用這個字節數組. 編譯器的優化可以避免在一些場景下分配和複製字符串數據, 但總的來説需要確保在b被脩改的情況下, 原始的s字符串也不會改變. 將一個字節切片轉到字符串的 string(b) 操作則是構造一個拷貝, 以確保s2字符串是隻讀的.
|
||||
從概念上講,一個[]byte(s)轉換是分配了一個新的字節數組用於保存字符串數據的拷貝,然後引用這個底層的字節數組。編譯器的優化可以避免在一些場景下分配和複製字符串數據,但總的來説需要確保在變量b被脩改的情況下,原始的s字符串也不會改變。將一個字節slice轉到字符串的string(b)操作則是構造一個字符串拷貝,以確保s2字符串是隻讀的。
|
||||
|
||||
爲了避免轉換中不必要的內存分配, bytes包和strings同時提供了許多類似的實用函數. 下面是strings包中的六個函數:
|
||||
爲了避免轉換中不必要的內存分配,bytes包和strings同時提供了許多實用函數。下面是strings包中的六個函數:
|
||||
|
||||
```Go
|
||||
func Contains(s, substr string) bool
|
||||
@@ -99,7 +98,7 @@ func Index(s, sep string) int
|
||||
func Join(a []string, sep string) string
|
||||
```
|
||||
|
||||
bytes 包中對應的六個函數:
|
||||
bytes包中也對應的六個函數:
|
||||
|
||||
```Go
|
||||
func Contains(b, subslice []byte) bool
|
||||
@@ -110,9 +109,9 @@ func Index(s, sep []byte) int
|
||||
func Join(s [][]byte, sep []byte) []byte
|
||||
```
|
||||
|
||||
唯一的區别是字符串類型參數被替換成了字節切片類型的參數.
|
||||
它們之間唯一的區别是字符串類型參數被替換成了字節slice類型的參數。
|
||||
|
||||
bytes 包還提供了 Buffer 類型用於字節切片的緩存. 一個 Buffer 開始是空的, 但是隨着 string, byte, 和 []byte 等類型數據的寫入可以動態增長, 一個 bytes.Buffer 變量併不需要處理化, 因此零值也是有效的:
|
||||
bytes包還提供了Buffer類型用於字節slice的緩存。一個Buffer開始是空的,但是隨着string、byte或[]byte等類型數據的寫入可以動態增長,一個bytes.Buffer變量併不需要處理化,因爲零值也是有效的:
|
||||
|
||||
```Go
|
||||
gopl.io/ch3/printints
|
||||
@@ -136,16 +135,15 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
當向 bytes.Buffer 添加任意字符的UTF8編碼, 最好使用 bytes.Buffer 的 WriteRune 方法, 但是 WriteByte 方法對於寫入類似 '[' 和 ']' 等 ASCII 字符則更有效.
|
||||
當向bytes.Buffer添加任意字符的UTF8編碼時,最好使用bytes.Buffer的WriteRune方法,但是WriteByte方法對於寫入類似'['和']'等ASCII字符則會更加有效。
|
||||
|
||||
bytes.Buffer 類型有着諸多實用的功能, 我們在第七章討論接口時層涉及到, 我們將看看如何將它用作一個I/O 的輸入和輸出對象, 例如 Fprintf 的 io.Writer 輸出, 或作爲輸入源 io.Reader.
|
||||
bytes.Buffer類型有着很多實用的功能,我們在第七章討論接口時將會涉及到,我們將看看如何將它用作一個I/O的輸入和輸出對象,例如當做Fprintf的io.Writer輸出對象,或者當作io.Reader類型的輸入源對象。
|
||||
|
||||
**練習3.10:** 編寫一個非遞歸版本的comma函數, 使用 bytes.Buffer 代替字符串鏈接操作.
|
||||
**練習 3.10:** 編寫一個非遞歸版本的comma函數,使用bytes.Buffer代替字符串鏈接操作。
|
||||
|
||||
**練習3.11:** 完善 comma 函數, 以支持浮點數處理和一個可選的正負號處理.
|
||||
**練習 3.11:** 完善comma函數,以支持浮點數處理和一個可選的正負號的處理。
|
||||
|
||||
|
||||
**練習3.12:** 編寫一個函數, 判斷兩個字符串是否是是相互打亂的, 也就是説它們有着相同的字符, 但是對應不同的順序.
|
||||
**練習 3.12:** 編寫一個函數,判斷兩個字符串是否是是相互打亂的,也就是説它們有着相同的字符,但是對應不同的順序。
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user