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