From 55ba6736e9018d4cef9d8b67a83fd405546e1788 Mon Sep 17 00:00:00 2001 From: chai2010 Date: Fri, 18 Dec 2015 17:22:58 +0800 Subject: [PATCH] Update ch3-05-4.md --- ch3/ch3-05-4.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/ch3/ch3-05-4.md b/ch3/ch3-05-4.md index 3ab3f5c..4cd5d0a 100644 --- a/ch3/ch3-05-4.md +++ b/ch3/ch3-05-4.md @@ -1,4 +1,65 @@ ### 3.5.4. 字符串和Byte切片 + +标准库中有四个包对字符串处理尤为重要: bytes, strings, strconv, 和 unicode. strings 包提供了许多如字符串的查询, 替换, 比较, 截断, 拆分, 和合并等功能. + +bytes 包也提供了很多类似功能的函数, 但是针对和字符串有着相同结构的 []byte 类型. 因为字符串是只读的, 因此逐步构建字符串会导致很多分配和复制. 在这种情况下, 使用 bytes.Buffer 类型会更有效, 稍后我们将展示. + +strconv 包提供了 布尔型, 整型数, 浮点数和对应字符串间的相互转换, 还提供了双引号的字符串面值形式的转换. + +unicode 包提供了类似 IsDigit, IsLetter, IsUpper, 和 IsLower 等功能, 它们用于给字符分类. 每个函数有一个单一的rune类型的参数, 然后返回一个布尔值. 像 ToUpper 和 ToLower 之类的转换函数将用于rune字符的大小写转换. 所有的这些函数都是遵循Unicode标准定义的字母,数字等分类规范. strings 包也有类似的函数, 它们是 ToUpper 和 ToLower, 将原始字符串的每个字符都做相应的转换, 然后返回新的字符串. + +下面的 basename 函数的灵感由Unix shell的同名工具而来. 在我们实现的版本中, basename(s) 将看起来像是系统路径的前缀删除, 同时将看似文件类型的后缀名删除: + +```Go +fmt.Println(basename("a/b/c.go")) // "c" +fmt.Println(basename("c.d.go")) // "c.d" +fmt.Println(basename("abc")) // "abc" +``` + +第一个版本并没有使用任何库, 全部手工实现: + +```Go +gopl.io/ch3/basename1 +// basename removes directory components and a .suffix. +// e.g., a => a, a.go => a, a/b/c.go => c, a/b.c.go => b.c +func basename(s string) string { + // Discard last '/' and everything before. + for i := len(s) - 1; i >= 0; i-- { + if s[i] == '/' { + s = s[i+1:] + break + } + } + // Preserve everything before last '.'. + for i := len(s) - 1; i >= 0; i-- { + if s[i] == '.' { + s = s[:i] + break + } + } + return s +} +``` + +一个简化的版本使用了 strings.LastIndex 库函数: + +```Go +gopl.io/ch3/basename2 + +func basename(s string) string { + slash := strings.LastIndex(s, "/") // -1 if "/" not found + s = s[slash+1:] + if dot := strings.LastIndex(s, "."); dot >= 0 { + s = s[:dot] + } + return s +} +``` + +path 和 path/filepath 包提供了关于文件名更一般的函数操作. 使用斜杠分隔路径可以在任何操作系统上工作. 斜杠本身不应该用于文件名, 但是在其他一些领域可能是有效的, 例如URL路径组件. 相比之下, path/filepath 包使用操作系统本身的路径规则, 例如 POSIX 系统使用 /foo/bar, Microsoft Windows 使用 c:\foo\bar 等. + + + TODO