• 协程

代码如下:

package mainimport "fmt"func f(from string){for i:=0;i<3;i++{fmt.Println(from,":",i)}
}func main(){f("direct")go f("goroutine")go func(msg string){fmt.Println(msg)}("going")var input stringfmt.Scanln(&input)fmt.Println("done")
}

结果如下:

direct : 0
direct : 1
direct : 2
goroutine : 0
going
goroutine : 1
goroutine : 2

done

  • 通道

代码如下:

package mainimport "fmt"func main(){messages := make(chan string)go func(){messages <- "ping"}()//也可以用通道缓冲//messages := make(chan string, 1)//messages <- "ping"msg := <-messagesfmt.Println(msg)
}

结果如下:

ping

  • 通道缓冲

代码如下:

package mainimport ("fmt"
)func main(){messages := make(chan string,2)messages <- "buffered"messages <- "channel"fmt.Println(<-messages)fmt.Println(<-messages)
}

结果如下:

buffered
channel

  • 通道同步

代码如下:

package mainimport ("fmt""time"
)func worker(done chan bool){fmt.Println("working...")time.Sleep(time.Second)fmt.Println("done")done <- true
}func main(){done := make(chan bool)go worker(done)//也可以用通道缓冲//done := make(chan bool, 1)//worker(done)<-done
}

结果如下:

working...
done

  • 通道选择器

代码如下:

package mainimport ("fmt""time"
)func main(){ch1 := make(chan string)ch2 := make(chan string)go func(){time.Sleep(time.Second)ch1 <- "one"}()go func(){time.Sleep(time.Second*2)ch2 <- "two"}()for i:=0;i<2;i++{select {case msg1 := <- ch1:fmt.Println("received",msg1)case msg2 := <- ch2:fmt.Println("received",msg2)}}
}

结果如下:

received one
received two

  • 超时处理

代码如下:

package mainimport ("fmt""time"
)func main(){c1 := make(chan string)go func(){time.Sleep(time.Second*2)c1 <- "result1"}()select {case res := <- c1:fmt.Println(res)case <- time.After(time.Second):fmt.Println("timeout1")}c2 := make(chan string)go func(){time.Sleep(time.Second)c2 <- "result2"}()select {case res := <- c2:fmt.Println(res)case <- time.After(time.Second*2):fmt.Println("timeout2")}
}

结果如下:

timeout1
result2

  • 非阻塞通道操作

代码如下:

package mainimport "fmt"func main(){messages := make(chan string)//若有通道缓冲,则能够收到signals := make(chan string)select {case msg := <- messages:fmt.Println("received message",msg)default:fmt.Println("no messages received")}msg := "hi"select {case messages <- msg:fmt.Println("sent message",msg)default:fmt.Println("no messages sent")}select {case msg := <- messages:fmt.Println("received message",msg)case sig := <- signals:fmt.Println("received signal",sig)default:fmt.Println("no activity")}
}

结果如下:

no messages received
no messages sent
no activity

  • 通道的关闭​​​​​​​

代码如下:

package mainimport "fmt"func main(){jobs := make(chan int, 5)done := make(chan bool)go func(){for{value, more := <- jobsif more{fmt.Println("received job",value)}else{fmt.Println("received all jobs")done <- truereturn}}}()for i:=1;i<=3;i++{jobs <- ifmt.Println("sent job",i)}close(jobs)fmt.Println("sent all jobs")<-done
}

结果如下:

sent job 1
received job 1
received job 2
sent job 2
sent job 3
sent all jobs
received job 3
received all jobs

  • 通道遍历​​​​​​​

代码如下:

package mainimport "fmt"func main(){queue := make(chan string, 2)queue <- "one"queue <- "two"close(queue)for elem := range queue{fmt.Println(elem)}
}

结果如下:

one
two

  • 定时器​​​​​​​

代码如下:

package mainimport ("fmt""time"
)func main(){timer1 := time.NewTimer(time.Second)<-timer1.Cfmt.Println("Timer1 expired")timer2 := time.NewTimer(time.Second)go func(){<-timer2.Cfmt.Println("Timer2 expired")}()timer2.Stop()fmt.Println("Timer2 stopped")
}

结果如下:

Timer1 expired
Timer2 stopped

  • 打点器​​​​​​​

代码如下:

package mainimport ("fmt""time"
)func main(){ticker := time.NewTicker(time.Millisecond*500)go func(){for i := range ticker.C{fmt.Println("Tick at",i)}}()time.Sleep(time.Millisecond*1600)ticker.Stop()fmt.Println("Ticker stopped")
}

结果如下:

Tick at 2018-11-22 11:11:08.8536293 +0800 CST m=+0.506127601
Tick at 2018-11-22 11:11:09.3536449 +0800 CST m=+1.006143201
Tick at 2018-11-22 11:11:09.8539063 +0800 CST m=+1.506404601
Ticker stopped

  • 工作池​​​​​​​

代码如下:

package mainimport ("fmt""time"
)func worker(id int, jobs <-chan int, results chan<- int){for i := range jobs{fmt.Println("worker",id,"processing job",i)time.Sleep(time.Second)results <- i*2}
}func main() {jobs := make(chan int, 100)results := make(chan int, 100)for m:=1;m<=3;m++{go worker(m,jobs,results)}for i:=1;i<=9;i++{jobs <- i}close(jobs)for j:=1;j<=9;j++{<- results}
}

结果如下:

worker 2 processing job 2
worker 1 processing job 1
worker 3 processing job 3
worker 1 processing job 4
worker 2 processing job 5
worker 3 processing job 6
worker 2 processing job 7
worker 1 processing job 8
worker 3 processing job 9

  • 速率限制

代码如下:

package mainimport ("fmt""time"
)func main() {requests := make(chan int,5)for i:=1;i<=5;i++{requests <- i}close(requests)limiter := time.Tick(time.Millisecond*200)for req := range requests{<-limiterfmt.Println("request",req,time.Now())}burstyLimiter := make(chan time.Time,3)for i:=1;i<=3;i++{burstyLimiter <- time.Now()}go func() {t := time.Tick(time.Millisecond*200)for i := range t{burstyLimiter <- i}}()burstyRequests := make(chan int,5)for j:=1;j<=5;j++{burstyRequests <- j}close(burstyRequests)for req := range burstyRequests{<- burstyLimiter//tn := <- burstyLimiterfmt.Println("request",req,time.Now())//fmt.Println("request",req,tn)}
}

结果如下:

request 1 2018-11-22 13:31:12.5932522 +0800 CST m=+0.208619801
request 2 2018-11-22 13:31:12.793778 +0800 CST m=+0.409145601
request 3 2018-11-22 13:31:12.9931922 +0800 CST m=+0.608559801
request 4 2018-11-22 13:31:13.1937051 +0800 CST m=+0.809072801
request 5 2018-11-22 13:31:13.393264 +0800 CST m=+1.008631601
request 1 2018-11-22 13:31:13.393264 +0800 CST m=+1.008631601
request 2 2018-11-22 13:31:13.393264 +0800 CST m=+1.008631601
request 3 2018-11-22 13:31:13.393264 +0800 CST m=+1.008631601
request 4 2018-11-22 13:31:13.5933922 +0800 CST m=+1.208759901
request 5 2018-11-22 13:31:13.7938431 +0800 CST m=+1.409210701

  • 原子计数器
package mainimport ("fmt""runtime""sync/atomic""time"
)func main() {var ops uint64 = 0for i:=0;i<50;i++{go func() {for{atomic.AddUint64(&ops,1)runtime.Gosched()//让出CPU时间片}}()}time.Sleep(time.Second)opsFinal := atomic.LoadUint64(&ops)fmt.Println("ops:",opsFinal)
}

结果如下:

ops: 3139216

  • 互斥锁

代码如下:

package mainimport ("fmt""math/rand""runtime""sync""sync/atomic""time"
)func main() {var state = make(map[int]int)var mutex = &sync.Mutex{}var ops uint64 = 0for m:=0;m<10;m++{go func() {for{key := rand.Intn(5)val := rand.Intn(100)mutex.Lock()state[key]=valmutex.Unlock()atomic.AddUint64(&ops,1)runtime.Gosched()}}()}time.Sleep(time.Second)opsFinal := atomic.LoadUint64(&ops)fmt.Println("ops:",opsFinal)mutex.Lock()fmt.Println(state)mutex.Unlock()
}

结果如下:

ops: 2072334
map[1:65 0:85 2:25 4:65 3:54]

  • Go状态协程​​​​​​​

代码如下:

package mainimport ("fmt""math/rand""sync/atomic""time"
)type readOp struct {key  intresp chan int
}
type writeOp struct {key  intval  intresp chan bool
}func main() {var ops uint64reads := make(chan *readOp)writes := make(chan *writeOp)go func() {var state = make(map[int]int)for{select {case read := <- reads:read.resp <- state[read.key]case write := <- writes:state[write.key] = write.valwrite.resp <- true}}}()for r:=0;r<100;r++{go func() {for {read := &readOp{rand.Intn(5),make(chan int)}reads <- read<-read.respatomic.AddUint64(&ops, 1)}//runtime.Gosched()}()}for w:=0;w<10;w++{go func() {for{write := &writeOp{rand.Intn(5),rand.Intn(100),make(chan bool)}writes <- write<- write.respatomic.AddUint64(&ops,1)}//runtime.Gosched()}()}time.Sleep(time.Second)opsFinal := atomic.LoadUint64(&ops)fmt.Println("ops:",opsFinal)
}

结果如下:

ops: 601082

  • 排序​​​​​​​

代码如下:

package mainimport ("fmt""sort"
)func main() {strs := []string{"c","a","b"}sort.Strings(strs)fmt.Println("strings:",strs)ints := []int{7,2,4}sort.Ints(ints)fmt.Println("ints:",ints)s := sort.IntsAreSorted(ints)fmt.Println("sorted",s)
}

结果如下:

strings: [a b c]
ints: [2 4 7]
sorted true

  • 使用函数自定义排序​​​​​​​
package mainimport ("fmt""sort"
)type ByLength []stringfunc (s ByLength) Len() int{return len(s)
}func (s ByLength) Less(i,j int) bool{return len(s[i])<len(s[j])
}func (s ByLength) Swap(i,j int) {s[i], s[j] = s[j], s[i]
}func main(){s := []string{"hanmingyu","hanmy","hmy"}sort.Sort(ByLength(s))fmt.Println(s)
}

结果如下:

[hmy hanmy hanmingyu]

  • Panic​​​​​​​
package mainimport "os"func main(){panic("a problem")_,err := os.Create("/tmp/file")if err != nil{panic(err)}
}

结果如下:

panic: a problem

goroutine 1 [running]:
main.main()
    D:/GOPATH/src/awesomeProject/example/main/main.go:6 +0x40

Process finished with exit code 2

  • Defer​​​​​​​

代码如下:

package mainimport ("fmt""os"
)func main(){f := createFile("D:/GOPATH/src/awesomeProject/example/main/defer.txt")defer closeFile(f)writeFile(f)
}func createFile(p string) *os.File{fmt.Println("creating")f,err := os.Create(p)if err!=nil{panic(err)}return f
}func writeFile(f *os.File){fmt.Println("writing")fmt.Fprintln(f,"data")
}func closeFile(f *os.File){fmt.Println("closing")f.Close()
}

结果如下:

creating
writing
closing

  • 组合函数​​​​​​​

代码如下:

package mainimport ("fmt""strings"
)//返回目标字符串 t 出现的的第一个索引位置,或者在没有匹配值时返回 -1。
func Index(vs []string, t string) int{for i,v := range vs{if v==t{return i}}return -1
}//如果目标字符串 t 在这个切片中则返回 true。
func Include(vs []string, t string) bool{return Index(vs,t)>=0
}//如果这些切片中的字符串有一个满足条件 f 则返回true。
func Any(vs []string, f func(string) bool) bool{for _,v := range vs{if f(v){return true}}return false
}//如果切片中的所有字符串都满足条件 f 则返回 true。
func All(vs []string, f func(string) bool) bool{for _,v := range vs{if !f(v){return false}}return true
}//返回一个包含所有切片中满足条件 f 的字符串的新切片。
func Filter(vs []string, f func(string) bool) []string{s := []string{}//s := make([]string,0)for _,v := range vs{if f(v){s = append(s,v)}}return s
}//返回一个对原始切片中所有字符串执行函数 f 后的新切片。
func Map(vs []string, f func(string) string) []string{s := []string{}//s := make([]string,0)for _,v := range vs{s = append(s,f(v))}return s
}func main() {var strs = []string{"peach", "apple", "pear", "plum"}fmt.Println(Index(strs, "pear"))fmt.Println(Include(strs, "grape"))fmt.Println(Any(strs, func(v string) bool {return strings.HasPrefix(v, "p")}))fmt.Println(All(strs, func(v string) bool {return strings.HasPrefix(v, "p")}))fmt.Println(Filter(strs, func(v string) bool {return strings.Contains(v, "e")}))fmt.Println(Map(strs, strings.ToUpper))
}

结果如下:

2
false
true
false
[peach apple pear]
[PEACH APPLE PEAR PLUM]

  • 字符串函数​​​​​​​

代码如下:

package mainimport "fmt"
import s "strings"var p = fmt.Printlnfunc main(){p("Contains:  ", s.Contains("test", "es"))p("Count:     ", s.Count("test", "t"))p("HasPrefix: ", s.HasPrefix("test", "te"))p("HasSuffix: ", s.HasSuffix("test", "st"))p("Index:     ", s.Index("test", "e"))p("Join:      ", s.Join([]string{"a", "b"}, "-"))p("Repeat:    ", s.Repeat("a", 5))p("Replace:   ", s.Replace("foo", "o", "0", -1))p("Replace:   ", s.Replace("foo", "o", "0", 1))p("Split:     ", s.Split("a-b-c-d-e", "-"))p("ToLower:   ", s.ToLower("TEST"))p("ToUpper:   ", s.ToUpper("test"))p()p("Len: ", len("hello"))p("Char:", "hello"[1])
}

结果如下:

Contains:   true
Count:      2
HasPrefix:  true
HasSuffix:  true
Index:      1
Join:       a-b
Repeat:     aaaaa
Replace:    f00
Replace:    f0o
Split:      [a b c d e]
ToLower:    test
ToUpper:    TEST

Len:  5
Char: 101

  • 字符串格式化​​​​​​​
package mainimport ("fmt""os"
)type point struct {x,y int
}func main(){//Go 为常规 Go 值的格式化设计提供了多种打印方式。例如,这里打印了 point 结构体的一个实例。p := point{1, 2}fmt.Printf("%v\n", p)//如果值是一个结构体,%+v 的格式化输出内容将包括结构体的字段名。fmt.Printf("%+v\n", p)//%#v 形式则输出这个值的 Go 语法表示。例如,值的运行源代码片段。fmt.Printf("%#v\n", p)//需要打印值的类型,使用 %T。fmt.Printf("%T\n", p)//格式化布尔值是简单的。fmt.Printf("%t\n", true)//格式化整形数有多种方式,使用 %d进行标准的十进制格式化。fmt.Printf("%d\n", 123)//这个输出二进制表示形式。fmt.Printf("%b\n", 14)//这个输出给定整数的对应字符。fmt.Printf("%c\n", 33)//%x 提供十六进制编码。fmt.Printf("%x\n", 456)//对于浮点型同样有很多的格式化选项。使用 %f 进行最基本的十进制格式化。fmt.Printf("%f\n", 78.9)//%e 和 %E 将浮点型格式化为(稍微有一点不同的)科学技科学记数法表示形式。fmt.Printf("%e\n", 123400000.0)fmt.Printf("%E\n", 123400000.0)//使用 %s 进行基本的字符串输出。fmt.Printf("%s\n", "\"string\"")//像 Go 源代码中那样带有双引号的输出,使用 %q。fmt.Printf("%q\n", "\"string\"")//和上面的整形数一样,%x 输出使用 base-16 编码的字符串,每个字节使用 2 个字符表示。fmt.Printf("%x\n", "hex this")//要输出一个指针的值,使用 %p。fmt.Printf("%p\n", &p)//当输出数字的时候,你将经常想要控制输出结果的宽度和精度,可以使用在 % 后面使用数字来控制输出宽度。默认结果使用右对齐并且通过空格来填充空白部分。fmt.Printf("|%6d|%6d|\n", 12, 345)//你也可以指定浮点型的输出宽度,同时也可以通过 宽度.精度 的语法来指定输出的精度。fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)//要左对齐,使用 - 标志。fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)//你也许也想控制字符串输出时的宽度,特别是要确保他们在类表格输出时的对齐。这是基本的右对齐宽度表示。fmt.Printf("|%6s|%6s|\n", "foo", "b")//要左对齐,和数字一样,使用 - 标志。fmt.Printf("|%-6s|%-6s|\n", "foo", "b")//到目前为止,我们已经看过 Printf了,它通过 os.Stdout输出格式化的字符串。Sprintf 则格式化并返回一个字符串而不带任何输出。s := fmt.Sprintf("a %s", "string")fmt.Println(s)//你可以使用 Fprintf 来格式化并输出到 io.Writers而不是 os.Stdout。fmt.Fprintf(os.Stderr, "an %s\n", "error")
}

结果如下:

{1 2}
an error
{x:1 y:2}
main.point{x:1, y:2}
main.point
true
123
1110
!
1c8
78.900000
1.234000e+08
1.234000E+08
"string"
"\"string\""
6865782074686973
0xc0420080d0
|    12|   345|
|  1.20|  3.45|
|1.20  |3.45  |
|   foo|     b|
|foo   |b     |
a string

  • 正则表达式​​​​​​​

代码如下:

package mainimport ("bytes""fmt""regexp"
)func main(){//这个测试一个字符串是否符合一个表达式。match, _ := regexp.MatchString("p([a-z]+)ch", "peach")fmt.Println(match)//上面我们是直接使用字符串,但是对于一些其他的正则任务,你需要 Compile 一个优化的 Regexp 结构体。r, _ := regexp.Compile("p([a-z]+)ch")//这个结构体有很多方法。这里是类似我们前面看到的一个匹配测试。fmt.Println(r.MatchString("peach"))//这是查找匹配字符串的。fmt.Println(r.FindString("peach punch"))//这个也是查找第一次匹配的字符串的,但是返回的匹配开始和结束位置索引,而不是匹配的内容。fmt.Println(r.FindStringIndex("peach punch"))//Submatch 返回完全匹配和局部匹配的字符串。例如,这里会返回 p([a-z]+)ch 和 `([a-z]+) 的信息。fmt.Println(r.FindStringSubmatch("peach punch"))//类似的,这个会返回完全匹配和局部匹配的索引位置。fmt.Println(r.FindStringSubmatchIndex("peach punch"))//带 All 的这个函数返回所有的匹配项,而不仅仅是首次匹配项。例如查找匹配表达式的所有项。fmt.Println(r.FindAllString("peach punch pinch", -1))//All 同样可以对应到上面的所有函数。fmt.Println(r.FindAllStringSubmatchIndex("peach punch pinch", -1))//这个函数提供一个正整数来限制匹配次数。fmt.Println(r.FindAllString("peach punch pinch", 2))//上面的例子中,我们使用了字符串作为参数,并使用了如 MatchString 这样的方法。我们也可以提供 []byte参数并将 String 从函数命中去掉。fmt.Println(r.Match([]byte("peach")))//创建正则表示式常量时,可以使用 Compile 的变体MustCompile 。因为 Compile 返回两个值,不能用于常量。r = regexp.MustCompile("p([a-z]+)ch")fmt.Println(r)//regexp 包也可以用来替换部分字符串为其他值。fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))//Func 变量允许传递匹配内容到一个给定的函数中,in := []byte("a peach")out := r.ReplaceAllFunc(in, bytes.ToUpper)fmt.Println(string(out))
}

结果如下:

true
true
peach
[0 5]
[peach ea]
[0 5 1 3]
[peach punch pinch]
[[0 5 1 3] [6 11 7 9] [12 17 13 15]]
[peach punch]
true
p([a-z]+)ch
a <fruit>
a PEACH

  • JSON
package mainimport ("encoding/json""fmt""os"
)type Response1 struct {Page   intFruits []string
}type Response2 struct {Page   int      `json:"page"`Fruits []string `json:"fruits"`
}func main(){//首先我们来看一下基本数据类型到 JSON 字符串的编码过程。这里是一些原子值的例子。bolB, _ := json.Marshal(true)fmt.Println(string(bolB))intB, _ := json.Marshal(1)fmt.Println(string(intB))fltB, _ := json.Marshal(2.34)fmt.Println(string(fltB))strB, _ := json.Marshal("gopher")fmt.Println(string(strB))//这里是一些切片和 map 编码成 JSON 数组和对象的例子。slcD := []string{"apple", "peach", "pear"}slcB, _ := json.Marshal(slcD)fmt.Println(string(slcB))mapD := map[string]int{"apple": 5, "lettuce": 7}mapB, _ := json.Marshal(mapD)fmt.Println(string(mapB))//JSON 包可以自动的编码你的自定义类型。编码仅输出可导出的字段,并且默认使用他们的名字作为 JSON 数据的键。res1D := &Response1{Page:   1,Fruits: []string{"apple", "peach", "pear"}}res1B, _ := json.Marshal(res1D)fmt.Println(string(res1B))//你可以给结构字段声明标签来自定义编码的 JSON 数据键名称。在上面 Response2 的定义可以作为这个标签这个的一个例子。res2D := Response2{Page:   1,Fruits: []string{"apple", "peach", "pear"}}res2B, _ := json.Marshal(res2D)fmt.Println(string(res2B))//现在来看看解码 JSON 数据为 Go 值的过程。这里是一个普通数据结构的解码例子。byt := []byte(`{"num":6.13,"strs":["a","b"]}`)//我们需要提供一个 JSON 包可以存放解码数据的变量。这里的 map[string]interface{} 将保存一个 string 为键,值为任意值的map。var dat map[string]interface{}//这里就是实际的解码和相关的错误检查。if err := json.Unmarshal(byt, &dat); err != nil {panic(err)}fmt.Println(dat)//为了使用解码 map 中的值,我们需要将他们进行适当的类型转换。例如这里我们将 num 的值转换成 float64类型。num := dat["num"].(float64)fmt.Println(num)//访问嵌套的值需要一系列的转化。strs := dat["strs"].([]interface{})str1 := strs[0].(string)fmt.Println(str1)//我们也可以解码 JSON 值到自定义类型。这个功能的好处就是可以为我们的程序带来额外的类型安全加强,并且消除在访问数据时的类型断言。str := `{"page": 1, "fruits": ["apple", "peach"]}`res := &Response2{}json.Unmarshal([]byte(str), &res)fmt.Println(res)fmt.Println(res.Fruits[0])//在上面的例子中,我们经常使用 byte 和 string 作为使用标准输出时数据和 JSON 表示之间的中间值。我们也可以和os.Stdout 一样,直接将 JSON 编码直接输出至 os.Writer流中,或者作为 HTTP 响应体。enc := json.NewEncoder(os.Stdout)d := map[string]int{"apple": 5, "lettuce": 7}enc.Encode(d)
}

结果如下:

true
1
2.34
"gopher"
["apple","peach","pear"]
{"apple":5,"lettuce":7}
{"Page":1,"Fruits":["apple","peach","pear"]}
{"page":1,"fruits":["apple","peach","pear"]}
map[strs:[a b] num:6.13]
6.13
a
&{1 [apple peach]}
apple
{"apple":5,"lettuce":7}

  • 时间​​​​​​​

代码如下:

package mainimport ("fmt""time"
)func main(){p := fmt.Println//得到当前时间。now := time.Now()p(now)//通过提供年月日等信息,你可以构建一个 time。时间总是关联着位置信息,例如时区。then := time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC)p(then)//你可以提取出时间的各个组成部分。p(then.Year())p(then.Month())p(then.Day())p(then.Hour())p(then.Minute())p(then.Second())p(then.Nanosecond())p(then.Location())//输出是星期一到日的 Weekday 也是支持的。p(then.Weekday())//这些方法来比较两个时间,分别测试一下是否是之前,之后或者是同一时刻,精确到秒。p(then.Before(now))p(then.After(now))p(then.Equal(now))//方法 Sub 返回一个 Duration 来表示两个时间点的间隔时间。diff := now.Sub(then)p(diff)//我们计算出不同单位下的时间长度值。p(diff.Hours())p(diff.Minutes())p(diff.Seconds())p(diff.Nanoseconds())//你可以使用 Add 将时间后移一个时间间隔,或者使用一个 - 来将时间前移一个时间间隔。p(then.Add(diff))p(then.Add(-diff))
}

结果如下:

2018-11-22 19:13:53.5523728 +0800 CST m=+0.005076301
2009-11-17 20:34:58.651387237 +0000 UTC
2009
November
17
20
34
58
651387237
UTC
Tuesday
true
false
false
78998h38m54.900985563s
78998.64858360711
4.739918915016426e+06
2.8439513490098554e+08
284395134900985563
2018-11-22 11:13:53.5523728 +0000 UTC
2000-11-13 05:56:03.750401674 +0000 UTC

  • 时间戳​​​​​​​

代码如下:

package mainimport ("fmt""time"
)func main(){//分别使用带 Unix 或者 UnixNano 的 time.Now来获取从自协调世界时起到现在的秒数或者纳秒数。now := time.Now()secs := now.Unix()nanos := now.UnixNano()fmt.Println(now)//注意 UnixMillis 是不存在的,所以要得到毫秒数的话,你要自己手动的从纳秒转化一下。millis := nanos / 1000000fmt.Println(secs)fmt.Println(millis)fmt.Println(nanos)//你也可以将协调世界时起的整数秒或者纳秒转化到相应的时间。fmt.Println(time.Unix(secs, 0))fmt.Println(time.Unix(0, nanos))
}

结果如下:

2018-11-22 19:18:49.4598433 +0800 CST m=+0.008107401
1542885529
1542885529459
1542885529459843300
2018-11-22 19:18:49 +0800 CST
2018-11-22 19:18:49.4598433 +0800 CST

  • 时间的格式化和解析​​​​​​​

代码如下:

package mainimport ("fmt""time"
)func main(){p := fmt.Println//这里是一个基本的按照 RFC3339 进行格式化的例子,使用对应模式常量。t := time.Now()p(t.Format(time.RFC3339))//时间解析使用同 Format 相同的形式值。t1, e := time.Parse(time.RFC3339,"2012-11-01T22:08:41+00:00")p(t1)p(t.Format("3:04PM"))p(t.Format("Mon Jan _2 15:04:05 2006"))p(t.Format("2006-01-02T15:04:05.999999-07:00"))form := "3 04 PM"t2, e := time.Parse(form, "8 41 PM")p(t2)//对于纯数字表示的时间,你也可以使用标准的格式化字符串来提出出时间值得组成。fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",t.Year(), t.Month(), t.Day(),t.Hour(), t.Minute(), t.Second())//Parse 函数在输入的时间格式不正确是会返回一个错误。ansic := "Mon Jan _2 15:04:05 2006"_, e = time.Parse(ansic, "8:41PM")p(e)
}

结果如下:

2018-11-22T19:22:59+08:00
2012-11-01 22:08:41 +0000 +0000
7:22PM
Thu Nov 22 19:22:59 2018
2018-11-22T19:22:59.922421+08:00
0000-01-01 20:41:00 +0000 UTC
2018-11-22T19:22:59-00:00
parsing time "8:41PM" as "Mon Jan _2 15:04:05 2006": cannot parse "8:41PM" as "Mon"

  • 随机数​​​​​​​

代码如下:

package mainimport ("fmt""math/rand""time"
)func main(){fmt.Print(rand.Intn(100), ",")fmt.Print(rand.Intn(100))fmt.Println()//rand.Float64 返回一个64位浮点数 f,0.0 <= f <= 1.0。fmt.Println(rand.Float64())//这个技巧可以用来生成其他范围的随机浮点数,例如5.0 <= f <= 10.0fmt.Print((rand.Float64()*5)+5, ",")fmt.Print((rand.Float64() * 5) + 5)fmt.Println()s1 := rand.NewSource(time.Now().UnixNano())r1 := rand.New(s1)//调用上面返回的 rand.Source 的函数和调用 rand 包中函数是相同的。fmt.Print(r1.Intn(100), ",")fmt.Print(r1.Intn(100))fmt.Println()//如果使用相同的种子生成的随机数生成器,将会产生相同的随机数序列。s2 := rand.NewSource(42)r2 := rand.New(s2)fmt.Print(r2.Intn(100), ",")fmt.Print(r2.Intn(100))fmt.Println()s3 := rand.NewSource(42)r3 := rand.New(s3)fmt.Print(r3.Intn(100), ",")fmt.Print(r3.Intn(100))
}

结果如下:

81,87
0.6645600532184904
7.1885709359349015,7.123187485356329
89,71
5,87
5,87

  • 数字解析​​​​​​​

代码如下:

package mainimport ("fmt""strconv"
)func main(){//使用 ParseFloat 解析浮点数,这里的 64 表示表示解析的数的位数。f, _ := strconv.ParseFloat("1.234", 64)fmt.Println(f)//在使用 ParseInt 解析整形数时,例子中的参数 0 表示自动推断字符串所表示的数字的进制。64 表示返回的整形数是以 64 位存储的。i, _ := strconv.ParseInt("123", 0, 64)fmt.Println(i)//ParseInt 会自动识别出十六进制数。d, _ := strconv.ParseInt("0x1c8", 0, 64)fmt.Println(d)//ParseUint 也是可用的。u, _ := strconv.ParseUint("789", 0, 64)fmt.Println(u)//Atoi 是一个基础的 10 进制整型数转换函数。k, _ := strconv.Atoi("135")fmt.Println(k)//在输入错误时,解析函数会返回一个错误。_, e := strconv.Atoi("wat")fmt.Println(e)
}

结果如下:

1.234
123
456
789
135
strconv.Atoi: parsing "wat": invalid syntax

  • URL解析​​​​​​​

代码如下:

package mainimport ("fmt""net/url""strings"
)func main(){//我们将解析这个 URL 示例,它包含了一个 scheme,认证信息,主机名,端口,路径,查询参数和片段。s := "postgres://user:pass@host.com:5432/path?k=v#f"//解析这个 URL 并确保解析没有出错。u, err := url.Parse(s)if err != nil {panic(err)}//直接访问 scheme。fmt.Println(u.Scheme)//User 包含了所有的认证信息,这里调用 Username和 Password 来获取独立值。fmt.Println(u.User)fmt.Println(u.User.Username())p, _ := u.User.Password()fmt.Println(p)//Host 同时包括主机名和端口信息,如过端口存在的话,使用 strings.Split() 从 Host 中手动提取端口。fmt.Println(u.Host)h := strings.Split(u.Host, ":")fmt.Println(h[0])fmt.Println(h[1])//这里我们提出路径和查询片段信息。fmt.Println(u.Path)fmt.Println(u.Fragment)//要得到字符串中的 k=v 这种格式的查询参数,可以使用 RawQuery 函数。你也可以将查询参数解析为一个map。fmt.Println(u.RawQuery)m, _ := url.ParseQuery(u.RawQuery)fmt.Println(m)fmt.Println(m["k"][0])
}

结果如下:

postgres
user:pass
user
pass
host.com:5432
host.com
5432
/path
f
k=v
map[k:[v]]
v

  • SHA1散列​​​​​​​
package mainimport ("crypto/sha1""fmt"
)func main(){s := "i love cyj"h := sha1.New()h.Write([]byte(s))bs := h.Sum(nil)fmt.Println(s)fmt.Printf("%x\n",bs)
}

结果如下:

i love cyj
93452691dfa19ac3c4d58f3672da75ebdf348dc3

  • Base64编码
package mainimport "fmt"
import b64 "encoding/base64"func main(){//这是将要编解码的字符串。data := "i love cyj"//Go 同时支持标准的和 URL 兼容的 base64 格式。编码需要使用 []byte 类型的参数,所以要将字符串转成此类型。sEnc := b64.StdEncoding.EncodeToString([]byte(data))fmt.Println(sEnc)//解码可能会返回错误,如果不确定输入信息格式是否正确,那么,你就需要进行错误检查了。sDec, _ := b64.StdEncoding.DecodeString(sEnc)fmt.Println(string(sDec))fmt.Println()//使用 URL 兼容的 base64 格式进行编解码。uEnc := b64.URLEncoding.EncodeToString([]byte(data))fmt.Println(uEnc)uDec, _ := b64.URLEncoding.DecodeString(uEnc)fmt.Println(string(uDec))
}

结果如下:

aSBsb3ZlIGN5ag==
i love cyj

aSBsb3ZlIGN5ag==
i love cyj

  • 读文件​​​​​​​

代码如下:

package mainimport ("bufio""fmt""io""io/ioutil""os"
)func check(e error){if e!=nil{panic(e)}
}func main(){//也许大部分基本的文件读取任务是将文件内容读取到内存中。dat,err := ioutil.ReadFile("D:/GOPATH/src/awesomeProject/example/main/defer.txt")check(err)fmt.Println(string(dat))//对于这个任务,从使用 os.Open打开一个文件获取一个 os.File 值开始。f,err := os.Open("D:/GOPATH/src/awesomeProject/example/main/defer.txt")check(err)//从文件开始位置读取一些字节。这里最多读取 6 个字节,并且这也是我们实际读取的字节数。b1 := make([]byte,6)n1,err := f.Read(b1)check(err)fmt.Printf("%d bytes: %s \n",n1,string(b1))//你也可以 Seek 到一个文件中已知的位置并从这个位置开始进行读取。o2,err := f.Seek(7,0)check(err)b2 := make([]byte,3)n2,err := f.Read(b2)check(err)fmt.Printf("%d bytes @ %d: %s\n",n2,o2,string(b2))//io 包提供了一些可以帮助我们进行文件读取的函数。o3,err := f.Seek(7,0)check(err)b3 := make([]byte,3)n3,err := io.ReadAtLeast(f,b3,3)check(err)fmt.Printf("%d bytes @ %d: %s\n",n3,o3,string(b3))//没有内置的回转支持,但是使用 Seek(0, 0) 实现。_,err = f.Seek(0,0)check(err)//bufio 包实现了带缓冲的读取,这不仅对有很多小的读取操作的能提升性能,也提供了很多附加的读取函数。r4 := bufio.NewReader(f)b4,err := r4.Peek(10)check(err)fmt.Printf("10 bytes: %s\n",string(b4))//任务结束后要关闭这个文件(通常这个操作应该在 Open操作后立即使用 defer 来完成)。f.Close()
}

结果如下:

i love cyj
6 bytes: i love 
3 bytes @ 7: cyj
3 bytes @ 7: cyj
10 bytes: i love cyj

  • 写文件​​​​​​​

代码如下:

package mainimport ("bufio""fmt""io/ioutil""os"
)func check(e error){if e!=nil{panic(e)}
}func main(){//开始,这里是展示如写入一个字符串(或者只是一些字节)到一个文件。d1 := []byte("hello\nworld\n")err := ioutil.WriteFile("D:/GOPATH/src/awesomeProject/example/main/defer.txt",d1,0644)check(err)//对于更细粒度的写入,先打开一个文件。f,err := os.Create("D:/GOPATH/src/awesomeProject/example/main/dat.txt")check(err)//打开文件后,习惯立即使用 defer 调用文件的 Close操作。defer f.Close()//你可以写入你想写入的字节切片d2 := []byte("i love cyj\n")n2,err := f.Write(d2)check(err)fmt.Printf("write %d bytes\n",n2)//WriteString 也是可用的。n3,err := f.WriteString("cyj love me too\n")check(err)fmt.Printf("write %d bytes\n",n3)//调用 Sync 来将缓冲区的信息写入磁盘。f.Sync()//bufio 提供了和我们前面看到的带缓冲的读取器一样的带缓冲的写入器。w := bufio.NewWriter(f)n4,err := w.WriteString("buffered\n")check(err)fmt.Printf("write %d bytes\n",n4)//使用 Flush 来确保所有缓存的操作已写入底层写入器。w.Flush()
}

结果如下:

write 11 bytes
write 16 bytes
write 9 bytes

  • 行过滤器​​​​​​​

代码如下:

package mainimport ("bufio""fmt""os""strings"
)func main(){scanner := bufio.NewScanner(os.Stdin)for scanner.Scan(){//Text 返回当前的 token,现在是输入的下一行。ucl := strings.ToUpper(scanner.Text())//写出大写的行。fmt.Println(ucl)}//检查 Scan 的错误。文件结束符是可以接受的,并且不会被 Scan 当作一个错误。if err := scanner.Err(); err != nil {fmt.Fprintln(os.Stderr, "error:", err)os.Exit(1)}
}

结果如下:

hello
HELLO
world
WORLD

  • 环境变量

代码如下:

package mainimport ("fmt""os""strings"
)func main() {//使用 os.Setenv 来设置一个键值队。使用 os.Getenv获取一个键对应的值。如果键不存在,将会返回一个空字符串。os.Setenv("FOO", "1")fmt.Println("FOO:", os.Getenv("FOO"))fmt.Println("BAR:", os.Getenv("BAR"))//使用 os.Environ 来列出所有环境变量键值队。这个函数会返回一个 KEY=value 形式的字符串切片。fmt.Println()for _, e := range os.Environ() {pair := strings.Split(e, "=")fmt.Println(pair[0])}
}

结果如下:

FOO: 1
BAR:

ALLUSERSPROFILE
APPDATA
CommonProgramFiles
CommonProgramFiles(x86)
CommonProgramW6432
COMPUTERNAME
ComSpec
configsetroot
FOO
FPS_BROWSER_APP_PROFILE_STRING
FPS_BROWSER_USER_PROFILE_STRING
GOPATH
GOROOT
HOMEDRIVE
HOMEPATH
LOCALAPPDATA
LOGONSERVER
NUMBER_OF_PROCESSORS
OneDrive
OS
Path
PATHEXT
PROCESSOR_ARCHITECTURE
PROCESSOR_IDENTIFIER
PROCESSOR_LEVEL
PROCESSOR_REVISION
ProgramData
ProgramFiles
ProgramFiles(x86)
ProgramW6432
PSModulePath
PUBLIC
SESSIONNAME
SystemDrive
SystemRoot
TEMP
TMP
USERDOMAIN
USERDOMAIN_ROAMINGPROFILE
USERNAME
USERPROFILE
windir

  • 退出​​​​​​​

代码如下:

package mainimport ("fmt""os"
)func main() {//当使用 os.Exit 时 defer 将不会 执行,所以这里的 fmt.Println将永远不会被调用。defer fmt.Println("!")//退出并且退出状态为 3。os.Exit(3)
}

结果如下:

Process finished with exit code 3

最新文章

  1. [No0000C0]百度网盘真实地址解析(不用下载百度网盘)20170301
  2. 赶快使用Q-Dir软件,使您的文件夹操作更加高效
  3. 前端学习(3302):createRef
  4. java radio_java radioButton
  5. 3-3Tensor和机器学习的关系
  6. python意外退出_有趣的Python上下文管理器
  7. SAP License:别闹了,这些都不是数字化转型
  8. mysql udf http,mysql下mysql-udf-http效率测试小记
  9. TX2在Turtlebot测试kobuki
  10. JavaScript基础知识指南-思维导图
  11. 基于php网络小说,五部小说点击破亿,盘点网络文学白金作家我吃西红柿!
  12. 电子沙盘 数字沙盘 开发教程
  13. vcpkg工具+vs2019
  14. 更改C盘用户文件夹名
  15. Element日期选择器带快捷选项切换日期类型
  16. 如何使用电脑上的谷歌浏览器来调试安卓手机上的移动端页面
  17. 人的天性是贪嗔痴和戒定慧的等量叠加态
  18. kaggle数据集汇总_Kaggle比赛快速上手演示
  19. 信息学奥林匹克竞赛python_USACO美国信息学奥林匹克竞赛大师课火热招募中!提升TOP20名校申请竞争力!...
  20. echarts 象形柱图pictorialBar

热门文章

  1. 构建之法1,5,17章学习心得
  2. 【Prison Break】第八天(4.4)
  3. 【图像处理】【去模糊】图像去模糊之初探--Single Image Motion Deblurring
  4. LeetCode路径问题
  5. python中 return self的作用
  6. 直观讲解Matlab的im2col函数
  7. 补码转源码 吐血总结
  8. 四阶龙格库塔法的基本思想_“李军班长工作法”为“卓越班组”建设注入新动力...
  9. C语言复习一(内存对齐、大小端)
  10. Boost.Python.ArgumentError: Python argument types in错误解决及Boost安装配置