基礎(chǔ)
package main
import (
"fmt",
"math/rand"
"math"
)
func main() {
//導(dǎo)出的函數(shù)或者值必須大寫(xiě)開(kāi)頭
ftm.Print("My favorite time it", rand.Intn(10))
fmt.Println(math.Pi)
}
定義變量
//變量類(lèi)型
//rune,int8,int16,int32,int64
//byte,uint8,uint16,uint32,uint64
//rune == int32
//byte == uint8
//go中字符串是不可變的
var s string = "Hello"
s[0] = 'W' //報(bào)錯(cuò)
//如果要修改字符串
s := "Hello"
c := []byte(s)//字符串s轉(zhuǎn)化為字符數(shù)組
c[0] = 'W'
s2 := string(c) //轉(zhuǎn)化為字符串
//字符串雖然無(wú)法改寫(xiě),但是可以切片
var i, j = 1, 2
var x, y int = 1, 2
k := 3
var (
ToBe bool = false
MaxInt uint64 = 1 << 64 - 1
)
const f = "%T(%v)\\n"
const (
Big = 1 << 100
Small = Big >> 99
)
const (
x = iota //0
y = iota //1
z = iota //2
w //3
)
err = errors.New("emmit a error")
函數(shù)
func add(x, y int) int {
return x + y
}
func swap(x, y) (string, string) {
return y, x
}
//裸返回
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
//將函數(shù)作為變量
type testInt func(int) bool //申明一個(gè)函數(shù)類(lèi)型
循環(huán)
sum := 0
for i := 0 ; i < 10; i++ {
sum += i
}
sum := 0
for ;sum < 1000; {
sum += sum
}
sum := 0
for sum < 1000 {
sum += sum
}
//死循環(huán)
for {
}
條件語(yǔ)句
if x < 10 {
//.....
}
if v := math.Pow(x, n); v < lim {
//...
} else {
//....
}
import runtime
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("Mac os")
case "linux":
fmt.Println("Linux.")
default:
fmt.Printf("%s", os)
}
import time
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning")
case t.Hour() < 17:
fmt.Println("Good afternoon")
default:
fmt.Println("Good evening")
}
指針
i, j := 42, 2701
p := &i
fmt.Println(*p)
*p = 81
//golang中沒(méi)有指針運(yùn)算
結(jié)構(gòu)體
type Vertex struct {
X int
Y int
}
//創(chuàng)建結(jié)構(gòu)體對(duì)象
v := Vertex{1, 2}
v.X = 12
p = &Vertex{1, 2}
p.X = 12
v := Vertex{X: 1}
數(shù)組和切片
var a [10]int //數(shù)組
//[3]int和[4]int是不同的類(lèi)型,數(shù)組的長(zhǎng)度不可變
c := [...]{4, 5, 6} //自動(dòng)推算長(zhǎng)度
s := []int{2, 3, 4, 5, 6, 7} //切片
for i:=0; i < len(s); i++ {
fmt.Println(s[i])
}
二維切片
game := [][]string{
[]string{"_", "_", "_"},
[]string{"_", "_", "_"},
[]string{"_", "_", "_"},
}
game[0][0] = "X"
game[2][2] = "O"
game[2][0] = "X"
game[1][0] = "O"
game[0][2] = "X"
strings.Join(game[0], " ") //數(shù)組變字符串
//對(duì)slice切片
s[low:hig] //左閉右開(kāi)
//構(gòu)造slice
a := make([]int, 5) //len(a) == 5
b := make([]int, 0, 5) // len(b) = 0, cap(b) = 5
//slice的0值為nil
//向slice添加元素
var a []int
a = append(a, 0) //如果原slice不夠長(zhǎng),則創(chuàng)建新slice
var pow = []int{1, 2, 4, 8, 16, 32}
for i, v := range pow {
}
for _,v := range pow{
}
map
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
m = make(map[string]Vertex)
var m = map[string]Vertex{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
delete(m, "Bell Labs")
v, ok := m["Bell Labs"]
函數(shù)傳參傳函數(shù)
func compute(fn func(float64, float64) float64) float64 {
return fn(3, 4)
}
//函數(shù)閉包
func adder() func(int) int {
sum := 0
return func(x int) int {
sum+=x
return sum
}
}
//菲波那切數(shù)列
func fibonacci() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return a
}
}
方法
type Vertex struct {
X,Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X * v.X + v.Y*v.Y)
}
v := &Vertex{1, 3}
s := v.Abs()
接口
//接口類(lèi)型是由一組方法定義的集合。
type Abser interface {
Abs() float
}
type Reader interface {
Read(b []byte) (n int, err error)
}
type Writer interface {
Write(b []byte) (n int, err error)
}
type ReadWriter interface {
Reader
Writer
}
//fmt包進(jìn)行輸出的時(shí)候回調(diào)用這個(gè)接口,如果想自定義輸出,可以實(shí)現(xiàn)這個(gè)方法
type Stringer interface {
String() string
}
Reader
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Hello, Reader!")
b := make([]byte, 8)
for {
n, err := r.Read(b)
fmt.Printf("n = %v err = %v b = %v\\n", n, err, b)
fmt.Printf("b[:n] = %q\\n", b[:n])
if err == io.EOF {
break
}
}
}
最簡(jiǎn)單的web服務(wù)器
package main
import (
"fmt"
"log"
"net/http"
)
type Hello struct{}
func (h Hello) ServeHTTP(
w http.ResponseWriter,
r *http.Request) {
fmt.Fprint(w, "Hello!")
}
func main() {
var h Hello
err := http.ListenAndServe("localhost:4000", h)
if err != nil {
log.Fatal(err)
}
}
goroutine
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
chanel
ch := make(chan int)
ch <- v // 將 v 送入 channel ch。
v := <-ch // 從 ch 接收,并且賦值給 v。
//緩沖chanel
ch := make(chan int, 100)
//發(fā)送者可以close一個(gè)channel來(lái)表示沒(méi)有值會(huì)被發(fā)送
//接受者可以通過(guò)賦值語(yǔ)句的第二個(gè)參數(shù)來(lái)測(cè)試channel是否被關(guān)閉
v, ok := <-ch
for i := range c //會(huì)不斷從channel接收值,直到被關(guān)閉
package main
import (
"fmt"
)
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x+y
}
close(c)
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)
for i := range c {
fmt.Println(i)
}
}
//select會(huì)阻塞,直到條件分支中的某個(gè)可以繼續(xù)執(zhí)行,這時(shí)就會(huì)執(zhí)行那個(gè)條件分支。
//當(dāng)多個(gè)都準(zhǔn)備好的時(shí)候,會(huì)隨機(jī)選擇一個(gè)。
//當(dāng) select中的其他條件分支都沒(méi)有準(zhǔn)備好的時(shí)候,default分支會(huì)被執(zhí)行。
package main
import "fmt"
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}
互斥
package main
import (
"fmt"
"sync"
"time"
)
// SafeCounter 的并發(fā)使用是安全的。
type SafeCounter struct {
v map[string]int
mux sync.Mutex
}
// Inc 增加給定 key 的計(jì)數(shù)器的值。
func (c *SafeCounter) Inc(key string) {
c.mux.Lock()
// Lock 之后同一時(shí)刻只有一個(gè) goroutine 能訪問(wèn) c.v
c.v[key]++
c.mux.Unlock()
}
// Value 返回給定 key 的計(jì)數(shù)器的當(dāng)前值。
func (c *SafeCounter) Value(key string) int {
c.mux.Lock()
// Lock 之后同一時(shí)刻只有一個(gè) goroutine 能訪問(wèn) c.v
defer c.mux.Unlock()
return c.v[key]
}
func main() {
c := SafeCounter{v: make(map[string]int)}
for i := 0; i < 1000; i++ {
go c.Inc("somekey")
}
time.Sleep(time.Second)
fmt.Println(c.Value("somekey"))
}