golang学习笔记(四)
strings与strconv
strings包提供字符串常用操作函数:
- strings.HasPrefix(s, prefix string) bool
判断s是否匹配前缀prefix - strings.HasSuffix(s, suffix string) bool
判断s是否匹配后缀suffix - strings.Contains(s, substr string) bool
判断s是否包含子字符串substr - strings.Index(s, str string) int
返回s中str第一次出现的下标,没有返回-1 - strings.LastIndex(s, str string) int
返回s中str最后一次出现的下标,没有返回-1 - strings.Replace(str, old, new, n) string
将str中的前n个old子字符串替换为new,如果n是-1代表全部替换 - strings.Count(s, str string) int
统计s中str子串出现的概率 - strings.Repeat(s, count int) string
返回一个count个s顺序拼接的新字符串 - strings.ToLower(s) string
返回s转为小写的字符串 - strings.ToUpper(s) string
返回s转为大写的字符串 - strings.Split(s, sep) []string
返回s按照sep作为切割符得到的slice - strings.Fields(s) []string
返回s按照空白(一个或者多个空格)进行切割得到的slice - strings.Join(sl []string, sep string) string
返回sl这个字符串slice使用sep作为分隔符连接得到的新字符串
strconv提供字符串类型与其他类型相互转化的函数:
- strconv.Itoa(i int) string
返回整数i的十进制字符串表示 - strconv.Atoi(s string) (i int, err error)
返回十进制字符串s的整数表示 - strconv.ParseFloat(s string, bitSize int) (f float64, err error)
返回bitSize型的浮点型数字字符串s的float64表示
reflect
-
TypeOf和ValueOf
reflect包中提供了运行时反射的一些库:-
func TypeOf(i interface{}) Type
TypeOf方法返回一个对象的类型 -
func ValueOf(i interface{}) Value
ValueOf方法返回一个对象的Value, Value 有一个 Type 方法返回 reflect.Value 的 Type。
Type 和 Value 都有 Kind 方法返回一个常量来表示类型
Value 有叫做 Int 和 Float 等的方法可以获取存储在内部的值type MyInt int var m MyInt = 5 v := reflect.ValueOf(m) v.Kind() //reflect.Int v.Int() //5
-
-
反射修改基本类型
如果在ValueOf中传递的不是地址,则得到的是一个非指针对象,是只读类型
当我们通过ValueOf传递地址时,得到的value对象是指针对象,与原对象有密切关系
指针对象因为安全原因,不允许使用setXXX进行修改,所以需要通过Elem方法获得该指针对象对应的值对象(此对象基本等价于原始对象,在其上的修改也回作用到原始对象上),此时的值对象既可以进行set修改值
可以通过value的CanSet方法判断,其是否允许修改操作,如var x float64 = 3.4 v := reflect.ValueOf(&x) v = v.Elem() v.SetFloat(1.25) println(v.Float()) //1.25 println(x) //1.25
-
反射修改结构类型
- NumField() int 方法返回Value对象结构内的字段数量
- Field(n int) Value 方法返回Value对象结构内,第n个(n从0开始)成员的Value对象
- Method(n) Value 方法返回Value对象结构外,第n个(n从0开始)外部方法的Value对象
如果Value对象是一个方法对象,则可以通过Call方法进行调用,传递参数为Value类型的slic,代表方法形参,函数返回值也是一组Value对象slice
需要注意的是,结构类型的成员(结构内与结构外),只有以大写字母开头的字段或者方法,才能被反射调用和修改,大写开头的字段代表为公开字段,否则代表不能反射修改的字段func (v Value) Call(in []Value) []Value {
比如
package main; import "reflect" type A struct{ InnerFunc func() Num int } func(a A) Read(){ println("call read") } func main(){ a := A{ InnerFunc: func(){ println("call innerFunc") }, Num: 9, } v := reflect.ValueOf(&a).Elem() println(v.NumField())// 2 v.Field(0).Call(nil) //call innerFunc v.Method(0).Call(nil) //call read println(v.Field(1).Int()) //9 v.Field(1).SetInt(0) println(v.Field(1).Int()) //0 }
select
golang中的管道类型经常用于协程的协调上,select可以实现对管道事件的监控,在对应事件触发时,执行对应事件(其会在没有管道事件触发时阻塞,直到监听的管道事件之一触发的时候唤醒执行对应事件),比如
//ch1和ch2都是chan类型
select {
case u:= <- ch1:
...
case v:= <- ch2:
...
...
default: // no value ready to be received
...
}
一般通过select来处理协程的调度,而不使用for循环,可以降低性能损耗
更多文章,请搜索公众号歪歪梯Club