一直想系统的学习一下golang的官方包,同时我能找到的资源不是很多,而且多是英文版,我希望能把官方包的一些东西过一遍,能写成一些系列,当然有些实在不懂的我会跳过。
Func部分:
1.func Clone
func Clone(s string) string
该函数会克隆s,返回一个相同的字符串,官方包上写着,除非有明确申明,否则该函数使用的非常少,频繁使用,很耗内存。
2.func Compare
func Compare(a, b string) int
这个一个字典排序,就是按照英文字母排序,在二十六个字母里排在后面的为大,比如b>a
假如两个string的首字母相同,则比较下一个字母,如ab<ac
若所有前面的都相同,但是b比a多一个字母,则字母多的大,如aa<aac
返回值是一个int,若a=b,返回0;a>b,返回1,;a<b,返回-1。
文档上说实际上>=<这些符号也能实现比较,并且更好
下面是一些例子
fmt.Println(strings.Compare("bb", "bbc"))//-1
fmt.Println(strings.Compare("ac", "abc"))//1
fmt.Println(strings.Compare("b", "B"))//1 小写是大于大写的
3.func Contains
func Contains(s, substr string) bool
查询substr是否包含在s字符串之中
当然空字符串包含在所有的字符串之中
例子:
fmt.Println(strings.Contains("seafood", ""))//true
fmt.Println(strings.Contains("", ""))//true
3.func ContainAny
func ContainsAny(s, chars string) bool
contain函数的摆烂版本
chars实际上是一个字母的集合,s里面只要包含任何一个chars里面的字母就成立
但是不在承认空字符串,毕竟人家要求已经这么低了,再传空字符串不合适
例:
fmt.Println(strings.ContainsAny("fail", "ui"))//true
fmt.Println(strings.ContainsAny("foo", ""))//false
fmt.Println(strings.ContainsAny("", ""))//false
4.func ContainRune
func ContainsRune(s string, r rune) bool
这个明显是用来为其他文字设置的
fmt.Println(strings.ContainsRune("滑滑粉", '粉'))//true
5.func Count
func Count(s, substr string) int
求s里面出现了几次substr
如果substr是空字符串的话返回(s的长度+1)
例:
fmt.Println(strings.Count("cheese", "e"))//3
fmt.Println(strings.Count("five", "")) //5
6.func Cut
func Cut(s, sep string) (before, after string, found bool)
查找sep是否在s中存在,存在的话他的前面的和后面的内容究竟是什么
很明显是上面那个contain的全面版
例:
Cut("Gopher", "") = "", "Gopher", true(这种情况也要注意)
Cut("Gopher", "Go") = "", "pher", true
Cut("Gopher", "ph") = "Go", "er", true
Cut("Gopher", "er") = "Goph", "", true
Cut("Gopher", "Badger") = "Gopher", "", false(特别注意一下这种情况)
7.func EqualFold
func EqualFold(s, t string) bool
忽视大小写,比较s和t的实质是否相同
例:
fmt.Println(strings.EqualFold("Go", "go"))//true
fmt.Println(strings.EqualFold("Go ", "go"))//false(忽略大小写可没忽略空格)
8.func Fields
func Fields(s string) []string
根据空格把s分成一个string切片
例:
fmt.Printf(strings.Fields(" foo bar baz "))//["foo" "bar" "baz"]
明显这里有空格就行了,至于多少个空格不影响结果
9.func FieldsFunc
func FieldsFunc(s string, f func(rune) bool) []string
实际上是上面的fields函数的升级版,当遇到某个rune满足f函数条件的时候,就以这个rune边界,将s转化成[]string
例:
f := func(c rune) bool {
明显是当这个s里面这个rune不是字母也不是数字的时候,这个rune就是slice的分割点
return !unicode.IsLetter(c) && !unicode.IsNumber(c)
}
fmt.Printf("Fields are: %q", strings.FieldsFunc(" foo1;bar2!baz3...", f))
结果:Fields are: ["foo1" "bar2" "baz3"]
10.func HasPrefix func HasSuffix
func HasPrefix(s, prefix string) bool
func HasSuffix(s, suffix string) bool
s是否有前后缀,挺简单的
11.func Index
func Index(s, substr string) int
看substr是否存在于s之中,不存在返回-1
存在的话返回substr第一次出现的index
没什么讲头,和其他语言中的用法类似
如果substr是空字符串,返回0,很符合常理
12.func IndexAny
func IndexAny(s, chars string) int
和上面提到的containany函数类似,chars当中的任何一个字母,只要存在在s中,就返回它的index,不存在话返回-1,但是和上面的index函数不同,这个函数对空字符串不容忍,但能识别空格等
例:
fmt.Println(strings.IndexAny("chicken", ""))//-1
fmt.Println(strings.IndexAny("chi cken", " "))//-3
13.func IndexByte
func IndexByte(s string, c byte) int
特殊的index,查找的是byte的索引位置,也就是char,单个字母
14.func IndexRune
func IndexRune(s string, r rune) int
特殊的index函数,查找的是符合条件的rune的位置
fmt.Println(strings.IndexRune("黄烽", '烽'))//3 utf-8汉字占三个字节
fmt.Println(strings.IndexRune("chicken", 'd'))//-1 byte是一种特殊的rune
15func IndexFunc func LastIndexFunc
func IndexFunc(s string, f func(rune) bool) int
func LastIndexFunc(s string, f func(rune) bool) int
范围符合f函数要求的index位置,当然关于字符集之类的我还没看到,先空着
16.func LastIndex
func LastIndex(s, substr string) int
使用方法同index,只不过是从后算起
17.func LastIndexAny
func LastIndexAny(s, chars string) int
同IndexAny
18.func LastIndexByte
同indexByte
19.func Map
func Map(mapping func(rune) rune, s string) string
根据mapping函数对s的每一个rune进行处理
例:
func main() {
rot13 := func(r rune) rune {
switch {
case r >= 'A' && r <= 'Z':
return 'A' + 1
case r >= 'a' && r <= 'z':
return 'a' + 1
}
return r
}
fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher..."))
}
结果:'Bbbb bbbbbbb bbb bbb bbbbbb bbbbbb...
golang的rune和byte似乎是可以加减的
20 .func Repeat
func Repeat(s string, count int) string
将字符串进行重复处理得到新字符串,count代表重复的次数,很常见的功能
21.func Replace
func Replace(s, old, new string, n int) string
代替,将s中的old替换成new,n代表替换几次,这个n可以超越实际的次数,但n为-1的时候代表全部替换
fmt.Println(strings.Replace("oink oink oink", "k", "ky", 4))//oinky oinky oinky
fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))//moo moo moo
22.func ReplaceAll
func ReplaceAll(s, old, new string) string
和上面一个函数同功能,代表全部替换
23.func Join
func Join(elems []string, sep string) string
以sep为间隔将elems组合成一个string,常见方法不多述
24.func Split 和func SplitN
func Split(s, sep string) []string
这也是一个常见方法,重点要说一下后面那个方法
func SplitN(s, sep string, n int) []string
这个n参数限制返回的stringslice的元素数量,若n<0代表全部分隔,也就是相当于split
若n>可分隔的最大份数,也相当于split
若n=0,会返回一个空组数
例:
strings.SplitN("a,b,c", ",", 2)//[a b,c]
strings.SplitN("a,b,c", ",", 4)//[a,b,c]
25.func SplitAfter 和 func SplitAfterN
func SplitAfter(s, sep string) []string
这个函数是split函数的变种,在split函数之中,分隔的依据sep会被忽视,但是在这个函数之中,分隔符号也会被保存
例:
fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))//["a," "b," "c"]这个例子一来就十分明显
func SplitAfterN(s, sep string, n int) []string
这个函数就是SplitN的变形,可以参照SplitN和SplitAfter的特征一起理解
例:
fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2))//["a," "b,c"]
26.func ToLower 和 func ToUpper
func ToLower(s string) string
func ToUpper(s string) string
将s字符串全部字母变成小写/大写,常见功能
27.func ToTitle
func ToTitle(s string) string
字符串全部大写
和toUpper的不同之处在于,这个能处理俄文等大小写
28.func ToLowerSpecial 和func ToupperSpecial 和func ToTitleSpecial
func ToLowerSpecial(c unicode.SpecialCase, s string) string
func ToTitleSpecial(c unicode.SpecialCase, s string) string
func ToUpperSpecial(c unicode.SpecialCase, s string) string
这个三个函数的c参数代表选择字符的类型,应该是用来处理像土耳其文或者俄文这样的字母的大小写
29.func Trim、func TrimLeft和 func TrimRight
func Trim(s, cutset string) string
字符串修边函数,两边都修
参数cutset代表一连串需要修去的符号的合集
兄弟函数就是后面的TrimLeft和TrimRight
例:
fmt.Print(strings.Trim("¡¡¡Hello, Gophers!!!", "!¡"))//Hello, Gophers
30.func TrimSpace
func TrimSpace(s string) string
字符串修掉空格
当然中间的空格是不修的,这算是实际内容
例:
fmt.Println(strings.TrimSpace(" He llo, Gophers"))//He llo, Gophers
31.func TrimSuffix 和 func TrimPrefix
func TrimSuffix(s, suffix string) string
func TrimPrefix(s, prefix string) string
修掉字符串的前后缀,注意这里的前后缀不再是字母合集,而是一个字符串,这要和trim,trimleft之类的函数相区别
32.TrimFunc 和TrimLeftFunc和 TrimRightFunc
func TrimFunc(s string, f func(rune) bool) string
func TrimLeftFunc(s string, f func(rune) bool) string
func TrimRightFunc(s string, f func(rune) bool) string
看到这个Func后缀就知道这三个函数涉及到自主定义的修边
但s当中的字母符合f函数的要求,那我就将其修去
例:
strings.TrimFunc("¡¡¡Hello, Gophers!!!", func(r rune) bool {
return !unicode.IsLetter(r)
})//Hello, Gophers
上面的例子就是不是字母,就将其修去
33.func ToValidUTF8,暂时不清楚其作用
struct部分
1.type Builder
这个是字符串的构建结构,应该类似于一个缓存
例:
//1.type Builder
// 这个主要是构建string的一个缓存
// 创建一个Builder指针
var strBuilder strings.Builder
// 四种写入方式
//func (b *Builder) Write(p []byte) (int, error)
// 本质上是写入了一个byte切片,返回的是错误信息和切片的长度
n, err := strBuilder.Write([]byte("你好啊"))
if err != nil {
fmt.Println(err)
}
fmt.Println("写入的长度是:", n) //9
//2.func (b *Builder) WriteByte(c byte) error
// 这个函数是写入单个字节,所以说返回len就没有必要了
err = strBuilder.WriteByte('c')
if err != nil {
fmt.Println(err)
}
//3.func (b *Builder) WriteRune(r rune) (int, error)
// 现在我呀写入rune,也就是特殊字符,特殊字符占有的字节是不一样的,所以要查看len
n, err = strBuilder.WriteRune('后')
if err != nil {
fmt.Println(err)
}
fmt.Println("写入的长度是:", n) //3
//4.func (b *Builder) WriteString(s string) (int, error)
// 最后一种写入,写入一个字符串
n, err = strBuilder.WriteString("was")
if err != nil {
fmt.Println(err)
}
fmt.Println("写入的长度是:", n) //3 was就三个字母
//5.func (r *Reader) Len() int 查看这个缓存的内部字节长度
l := strBuilder.Len()
fmt.Println("现在缓存长度是:", l) //16
//6.func (b *Builder) Cap() int 查看这个缓存string化之后的容量是多少
l = strBuilder.Cap()
fmt.Println("现在cap是:", l) //16
//7.func (b *Builder) Grow(n int)
strBuilder.Grow(2)
l = strBuilder.Cap()
fmt.Println("现在cap是:", l) //34 这个方法实际上有些无用 34=16*2+2
//8.func (b *Builder) String() string 这个方法实际上是将缓存实体化
str := strBuilder.String()
fmt.Println(str) //你好啊c后was
//9.func (b *Builder) Reset() 缓存归零方法
strBuilder.Reset()
l = strBuilder.Len()
fmt.Println("现在缓存长度是:", l) //0
2.type Reader
涉及到对字符串的读取扫描,比如在Fscanf之类的函数之中
例:
//1.func NewReader(s string) *Reader
// 该方法是创建
reader := strings.NewReader("i am your father")
//2.func (r *Reader) Len() int
n = reader.Len()
fmt.Println(n) //16 空格也算一个字节,但是这个len只是未读取部分的字节
//3.func (r *Reader) Read(b []byte) (n int, err error) 开始读取
// 这个b实际上是一个缓存字节,会读取len(b)的长度,读取到b之中
// 创建一个缓存切片
byteslice := make([]byte, 8)
reader.Read(byteslice)
// fmt.Println(n) //8
// n = reader.Len() //8 现在的未读字节就是八
fmt.Println(string(byteslice)) //i am you
reader.Read(byteslice)
fmt.Println(string(byteslice)) //第二次读取 r father 也就是说我这样的写法byteslice的长度是不能增加的
// 如果我想直接用一个函数读取,那么我应该直接用len获取长度,让后将字节容量设置为这个len
// 注意这里有一个记忆的属性
n = reader.Len()
fmt.Println("hh", n) //0现在就是0了
//4.func (r *Reader) ReadAt(b []byte, off int64) (n int, err error)
// 这个函数也是读取,但是涉及到偏移量的问题
// 创建一个新的字节切片
byteSlice := make([]byte, 8)
reader.ReadAt(byteSlice, 8) //记住这个8实际上是从第九位开始
fmt.Println(string(byteSlice)) //r father
// n = reader.Len() 这个字节未读取的len实际上是由记忆的,,之前只要读取完了,就是0
//5.func (r *Reader) ReadByte() (byte, error)
// 这边我要创建一个新的reader
reader1 := strings.NewReader("father")
n2, _ := reader1.ReadByte()
fmt.Printf("%c\n", n2) //f 实际上这就是一个简单的读取字节,实际上会一个个字节读取
//6.func (r *Reader) ReadRune() (ch rune, size int, err error)
// 这个是一个读取rune
n3, _, _ := reader1.ReadRune() //因为是一个rune,所以需要一个size来表明这个字节的大小
fmt.Printf("%c\n", n3) //a 明显是一个接着读取
//7.func (r *Reader) Reset(s string)
// 这是一个读取重置
reader1.Reset("father")
// n2, _ = reader1.ReadByte() // n2=f重新回到了f
//8.func (r *Reader) Size() int64
n4 := reader1.Size()
fmt.Println(n4) //这个是原本的字节长度,无论是否被读取,也就是说这是len函数的原版
//9.func (r *Reader) Seek(offset int64, whence int) (int64, error)
//seek函数主要是定制化的偏移量读取,offset就是偏移量,whence是开始读取的相对位置
// const (
// SeekStart = 0 // 从reader开头开始
// SeekCurrent = 1 // 从reader已经读取的位置开始
// SeekEnd = 2 // 从reader结尾开始,这个应该不常用吧
// )
reader1.Seek(1, 0)
slice1 := make([]byte, 1)
reader1.Read(slice1)
fmt.Println(string(slice1)) //a
reader1.Read(slice1)
fmt.Println(string(slice1)) //t
//10.func (r *Reader) UnreadByte() error
reader1.UnreadByte()
reader1.Read(slice1) //照理这次读取应该是h,但是这次读取在UnreadByte这个方法后,这个方法后的下一次读取会返回最后一次读取的内容
fmt.Println("ssss", string(slice1)) //t
//11.func (r *Reader) UnreadRune() error
n5, _, _ := reader1.ReadRune()
fmt.Printf("%c\n", n5)
reader1.UnreadRune()
n5, _, _ = reader1.ReadRune()
fmt.Printf("%c\n", n5)
// 这个和上面的使用是一样的,只不过这个要在readrune方法后面使用
//12.func (r *Reader) WriteTo(w io.Writer) (n int64, err error)
// 这个就是将没有读取的内容写入一个writer
n6, _ := reader1.WriteTo(os.Stdout) //er 这个reader1也就er两个字母没有读取了
fmt.Println(n6) //这是写入的字节
3.type Replacer
这个接口的使用有点像正则表达式,用来对一个str内部的一些内容进项替换
例:
// 这个类型实际上是一个字符串的替换
//1.func NewReplacer(oldnew ...string) *Replacer 创建一个新的replacer类型
replace := strings.NewReplacer("<", "<", ">", ">")
//2.func (r *Replacer) Replace(s string) string 调用这个方法将s中的符合要求的字符串替换掉
str1 := replace.Replace("<script>")
fmt.Println(str1) //<script>
//3.func (r *Replacer) WriteString(w io.Writer, s string) (n int, err error)
// 这个方法看起来复杂,实际上是一个写入方法
n, _ = replace.WriteString(os.Stdout, "<水浒传>\n") //空格算一个字符
fmt.Println(n) //实际上会进行输出
// 在写一个
n, _ = replace.WriteString(&strBuilder, "<金瓶梅>\n")
fmt.Println(strBuilder.String(), n)
结尾:有些仓促,有些函数方法的使用情况没有穷尽,先写出来,以后有机会再改