golang笔记——string

  任何语言中,字符串操做API都是很是重要的,有些仍是熟记比较好,固然若是记不住能够去看源码文件,不得不说GO语言源码看起来很是舒服。html

  可使用反引号代替双引号,来表示原生的字符串,即不进行转义,尤为适合用于表示正则表达式、路径字符串、JSON串。git

  每一个Unicode码点都使用一样的大小32bit来表示。这种方式比较简单统一,可是它会浪费不少存储空间,由于大数据计算机可读的文本是ASCII字符,原本每一个ASCII字符只须要8bit或1字节就能表示。并且即便是经常使用的字符也远少于65,536个,也就是说用16bit编码方式就能表达经常使用字符。正则表达式

  UTF8是一个将Unicode码点编码为字节序列的变长编码。UTF8编码由Go语言之父Ken Thompson和Rob Pike共同发明的,如今已是Unicode的标准。UTF8编码使用1到4个字节来表示每一个Unicode码点,ASCII部分字符只使用1个字节,经常使用字符部分使用2或3个字节表示。每一个符号编码后第一个字节的高端bit位用于表示总共有多少编码个字节。若是第一个字节的高端bit为0,则表示对应7bit的ASCII字符,ASCII字符每一个字符依然是一个字节,和传统的ASCII编码兼容。若是第一个字节的高端bit是110,则说明须要2个字节;后续的每一个高端bit都以10开头。更大的Unicode码点也是采用相似的策略处理。 数组

许多类型都会定义一个String方法,由于当使用fmt包的打印方法时,将会优先使用该类型对应的String方法返回的结果打印缓存

 

  go语言默认使用UTF-8编码,对Unicode的支持很是好。其它语言中通常都提供获取字符串长度的函数,但其实是获取字节个数,但获取 Unicode 码点个数就可能有些麻烦,好比注册账号时,无视中英文限制长度时,就要获取Unicode码点个数。GO语言内置了方法:函数

import "unicode/utf8"

s := "Hello, 世界"
fmt.Println(len(s))                    // "13"
fmt.Println(utf8.RuneCountInString(s)) // "9"

  而遍历输出这些字符是这样的:大数据

for i := 0; i < len(s); {
    r, size := utf8.DecodeRuneInString(s[i:])
    fmt.Printf("%d\t%c\n", i, r)
    i += size
}

每一次调用DecodeRuneInString函数都返回一个r和长度,r对应字符自己,长度对应r采用UTF8编码后的编码字节数目。实际上,Go语言的range循环在处理字符串的时候,会自动隐式解码UTF8字符串。编码

for i, r := range "Hello, 世界" {
    fmt.Printf("%d\t%q\t%d\n", i, r, r)
}

string接受到[]rune的类型转换,能够将一个UTF8编码的字符串解码为Unicode字符序列。spa

若是遇到非法的unicode字符,会解析成 \uFFFD,它是一个特殊符号,遇到它就要注意了。code

标准库中有四个包对字符串处理尤其重要:bytes、strings、strconv和unicode包。strings包提供了许多如字符串的查询、替换、比较、截断、拆分和合并等功能。

bytes包也提供了不少相似功能的函数,可是针对和字符串有着相同结构的[]byte类型。由于字符串是只读的,所以逐步构建字符串会致使不少分配和复制。在这种状况下,使用bytes.Buffer类型将会更有效,稍后咱们将展现。

strconv包提供了布尔型、整型数、浮点数和对应字符串的相互转换,还提供了双引号转义相关的转换。

unicode包提供了IsDigit、IsLetter、IsUpper和IsLower等相似功能,它们用于给字符分类。每一个函数有一个单一的rune类型的参数,而后返回一个布尔值。而像ToUpper和ToLower之类的转换函数将用于rune字符的大小写转换。全部的这些函数都是遵循Unicode标准定义的字母、数字等分类规范。strings包也有相似的函数,它们是ToUpper和ToLower,将原始字符串的每一个字符都作相应的转换,而后返回新的字符串。

  字节数组 []byte 和 string 能够互相转换,[]byte本质是一个数组(切片?),string是一个常量。bytes包和strings包提供了不少相似的函数,都是为了效率出发,避免转换。bytes包还提供了Buffer类型用于字节slice的缓存。一个Buffer开始是空的,可是随着string、byte或[]byte等类型数据的写入能够动态增加,一个bytes.Buffer变量并不须要处理化,由于零值也是有效的:

当向bytes.Buffer添加任意字符的UTF8编码时,最好使用bytes.Buffer的WriteRune方法,可是WriteByte方法对于写入相似'['和']'等ASCII字符则会更加有效。

 

  字符串操做相关的API大多封装在 strings 包里,下面列一些常见的

func Count(s, sep string) int

  获取指定子字符串的个数

func Contains(s, substr string) bool

  判断是否包括某子字符串

func ContainsAny(s, chars string) bool

  判断是否包括某字符串中的作任意一个字符,只要包括其中任意一个字符则返回true

func EqualFold(s, t string) bool

  忽略大小写时,判断两个字符串是否相等。

func Fields(s string) []string

  其实就是其它语言中的 Splite 函数,分隔字符串的,这个是按空格分隔。

func Split(s, sep string) []string

  按指定字符分隔字符串

func FieldsFunc(s string, f func(rune) bool) []string

  更强大的自定义分隔字符串,使用函数做为参数

    s := "a,b,c d,e,f"
    slice1 := strings.FieldsFunc(s, func(c rune) bool {
        if c == ',' || c == ' ' {
            return true
        }
        return false
    })
    print_array(slice1)

func HasPrefix(s, prefix string) bool

  判断是否以某字符串开头

func HasSuffix(s, suffix string) bool

  判断是否以某字符串结尾

 

  

接合这个看源码吧  http://www.widuu.com/archives/01/939.html