go

概念

package

源码文件

命令行工具

语法

// single row
/*
multi row
*/
package main // 程序所属包
import "fmt" // 导入依赖包
const NAME = "cxk" // 常量定义
type myInt int // 一般类型声明
// 结构体声明
type user struct { }
// 接口声明
type UserService interface { }
// 入口函数
func main(){
  var a = "cxk"
  fmt.Println(a+NAME)
}

import

// 另外一种语法
import ( 
  "fmt"
  "time"
)

原理

批注 2020-04-14 155821

别名

import pk "awesomeProject/pkg1"

pk.F()
import . "awesomeProject/pkg1"

F()
import _ "awesomeProject/pkg1"

数据类型

var i uint32 = 2
fmt.Println(unsafe.Sizeof(i)) // 4
var i1 int = 2
fmt.Println(unsafe.Sizeof(i1)) // 8
var i2 float32 = 1.0
fmt.Println(unsafe.Sizeof(i2)) // 4
var i3 bool = true
fmt.Println(unsafe.Sizeof(i3)) // 1
var i4 byte = 1
fmt.Println(unsafe.Sizeof(i4)) // 1

批注 2020-04-14 190812

变量

var(
i int
j float32
name string
)
var a, b, c int = 1,2,3
// 或者
var a,b,c = 1,2,3
// 省略var
a,b,c := 1,2,3
var a=1
func main(){
    b:=2
    fmt.Println(a,b)
}
var _ = 2
// 无法使用_
var a =1
var b  = float32(a)
// pkg1
func F1(){}

func f1(){}

// main
func main(){
    pkg1.F1()
    //pkg1.f1() 无法访问
}

常量

显式: const identifier [type] = value 隐式: const identifier = value ( 通常叫无类型常量)

const name = "cxk"
const age int = 18
const (
    habbit1 = "sing"
    habbit2 = "rap"
)

常量可以使用内置表达式定义,例如: len(),unsafe.Sizeof()等 ; 常量范围目前只支持布尔型、数字型(整数型、浮点型和复数)和字符串型;

特殊常量iota

const a = iota
const b = iota

const (
    c = iota
    d = iota
)
func main(){
    fmt.Println(a,b) // 0 0
    fmt.Println(c,d) // 0 1
}

1)跳值使用法;

const (
    c = iota
    _ = iota
    d = iota
)
func main(){
    fmt.Println(c,d) // 0 2
}

2)插队使用法;

const (
    c = iota
    d = 3
    e = iota
)
func main(){
    fmt.Println(c,d,e) // 0 3 2
}

3 )表达式隐式使用法;

const (
    c = iota *2
    d // 没有指定值,默认会继承之前的表达式
    e
)
func main(){
    fmt.Println(c,d,e) // 0 2 4
}

4)单行使用法;

const (
    a ,b = iota,iota+3
    c,d
)
func main(){
    fmt.Println(a,b,c,d) // 0 3 1 4
}

运算符

a := 1
b := 2
a++ // ++运算符只能这样用
println(a)
b-- // --运算符只能这样用
println(b)

控制语句

a := 0
if a>=1 {
    println("true")
}else if a <= 0 {
    println("false")
}
a := 10
switch a {
case 1:
    {
        println("1")
    }
case 2:
    {
        println("2")
    }
default:
    {
        println("default")
    }
}
// 死循环
for {
    println("run")
    time.Sleep(1*time.Second)
}
// 经典for循环
for i:=1;i<10;i++ {
    println("run",i)
}
// foreach
a := []string{"cxk", "jntm"}
for key, value := range a {
    println(key, value)
}
if true {
    goto label2
}else {
    goto label1
}
label1:
    println("label1")
label2:
    println("label2")
a := []string{"cxk", "jntm"}
for key, value := range a {
    println(key, value)
    if key == 0 {
        break
    }
}

内建方法

make

// slice类似于数组
slice := make([]string,3)
slice[0] = "cxk"
slice[1] = "cxk2"
slice[2] = "cxk3"
for k,v := range slice {
    println(k,v)
}
println("---")
// map
aMap := make(map[string]string,3)
aMap["a"]="1"
aMap["b"]="2"
for k,v := range aMap {
    println(k,v)
}
println("---")
// channel 类似缓冲区
aChan := make(chan int,3)
close(aChan)

new

// 返回一个指针
aMap := new(map[string]string)
fmt.Println(reflect.TypeOf(aMap)) // *map[string]string

append & copy & delete

slice :=make ([]string,2)
slice[0]="1"
slice[1]="2"
slice = append(slice,"3")
fmt.Println(slice) // 1 2 3
slice1 :=make ([]string,2)
slice1[0]="1"
slice1[1]="2"
slice2 :=make([]string,2)
copy(slice2,slice1)
fmt.Println(slice2) // 1 2
aMap := make(map[string]string)
aMap["1"]="a"
aMap["2"]="b"
delete(aMap,"1")
fmt.Println(aMap) // 2:b

异常

func main() {
    defer func() {
        // 异常处理
        msg := recover()
        fmt.Println("msg:",msg)
    }()
    // 抛出异常
    panic("异常")
}

len && cap && close

slice := make([]int,3,5)
println(len(slice)) // 3
println(cap(slice)) // 5

aChan := make(chan int,1)
aChan <- 1
close(aChan)

结构体

// 定义结构体
type Person struct {
    Name string
    Age int
}
func main(){
    var p Person // 声明结构体变量
    p.Age = 18 // 结构体成员赋值
    p1 := Person{Name: "cxk"} // 另外一种方式
    p2 := new(Person) // 返回一个Person指针
    p.Name = "cxk"
    fmt.Println(p)
}

属性及函数

// 定义Person的一个公开成员方法
func (p *Person)Say(){
    fmt.Println("person say")
}

组合

type Animal struct {
    Type string
}
type Dog struct {
    Animal // 组合animal,Dog继承Animal的属性
    Name string
}

并发

func main(){
    go run()
    go run()
    time.Sleep(time.Second*5)
}
func run(){
    for i:=1;i<10;i++ {
        time.Sleep(time.Millisecond*2)
        print(i)
    }
    println()
}
var chanInt = make(chan int,10)
func main(){
    go send()
    go receive()
    time.Sleep(5*time.Second)
}

func send(){
    chanInt <- 1
    chanInt <- 2
    chanInt <- 3
}

func receive(){
    num := <- chanInt
    fmt.Println(num)
    num = <- chanInt
    fmt.Println(num)
    num = <- chanInt
    fmt.Println(num)
}
var chanInt = make(chan int,10)
var chan1 = make(chan int,10)

func send(){
    for i:=0;i<10;i++ {
        chanInt <- i
        chan1 <- i*i
    }
}

func receive(){
    for {
        select {
        case num := <- chanInt:
            fmt.Println(num)
        case num := <- chan1:
            fmt.Println(num)
        }
    }
}

select可以随机在多个channel中取数据

func main(){
    makeFood(10)
    go eatFood(10)
    waitGroup.Wait()
}
var waitGroup sync.WaitGroup
func makeFood(i int){
    for j:=0;j<i;j++ {
        waitGroup.Add(1)
        fmt.Println("make food",j)
    }
}
func eatFood(i int){
    for j:=0;j<i;j++ {
        fmt.Println("eat food",j)
        waitGroup.Done() // countdown
    }
}

指针

i:=20
var pi *int=&i // pi指向i
fmt.Println(*pi) // 读取pi所指向的内容
fmt.Println(pi == nil) // 判断是否为空

a,b :=1,2
pa := [...]*int{&a,&b} // 指针数组(元素为指针的数组)
fmt.Println(pa)

arr := [...]int{1,2,3}
ap := &arr // 数组指针(指向一个数组的指针)
fmt.Println(ap)

json

setting := Setting{Menu:"menu",Count: 15}
byte,err:=json.Marshal(setting)
if err!=nil {
    fmt.Println(err)
}else {
    fmt.Println(string(byte))
}
type Setting struct {
    Menu string `json:"menu"` // 指定序列后的字段名字
    Count int
}
str := "{\"menu\":\"menu\",\"Count\":15}\n"
var setting Setting
err := json.Unmarshal([]byte(str),&setting)
if err != nil {
    fmt.Println(err)
}else {
    fmt.Println(setting)
}

module

go mod init
go mod graph