首選,如果之前使用過redis容器,我們需要先remove掉之前的容器
創(chuàng)新互聯(lián)公司擁有10多年的建站服務(wù)經(jīng)驗,在此期間,我們發(fā)現(xiàn)較多的客戶在挑選建站服務(wù)商前都非常的猶豫。主要問題集中:在無法預(yù)知自己的網(wǎng)站呈現(xiàn)的效果是什么樣的?也無法判斷選擇的服務(wù)商設(shè)計出來的網(wǎng)頁效果自己是否會滿意?創(chuàng)新互聯(lián)公司業(yè)務(wù)涵蓋了互聯(lián)網(wǎng)平臺網(wǎng)站建設(shè)、移動平臺網(wǎng)站制作、網(wǎng)絡(luò)推廣、按需網(wǎng)站建設(shè)等服務(wù)。創(chuàng)新互聯(lián)公司網(wǎng)站開發(fā)公司本著不拘一格的網(wǎng)站視覺設(shè)計和網(wǎng)站開發(fā)技術(shù)相結(jié)合,為企業(yè)做網(wǎng)站提供成熟的網(wǎng)站設(shè)計方案。
然后創(chuàng)建redis容器,并運行
進入redis容器中
接著我們通過 redis-cli 連接測試使用 redis 服務(wù)
setex指令 可以設(shè)置數(shù)據(jù)存在的時間, setex key second value
MSET 一次設(shè)置多個key-value
MGET一次獲取多個key-value
HGET
HGETALL
Hlen和hexist
Lpush 和 Lrange
Lpop和Rpop 從鏈表取出并移走數(shù)據(jù)
刪除鏈表所有數(shù)據(jù) DEL
字符串無序 不能重復(fù)
從連接池中Get出一個conn連接
如果你想輸出的時間是YYYY-MM-DD的話
要在使用json數(shù)據(jù)化之前自己處理時間
type Article struct { Id int Title string CreateTimeStr string}
然后要將之前的時間轉(zhuǎn)過來
Article.CreateTimeStr = Createdatetime.Format("2006-01-02")
最后序列化JSON就是YYYY-MM-DD
這是最簡單的方法
1、 string的定義
Golang中的string的定義在reflect包下的value.go中,定義如下:
StringHeader 是字符串的運行時表示,其中包含了兩個字段,分別是指向數(shù)據(jù)數(shù)組的指針和數(shù)組的長度。
// StringHeader is the runtime representation of a string.
// It cannot be used safely or portably and its representation may
// change in a later release.
// Moreover, the Data field is not sufficient to guarantee the data
// it references will not be garbage collected, so programs must keep
// a separate, correctly typed pointer to the underlying data.
type StringHeader struct {
Data uintptr
Len int
}
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
2、string不可變
Golang中的字符串是不可變的,不能通過索引下標的方式修改字符串中的數(shù)據(jù):
在這里插入圖片描述
運行代碼,可以看到編譯器報錯,string是不可變的
在這里插入圖片描述
但是能不能進行一些騷操作來改變元素的值呢?
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
a := "hello,world"
b := a[6:]
bptr := (*reflect.StringHeader) (unsafe.Pointer(b))
fmt.Println(a)
fmt.Println(b)
*(*byte)(unsafe.Pointer(bptr.Data)) = '.'
fmt.Println(a)
fmt.Println(b)
}
// 運行結(jié)果
hello,world
world
unexpected fault address 0x49d7e3
fatal error: fault
[signal 0xc0000005 code=0x1 addr=0x49d7e3 pc=0x4779fa]
goroutine 1 [running]:
runtime.throw(0x49c948, 0x5)
C:/Program Files/Go/src/runtime/panic.go:1117 +0x79 fp=0xc0000dbe90 sp=0xc0000dbe60 pc=0x405fd9
runtime.sigpanic()
C:/Program Files/Go/src/runtime/signal_windows.go:245 +0x2d6 fp=0xc0000dbee8 sp=0xc0000dbe90 pc=0x4189f6
main.main()
F:/go_workspace/src/code/string_test/main.go:20 +0x13a fp=0xc0000dbf88 sp=0xc0000dbee8 pc=0x4779fa
runtime.main()
C:/Program Files/Go/src/runtime/proc.go:225 +0x256 fp=0xc0000dbfe0 sp=0xc0000dbf88 pc=0x4087f6
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1371 +0x1 fp=0xc0000dbfe8 sp=0xc0000dbfe0 pc=0x435da1
Process finished with the exit code 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
在上面的代碼中,因為在go語言中不能進行指針的加減運算,因此取切片,讓b的Data指針指向’,'所在的位置。然后把"hello,world"中的逗號改為點,但是發(fā)現(xiàn)還是不行,程序直接崩潰了。看來go語言中的指針得到了大大的限制,設(shè)計者并不想讓程序員過度使用指針來寫出一些不安全的代碼。
3、使用string給另一個string賦值
Golang中的字符串的賦值并不是拷貝底層的字符串數(shù)組,而是數(shù)組指針和長度字段的拷貝。例如:當我們定義了一個字符串 a := “hello,world” 然后定義了 b := a 底層所做的操作只是創(chuàng)建了兩個StringHeader的結(jié)構(gòu)體,它們的Data字段都指向同一段數(shù)據(jù),如下圖:
在這里插入圖片描述
我們可以利用代碼來證實這一點:
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
a := "hello,world"
b := a
fmt.Println(a)
fmt.Println(b)
aptr := (*reflect.StringHeader) (unsafe.Pointer(a))
bptr := (*reflect.StringHeader) (unsafe.Pointer(b))
fmt.Println("a ptr:", unsafe.Pointer(aptr.Data))
fmt.Println("b ptr:", unsafe.Pointer(bptr.Data))
}
// 運行結(jié)果
hello, world
hello, world
a ptr: 0x6bdb76
b ptr: 0x6bdb76
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
在上面的代碼中,將a和b轉(zhuǎn)換為StringHeader類型的指針,然后分別打印出,a和b的Data指針的值,發(fā)現(xiàn)是相同的
那么如果對a做切片賦值給b呢?
func main() {
a := "hello,world"
b := a[6:]
fmt.Println(a)
fmt.Println(b)
aptr := (*reflect.StringHeader) (unsafe.Pointer(a))
bptr := (*reflect.StringHeader) (unsafe.Pointer(b))
fmt.Println("a ptr:", unsafe.Pointer(aptr.Data))
fmt.Println("b ptr:", unsafe.Pointer(bptr.Data))
}
// 運行結(jié)果
hello,world
world
a ptr: 0xd4d849
b ptr: 0xd4d84f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
0xd4d849 - 0xd4d84f = 0x000006
顯然,也沒有分配新的數(shù)組并拷貝數(shù)據(jù),而是將原字符數(shù)組的指針的偏移賦給了b的StringHeader的Data
4、string重新賦值
如果對一個已經(jīng)賦值的字符串重新賦值,也不會修改原內(nèi)存空間,而是申請了新的內(nèi)存空間,對其賦值,并指向新的內(nèi)存空間。如下圖:
在這里插入圖片描述
也可以使用代碼來證實一下:
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
a := "hello,world"
aptr := (*reflect.StringHeader) (unsafe.Pointer(a))
fmt.Println("a ptr:", unsafe.Pointer(aptr.Data))
fmt.Println("a len", aptr.Len)
a = "hello,golang"
newAPtr := (*reflect.StringHeader) (unsafe.Pointer(a))
fmt.Println("b ptr:", unsafe.Pointer(newAPtr.Data))
fmt.Println("b len:", newAPtr.Len)
}
// 運行結(jié)果
a ptr: 0x3ed7f4
a len 11
b ptr: 0x3edb2c
b len: 12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
文章知識點與官方知識檔案匹配
Go技能樹九陰真經(jīng)字符串
2043 人正在系統(tǒng)學(xué)習(xí)中
點擊閱讀全文
打開CSDN APP,看更多技術(shù)內(nèi)容
Golang底層原理剖析之string類型與字符編碼_cheems~的博客_g...
string類型 string結(jié)構(gòu) go語言中默認使用的是UTF-8編碼 string由兩部分組成,一部分是指向字符串起始地址的指針,另一部分是字節(jié)個數(shù)len注意不是字符個數(shù),是字節(jié)個數(shù)!這個數(shù)據(jù)類型占用16B空間,指向字符串起始地址的指針和存在字節(jié)個數(shù)的整...
繼續(xù)訪問
...底層系列二(基礎(chǔ))_GoGo在努力的博客_golang string底層
1、 string的定義 Golang中的string的定義在reflect包下的value.go中,定義如下: StringHeader 是字符串的運行時表示,其中包含了兩個字段,分別是指向數(shù)據(jù)數(shù)組的指針和數(shù)組的長度。 // StringHeader is the runtime representation of a...
繼續(xù)訪問
最新發(fā)布 Golang: []string 和 ...string
… 參數(shù)語法形成了可變參數(shù)的參數(shù)。它將接受零個或多個string參數(shù),并將它們作為切片引用
繼續(xù)訪問
常用的Golang字符串(string)操作
文章目錄Golang中常用的字符串操作一、標準庫相關(guān)的Package二、常用字符串操作判斷是否為空字符串 正文 Golang中常用的字符串操作 一、標準庫相關(guān)的Package 二、常用字符串操作 判斷是否為空字符串 思路:直接判斷是否等于""空字符串,由于golang中字符串不能為nil,且為值類型,所以直接與空字符串比較即可 舉例: str := "" if str == ""{...
繼續(xù)訪問
golang中的string_xiaodongdonga的博客_golang ...string
golang中的string 在golang中,string其實是個結(jié)構(gòu)體,如圖 ,在這個結(jié)構(gòu)體中有兩個值,一個是指向字符數(shù)組的指針str,另一個是這個字符串的長度len。 另外在golang中用的是UFT8邊長編碼,里面字母是用一個字節(jié),西方的文字使用兩個字節(jié),...
繼續(xù)訪問
Golang中對字符串string的相關(guān)操作_Codex_97的博客_go 字符...
golang中擁有string的內(nèi)置類型,可以使用與普通slice類型相似的性質(zhì)。 1.簡介 strings包提供了很多操作字符串的簡單函數(shù),通常一般的字符串操作都可以在這個包中找到。 strconv 包提供了基本數(shù)據(jù)類型和字符串之間的轉(zhuǎn)換。在Go 中,沒有隱式...
繼續(xù)訪問
go-string-set:一種在GoLang中創(chuàng)建字符串集的方法
概述 通過字符串設(shè)置方法。 用法 go get github.com/wojnosystems/go-string-set package main import ( "github.com/wojnosystems/go-string-set/string_set" "strings" ) func main () { myPeople := string_set . New () myPeople . Add ( "Bob" ) myPeople . Add ( "Jane" ) myPeople . Add ( "Gary" ) myPeople . Add ( "Bob" ) if myPeople . Exists ( "Bob" ) { // Bob exists in myPeople, so this code block execute
Golang:strings包和字符串操作
strings包 string類型值是不可變的,如果想要獲得一個不一樣的字符串,就只能基于原字符串進行剪裁,拼接等操作,然后將得到的新字符串存放到一塊聯(lián)系內(nèi)存中。 string值包含了指向底層字節(jié)數(shù)組頭部的指針值,以及該字節(jié)數(shù)組的長度。在string值上做切片,就相當于在其底層字節(jié)數(shù)組做切片。 而字符串拼接時(使用+),會把所有被拼接的字符串依次拷貝到一個嶄新且足夠大的連續(xù)內(nèi)存空間中,并把持有新...
繼續(xù)訪問
golang中的strings.SplitN_盼盼編程的博客_strings.splitn
golang中的字符串操作strings.SplitN package main import ( "fmt" "strings" ) //golang字符串操作 func main(){ s := "hello world hello world" //str := "wo" //以str為分隔符,將s切分成多個子串,結(jié)果中**不包含*...
繼續(xù)訪問
Golang_String常用操作_itzhuzhu.的博客_golang strings
func main() { var x string = "ITzhuzhu" var y string = "itzhuzhu" fmt.Println(strings.EqualFold(x, y)) //true fmt.Println(x == y) //false } 1 2 3 4 5 6 返回子串在字符串第一次出現(xiàn)的索引,如果沒有則...
繼續(xù)訪問
Golang類型的String()方法
作用 用于定制fmt.Println(x)、fmt.Printf("%v", x)、fmt.Print(x)時輸出的內(nèi)容。 示例 package main import "fmt" type Couple struct { Husband string Wife string } func (self Couple) String() string { return "(husband:" + self.Husband + ", wife:" + self.Wife +
繼續(xù)訪問
golang的string
golang中的string是不可變的字節(jié)序列,零值是空字符串,默認是UTF-8編碼。 golang中使用字符串最需要注意的是,golang中的字符串是字節(jié)序列,string == []byte,由于一個字符占用的字節(jié)數(shù)不確定,所以無法通過下標[i]的方式穩(wěn)定地獲取對應(yīng)位置的字符。 也就意味著字符串的第i個字節(jié),不一定就是第i個字符,原因請參考 unicode與UTF-8 文字符號在golang中被稱為rune,發(fā)音為/ru:n/,意思是符號。由于utf-8最多使用4個字節(jié)來編碼,所以rune類型是int3
繼續(xù)訪問
golang中的strings.Trim_盼盼編程的博客_strings.trim
golang中的字符串操作strings.Trim package main import ( "fmt" "strings" ) //golang字符串操作 func main(){ s := "Hello world hello world" str := "world" //var s = []string{"11","22","33"} //刪除s首尾...
繼續(xù)訪問
Golang 字符串
Go語言的代碼是由Unicode字符組成的,它們都必須由Unicode編碼規(guī)范中的UTF-8編碼格式進行編碼并存儲,Unicode編碼規(guī)范中的編碼格式定義的是字符與字節(jié)序列之間的轉(zhuǎn)換方式。其中的UTF-8是一種可變寬的編碼方案,它會用一個或多個字節(jié)的二進制數(shù)來表示某個字符,最多使用四個字節(jié)。Go語言中的一個string類型值會由若干個Unicode字符組成,每個Unicode字符都可以由一個rune類型的值來承載。stringforrange。...
繼續(xù)訪問
golang字符串[]string(slice)去重
1、現(xiàn)實代碼 // []string 去重 func RemoveDuplicate(list []string) []string { // 這個排序很關(guān)鍵 sort.Strings(list) i := 0 var newlist = []string{""} for j := 0; j len(list); j++ { if strings.Compare(newlist[i], list[j]) == -1 { newlist = append(newlist, lis
繼續(xù)訪問
深入理解golang string
golang string string的定義 // string is the set of all strings of 8-bit bytes, conventionally but not // necessarily representing UTF-8-encoded text. A string may be empty, but // not nil. Values of string type are immutable. type string string string里存儲的是字符
繼續(xù)訪問
golang中string包
對于基本類型來說,字符串所需要執(zhí)行的操作會比較復(fù)雜,所以一般語言都會額外封裝一些方法用于處理字符串,go語言標準庫中也存在這樣一個名為strings的庫 包含判斷,判斷一個字符中是否有相應(yīng)的某個子字符串是經(jīng)常遇到的一種字符串操作,再go語言中可以使用strings包中的兩個方法判斷 ...
繼續(xù)訪問
golang中的strings.TrimLeft
golang中的字符串操作strings.TrimLeft package main import ( "fmt" "strings" ) //golang字符串操作 func main(){ s := "Hello world hello world" str := "Hello" //var s = []string{"11","22","33"} //刪除s頭部連續(xù)的包含在str中的字符串 .
繼續(xù)訪問
golang入門time與string轉(zhuǎn)換, time加減時間, 兩個時間差
package mainimport ( "fmt" "time")var timeLayoutStr = "2006-01-02 15:04:05" //go中的時間格式化必須是這個時間//var timeLayoutStr = 2006/01/02 03:04:05 //合法, 格式可以改變//var timeLayoutStr = 2019/01/02 15:04:05 /...
繼續(xù)訪問
Golang——string
1.string結(jié)構(gòu)體底層 由兩部分組成:指向底層[ ]byte數(shù)組的指針;長度(類似切片結(jié)構(gòu)體) 2.相同的string常量不會重復(fù)存儲 //由s1、s2的指針指向一塊相同的只讀內(nèi)存,這段內(nèi)存以utf-8編碼存放hello數(shù)組 s1 := "hello" s2 := "hello" 3.string常量會在編譯期分配到只讀段,對應(yīng)數(shù)據(jù)地址不可寫入,故string不支持修改。 要修改必須轉(zhuǎn)[]byte,string和[]byte轉(zhuǎn)換,會將這段只讀內(nèi)存的數(shù)據(jù)復(fù)制到堆/棧上。 //wrong s := "he
繼續(xù)訪問
熱門推薦 golang -----------字符串(rune,string,type)
一、內(nèi)存布局 字符串在Go語言內(nèi)存模型中用一個2字長的數(shù)據(jù)結(jié)構(gòu)表示。它包含一個指向字符串存儲數(shù)據(jù)的指針和一個長度數(shù)據(jù)。因為string類型是不可變的,對于多字符串共享同一個存儲數(shù)據(jù)是安全的。切分操作str[i:j]會得到一個新的2字長結(jié)構(gòu),一個可能不同的但仍指向同一個字節(jié)序列(即上文說的存儲數(shù)據(jù))的指針和長度數(shù)據(jù)。這意味著字符串切分可以在不涉及內(nèi)存分配或復(fù)制操作。這使得字符串切分的效率等同于...
繼續(xù)訪問
Golang string 常用方法
strings.Compare(p1, p2) 判斷p1是否大于p2,大于:1,小于:-1,等于:0。2.strings.LastIndex(p1,p2) p2在p1中最后一次出現(xiàn)的位置,未出現(xiàn)返回-1。1.strings.Replace(p1,p2,p3,n) 將p1中的p2替換成p3,最多替換n個。1.strings.Index(p1,p2) p2在p1中第一次出現(xiàn)的位置,未出現(xiàn)返回-1。2.strings.ReplaceAll(p1,p2,p3) 將p1中的所有p2替換成p3。
繼續(xù)訪問
golang中的字符串
在go中rune是一個unicode編碼點。 我們都知道UTF-8將字符編碼為1-4個字節(jié),比如我們常用的漢字,UTF-8編碼為3個字節(jié)。所以rune也是int32的別名。
繼續(xù)訪問
golang之字符串
Go語言的字符有兩種類型: 一種是byte型,或者叫uint8類型,代表了ASCII碼的一個字符。 一種是rune類型,或者叫int32類型,代表一個UTF-8字符,當需要處理中文、日文等unicode字符時,則需要用到rune類型。 ...
繼續(xù)訪問
Golang的 string 類型
一點睛 字符串就是一串固定長度的字符連接起來的字符序列。Go 的字符串是由單個字節(jié)連接起來的。Go語言的字符串的字節(jié)使用 UTF-8 編碼標識 Unicode 文本。 二 string 使用注意事項和細節(jié) 1 Go 語言的字符串的字節(jié)使用 UTF-8 編碼標識 Unicode 文本,這樣 Golang 統(tǒng)一使用 UTF-8 編碼,中文亂碼問題不會再困擾程序員。 2 字符串一旦賦值了,字符串就不能修改了,在 Go 中字符串是不可變的。 3 字符串的兩種表示形式。 a 雙引號——會識別轉(zhuǎn)義字符 .
繼續(xù)訪問
Golang Strings 官方包常用方法,學(xué)會這些夠用了
1.判斷是否以某字符串打頭/結(jié)尾 2.字符串分割 3.返回子串索引 4.字符串連接 5.字符串轉(zhuǎn)化為大小寫 6.統(tǒng)計某個字符在字符串出現(xiàn)的次數(shù) 7.判斷字符串的包含關(guān)系 8.字符串替換
Go語言作為出現(xiàn)比較晚的一門編程語言,在其原生支持高并發(fā)、云原生等領(lǐng)域的優(yōu)秀表現(xiàn),像目前比較流行的容器編排技術(shù)Kubernetes、容器技術(shù)Docker都是用Go語言寫的,像Java等其他面向?qū)ο蟮恼Z言,雖然也能做云原生相關(guān)的開發(fā),但是支持的程度遠沒有Go語言高,憑借其語言特性和簡單的編程方式,彌補了其他編程語言一定程度上的不足,一度成為一個熱門的編程語言。
最近在學(xué)習(xí)Go語言,我之前使用過C#、Java等面向?qū)ο缶幊痰恼Z言,發(fā)現(xiàn)其中有很多的編程方式和其他語言有區(qū)別的地方,好記性不如爛筆頭,總結(jié)一下,和其他語言做個對比。這里只總結(jié)差異的地方,具體的語法不做詳細的介紹。
種一棵樹最好的時間是十年前,其次是現(xiàn)在。
3)變量初始化時候可以和其他語言一樣直接在變量后面加等號,等號后面為要初始化的值,也可以使用變量名:=變量值的簡單方式
3)變量賦值 Go語言的變量賦值和多數(shù)語言一致,但是Go語言提供了多重賦值的功能,比如下面這個交換i、j變量的語句:
在不支持多重賦值的語言中,交換兩個變量的值需要引入一個中間變量:
4)匿名變量
在使用其他語言時,有時候要獲取一個值,卻因為該函數(shù)返回多個值而不得不定義很多沒有的變量,Go語言可以借助多重返回值和匿名變量來避免這種寫法,使代碼看起來更優(yōu)雅。
假如GetName()函數(shù)返回3個值,分別是firstName,lastName和nickName
若指向獲得nickName,則函數(shù)調(diào)用可以這樣寫
這種寫法可以讓代碼更清晰,從而大幅降低溝通的復(fù)雜度和維護的難度。
1)基本常量
常量使用關(guān)鍵字const 定義,可以限定常量類型,但不是必須的,如果沒有定義常量的類型,是無類型常量
2)預(yù)定義常量
Go語言預(yù)定義了這些常量 true、false和iota
iota比較特殊,可以被任務(wù)是一個可被編譯器修改的常量,在每個const關(guān)鍵字出現(xiàn)時被重置為0,然后在下一個const出現(xiàn)之前每出現(xiàn)一個iota,其所代表的數(shù)字會自動加1.
3)枚舉
1)int 和int32在Go語言中被認為是兩種不同類型的類型
2)Go語言定義了兩個浮點型float32和float64,其中前者等價于C語言的float類型,后者等價于C語言的double類型
3)go語言支持復(fù)數(shù)類型
復(fù)數(shù)實際上是由兩個實數(shù)(在計算機中使用浮點數(shù)表示)構(gòu)成,一個表示實部(real)、一個表示虛部(imag)。也就是數(shù)學(xué)上的那個復(fù)數(shù)
復(fù)數(shù)的表示
實部與虛部
對于一個復(fù)數(shù)z=complex(x,y),就可以通過Go語言內(nèi)置函數(shù)real(z)獲得該復(fù)數(shù)的實部,也就是x,通過imag(z)獲得該復(fù)數(shù)的虛部,也就是y
4)數(shù)組(值類型,長度在定義后無法再次修改,每次傳遞都將產(chǎn)生一個副本。)
5)數(shù)組切片(slice)
數(shù)組切片(slice)彌補了數(shù)組的不足,其數(shù)據(jù)結(jié)構(gòu)可以抽象為以下三個變量:
6)Map 在go語言中Map不需要引入任何庫,使用很方便
Go循環(huán)語句只支持for關(guān)鍵字,不支持while和do-while
goto語句的語義非常簡單,就是跳轉(zhuǎn)到本函數(shù)內(nèi)的某個標簽
今天就介紹到這里,以后我會在總結(jié)Go語言在其他方面比如并發(fā)編程、面向?qū)ο?、網(wǎng)絡(luò)編程等方面的不同及使用方法。希望對大家有所幫助。
golang在1.6.2的時候還沒有自己的context,在1.7的版本中就把golang.org/x/net/context包被加入到了官方的庫中。中文譯作“上下文”,它主要包含了goroutine 的運行狀態(tài)、環(huán)境等信息。
context 主要用來在 goroutine 之間傳遞上下文信息,包括:同步信號、超時時間、截止時間、請求相關(guān)值等。
該接口定義了四個需要實現(xiàn)的方法:
如果有個網(wǎng)絡(luò)請求Request,然后這個請求又可以開啟多個goroutine做一些事情,當這個網(wǎng)絡(luò)請求出現(xiàn)異常和超時時,這個請求結(jié)束了,這時候就可以通過context來跟蹤這些goroutine,并且通過Context來取消他們,然后系統(tǒng)才可回收所占用的資源。
為了更方便的創(chuàng)建Context,包里頭定義了Background來作為所有Context的根,它是一個emptyCtx的實例。
Background返回一個非空的Context。它永遠不會被取消。它通常用來初始化和測試使用,作為一個頂層的context,也就是說一般我們創(chuàng)建的context都是基于Background。
TODO返回一個非空的Context。當不清楚要使用哪個上下文的時候可以使用TODO。
他們兩個本質(zhì)上都是emptyCtx結(jié)構(gòu)體類型,是一個不可取消,沒有設(shè)置截止時間,沒有攜帶任何值的Context。
有了如上的根Context,那么是如何衍生更多的子Context的呢?這就要靠context包為我們提供的With系列的函數(shù)了。
通過這些函數(shù),就創(chuàng)建了一顆Context樹,樹的每個節(jié)點都可以有任意多個子節(jié)點,節(jié)點層級可以有任意多個。
WithCancel函數(shù),最常用的派生 context 方法。該方法接受一個父 context。父 context 可以是一個 background context 或其他 context。
WithDeadline函數(shù),該方法會創(chuàng)建一個帶有 deadline 的 context。當 deadline 到期后,該 context 以及該 context 的可能子 context 會受到 cancel 通知。另外,如果 deadline 前調(diào)用 cancelFunc 則會提前發(fā)送取消通知。
WithTimeout和WithDeadline基本上一樣,這個表示是超時自動取消,是多少時間后自動取消Context的意思。
WithValue函數(shù)和取消Context無關(guān),它是為了生成一個綁定了一個鍵值對數(shù)據(jù)的Context,這個綁定的數(shù)據(jù)可以通過Context.Value方法訪問到,一般我們想要通過上下文來傳遞數(shù)據(jù)時,可以通過這個方法,如我們需要tarce追蹤系統(tǒng)調(diào)用棧的時候。
使用Context的程序應(yīng)遵循以下規(guī)則,以使各個包之間的接口保持一致:
1.不要將 Context 塞到結(jié)構(gòu)體里。直接將 Context 類型作為函數(shù)的第一參數(shù),而且一般都命名為 ctx。
2.不要向函數(shù)傳入一個 nil 的 context,如果你實在不知道傳什么,標準庫給你準備好了一個 context:todo。
3.不要把本應(yīng)該作為函數(shù)參數(shù)的類型塞到 context 中,context 存儲的應(yīng)該是一些共同的數(shù)據(jù)。例如:登陸的 session、cookie 等。
4.同一個 context 可能會被傳遞到多個 goroutine,別擔心,context 是并發(fā)安全的。
是說?20060102150405 這個嗎,原因大致如下:
可讀性高,所見即所得
實現(xiàn)簡單,排除二義性(15或3代表時,4代表分,5代表秒,06或2006代表年)
請參考源代碼:
187 case?'3':
188 return?layout[0:i],?stdHour12,?layout[i+1:]
189
190 case?'4':
191 return?layout[0:i],?stdMinute,?layout[i+1:]
192
193 case?'5':
194 return?layout[0:i],?stdSecond,?layout[i+1:]
195