下一篇 Go聖經-臨時插入ORM的小trickgolang
Go語言的數據類型分爲四類:基礎類型
、複合類型
、引用類型
和接口類型
。其中數組
int
, uint
、 float
, string
, bool
等結構體
、數組
。它們由一個或者多個元素組成更加複雜的數據結構指針
、slice
、map
、chan
、func
Go語言源文件都是用UTF-8編碼。 一個字符串是一個不可改變的字節序列,相似C++中的字面字符串,只能讀不能寫。網絡
這裏要注意的是len(string)的長度是指存放在內存中的字節數目(而不是rune字符數目)。因此索引操做s[i]表示內存中第i個字節值。數據結構
第i
字節並不必定是第i
個字符,由於對於非ASCII字符的UTF-8編碼會要多兩個或者多個字節。oop
科普一下ASCII、Unicode和UTF-8之間的關係:學習
可是這裏存在一個問題:可能把全世界的字符所有存儲進來,可能字節大小有4~8個字節那麼多,則ASCII的第一個字符只佔用了一個字節,則剩下的3-7個字節都存儲的0值,嚴重浪費空間
,因此須要引入新的編碼方式,儘可能節約內存空間。更多信息,須要本身上網查看。由此,咱們能夠知道,一個字節並不必定表明一個字符。一個rune表示一個字符。ui
若是一個字符串太長,你想要主動換行,能夠用反引號代替雙引號,它裏面的字符沒有轉義操做,同時能夠跨越多行,例如:編碼
// 格式好看的寫法,使用反引號 var buffer bytes.Buffer buffer.WriteString(` SELECT sale_order_id, amount FROM sale_order WHERE company_id=? AND user_id=? AND status=? `) // 格式很差看的寫法,使用雙引號 buffer.WriteString("SELECT sale_order_id, amount FROM sale_order WHERE company_id=? AND user_id=? AND status=?") (*o).Raw(buffer.String(), soId, uId, consts.STATUS_OK).QueryRows(&sos)
上面在打orm的日誌時,前者會格式輸出,易讀美觀。後者是一坨,不清晰,看着日誌比較吃力。.net
對於中文字符串的輸出:
var s:="hello, "世界"
如今要輸出s字符的個數和遍歷s各個字符,須要藉助utf-8標準庫,有兩種方式實現。
第一種方式:
for i:=0;i<len(s);{ r, size:=utf8.RuneCountInString(s[i:]) // 獲取一個字符, 且返回一個字符和字符所佔字節數 fmt.Printf("%d\t%c\n", i, r) i+=size }
第二種方式:
// 這個range是遍歷字符, 隱式解碼 for i, r:= range s{ fmt.Printf("%d\t%c\t%d", i, r, r) }
經常使用的字符串處理的標準庫有四個:bytes
, strings
,strconv
和unicode
, 其中前兩個標準庫比較類似,一個針對比特流,一個針對字符串。舉兩個例子簡單使用一下標準庫: 1. 實現相似linux中的basename命令;2.int型的動態數組字符串輸出;
對於第一個,輸入:basename a/b/c.go
, 輸出:c
func basename(s string) string{ slash:=strings.LastIndex(s, "/") s = s[slash+1:] if dot:= strings.LastIndex(s, "."); dot>=0 { s=s[:dot] } return s }
func intsToString(elems []int) string{ var buffer bytes.Buffer buffer.WriteString("[") for index, elem:= range elems{ if index >0 { buffer.WriteString(", ") } fmt.Fprintf(&buffer, "%d", elem) } buffer.WriteString("]") return buffer.String() } func main(){ fmt.Println(intsToString([]int{1,2,3}) // "[1, 2, 3]" }
初學者可能對iota的使用不是很瞭解,常量聲明可使用iota常量進行初始化,但不是每一行都須要寫一遍初始化表達式。
明白粗體部分的文字,你就秒懂iota的使用方法。在一個const聲明語句中,在第一個聲明的常量所在行,iota=0,而後在每個有常量聲明的行加一操做, 兩個例子:一個表示一週;一個表示網絡的枚舉
type Weekday int const ( Sunday Weekday = iota // iota =0 Monday // iota =1 Tuesday // iota =2 Wednesday Thursday Friday // ...... Saturday // iota = 6 )
type Flags uint const ( FlagUp Flags = 1 << iota // is up FlagBroadcast // supports broadcast access capability FlagLoopback // is a loopback interface FlagPointToPoint // belongs to a point-to-point link FlagMulticast // supports multicast access capability ) // 其實上面表示 xx Flags = 1 << iota, 好比第三行,iota=2;則第三行的常量值等於1<<2 =4。
這樣的解釋和例子,不知道是否明白怎麼樣使用iota常量生成器了。