bytes中常用函數的使用:
package main; import ( "bytes" "fmt" "unicode" ) //bytes包中實現了大量對[]byte操作的函數和兩個最主要的Reader和Buffer兩個結構 func main() { str := "aBcD"; //轉為小寫 fmt.Println(string(bytes.ToLower([]byte(str)))); //轉為大寫 fmt.Println(string(bytes.ToUpper([]byte(str)))); //轉為標題, fmt.Println(string(bytes.ToTitle([]byte(str)))); //自定義映射表 mycase := unicode.SpecialCase{ unicode.CaseRange{ //1,1表示替換規則只影響1到1之間的字符 1, 1, [unicode.MaxCase]rune{ //大寫轉換 '壹' - 1, //小寫轉換 '一' - 1, //標題轉換 '小' - 1, }, }, unicode.CaseRange{ 2, 2, [unicode.MaxCase]rune{ '貳' - 2, '二' - 2, '中' - 2, }, }, unicode.CaseRange{ 3, 3, [unicode.MaxCase]rune{ '叄' - 3, '三' - 3, '大' - 3, }, }, }; //使用映射表將[]byte中字符修改為小寫 data := bytes.ToLowerSpecial( mycase, []byte{1, 2, 3}, ) fmt.Println(string(data)); //使用映射表將[]byte中字符修改為大寫 data = bytes.ToUpperSpecial( mycase, []byte{1, 2, 3}, ); fmt.Println(string(data)); //使用映射表將[]byte中字符修改為標題 data = bytes.ToTitleSpecial( mycase, []byte{1, 2, 3}, ); fmt.Println(string(data)); //將[]byte中單詞首字符修改為Title並返回 fmt.Println(string(bytes.Title([]byte("abc def")))); //比較兩個[]byte, // a < b 返回 -1 // a == b 返回 0 // b > b 返回 1 fmt.Println(bytes.Compare([]byte("a"), []byte("b"))); //比較兩個[]byte是否相等 fmt.Println(bytes.Equal([]byte("abc"), []byte("abc"))); //比較兩個[]byte是否相等,忽略大寫,小寫,標題 fmt.Println(bytes.EqualFold([]byte("ABC"), []byte("abc"))); //去掉[]byte兩邊包含在cutset中的字符 fmt.Println(string(bytes.Trim([]byte(" abc "), " "))); //去掉左邊包含在cutset中的字符 fmt.Println(string(bytes.TrimLeft([]byte(" abc "), " "))); //去掉右邊包含在cutset中的字符 fmt.Println(string(bytes.TrimRight([]byte(" abc "), " "))); //去掉兩邊空白字符 fmt.Println(string(bytes.TrimSpace([]byte(" abc ")))); //去掉前綴 fmt.Println(string(bytes.TrimPrefix([]byte("tb_user"), []byte("tb_")))); //去掉后綴 fmt.Println(string(bytes.TrimSuffix([]byte("user_idx"), []byte("_idx")))); //以sep為分隔符,切分為多個[]byte tmp := bytes.Split([]byte("ab cd ef"), []byte(" ")); for _, v := range tmp { fmt.Println(string(v)); } //分割最多n個子切片,超出n的部分將不進行切分 tmp = bytes.SplitN([]byte("ab cd ef"), []byte(" "), 2); for _, v := range tmp { fmt.Println(string(v)); } //以sep為分隔符,切分為多個[]byte,結果包含分隔符,在子串尾部 tmp = bytes.SplitAfter([]byte("ab,cd,ef"), []byte(",")); for _, v := range tmp { fmt.Println(string(v)); } //分割最多n個子切片,超出n的部分將不進行切分 tmp = bytes.SplitAfterN([]byte("ab,cd,ef"), []byte(","), 2); for _, v := range tmp { fmt.Println(string(v)); } //以空白字符切分 tmp = bytes.Fields([]byte("a b c d")); for _, v := range tmp { fmt.Println(string(v)); } //以符合函數的字符作為分隔符來切分 tmp = bytes.FieldsFunc([]byte("asbscsd"), func(r rune) bool { if r == rune('s') { return true; } return false; }); for _, v := range tmp { fmt.Println(string(v)); } //以sep為連接符,拼接[][]byte fmt.Println(string(bytes.Join( [][]byte{ []byte("aa"), []byte("bb"), []byte("cc"), }, []byte("-"), ))); //重復[]byte,Count次 fmt.Println(string(bytes.Repeat([]byte("abc"), 3))); //判斷是否有前綴 fmt.Println(bytes.HasPrefix([]byte("is_true"), []byte("is_"))); //判斷是否有后綴 fmt.Println(bytes.HasSuffix([]byte("chk_on"), []byte("_on"))); //判斷是否包含某個[]byte fmt.Println(bytes.Contains([]byte("i am jack"), []byte("jack"))); //判斷是否包含某個rune fmt.Println(bytes.ContainsRune([]byte("i from 中國"), rune('中'))); //查找sep在參數一中第一次出現的位置,找不到返回-1 fmt.Println(bytes.Index([]byte("abcabc"), []byte("a"))); fmt.Println(bytes.IndexByte([]byte("cba"), 'a')); fmt.Println(bytes.IndexRune([]byte("i from 中國"), rune('中'))); //查找chars中任意一個字符在參數一中出現的位置,找不到返回-1 fmt.Println(bytes.IndexAny([]byte("hello world"), "xy")); //功能同上,只不過查找最后一次出現的位置 fmt.Println(bytes.LastIndex([]byte("abcabc"), []byte("a"))); fmt.Println(bytes.LastIndexByte([]byte("cba"), 'a')); fmt.Println(bytes.LastIndexAny([]byte("hello world"), "xy")); //獲取sep中在參數一中出現的次數 fmt.Println(bytes.Count([]byte("a|b|c"), []byte("|"))); //將參數一中前n個old替換成new,n小於0則全部替換。 fmt.Println(string( bytes.Replace( []byte("i am jack"), []byte("i am"), []byte("我是"), -1, ), )); //將[]byte中的字符替換為函數的返回值,如果返回值為負數,則丟棄訪字符。 fmt.Println(string( bytes.Map( func(r rune) rune { if r == 'a' { return 'A'; } else if r == 'c' { return -1; } return r; }, []byte("abcd"), ), )); //將[]byte轉換為[]rune fmt.Println(string(bytes.Runes([]byte("我是誰")))); }
bytes中Reader和Buffer的使用:
package main; import ( "bytes" "fmt" ) //bytes中Reader和Buffer兩個結構的使用 func useReader() { data := "abcdefghijk"; //通過[]byte創建Reader re := bytes.NewReader([]byte(data)); //返回未讀取部分的長度 fmt.Println("re len : ", re.Len()); //返回底層數據總長度 fmt.Println("re size : ", re.Size()); buf := make([]byte, 2); for { //讀取數據 n, err := re.Read(buf); if err != nil { break; } fmt.Println(string(buf[:n])); }; //設置偏移量,因為上面的操作已經修改了讀取位置等信息 re.Seek(0, 0); for { //一個字節一個字節的讀 b, err := re.ReadByte(); if err != nil { break; } fmt.Println(string(b)); } re.Seek(0, 0); off := int64(0); for { //指定偏移量讀取 n, err := re.ReadAt(buf, off); if err != nil { break; } off += int64(n); fmt.Println(off, string(buf[:n])); } } func useBuffer() { data := "123456789"; //通過[]byte創建一個Buffer bf := bytes.NewBuffer([]byte(data)); //Len()返回未讀取的數據長度 fmt.Println("bf len : ", bf.Len()); //Cap()緩存容量 fmt.Println("bf cap : ", bf.Cap()); //Bytes()返回未讀取的數據切片 bys := bf.Bytes(); for _, v := range bys { fmt.Print(string(v) + " "); } fmt.Println(); //Next()返回未讀取部分前n字節數據的切片 for i := 0; i < 10; i++ { tmp := bf.Next(1); fmt.Print(string(tmp) + " "); } fmt.Println(); //再次Next,返回[]byte,說明沒有未讀取的 fmt.Println(bf.Next(1)); //重設緩沖,丟棄全部內容 bf.Reset(); //通過string創建Buffer bf2 := bytes.NewBufferString(data); //讀取第一個 delim 及其之前的內容,返回遇到的錯誤 line, _ := bf2.ReadBytes('3'); fmt.Println(string(line)); //效果同上,返回string line2, _ := bf2.ReadString('7'); fmt.Println(line2); //創建一個空Buffer bf3 := bytes.Buffer{}; //自動增加緩存容量,保證有n字節剩余空間 bf3.Grow(16); //寫入rune編碼,返回寫入的字節數和錯誤。 n, _ := bf3.WriteRune(rune('中')); fmt.Println("bf3 write ", n); n, _ = bf3.WriteString("國人"); fmt.Println("bf3 write ", n); //返回未讀取的字符串 fmt.Println(bf3.String()); //將數據長度截斷到n字節 bf3.Truncate(6); fmt.Println(bf3.String()); } func main() { //防止main中代碼過多,我新建兩個函數單獨寫 useReader(); useBuffer(); }