• Go 知识汇总


    一、语法基础

    1、package:声明包。类似Java。Go程序是由包组成的。程序入口的包是main。

    2、import:导入包。类似Java。利用圆括号可以导入多个包,或者逐个导入。

    3、func:定义函数。

    4、导出的名称,首字母是大写。

    5、变量类型在变量名后面。

    6、函数的命名参数,多个连续同类型,可以只保留最后一个类型。

    x int, y int
    // 简写成:
    x, y int

    7、函数返回值位于函数签名的尾部。

    8、函数返回值可以有名字,并且像变量一样使用。

    9、return语句没有参数,即返回各个变量的当前值。

    10、:=,短声明变量,明确类型的赋值语句,只能用在函数内。

    11、基本类型:bool,string,int,int8,int16,int32,int64,uint8,uint16,uint32,uint64,uintptr,byte,rune,float32,float64,complex64,complex128。 

    12、var可以利用圆括号包含多个变量声明。 

    13、没有初始化的变量,会被赋值为零值。类似C/C++中的默认值。数值类型为0,布尔类型为false,字符串类型为"",指针类型为nil,slice为nil,map为nil。

    14、不同类型之间的转换,需要显式指定。C/C++支持隐式类型转换。 

    15、类型推导:如果右值有明确类型,而左值没有,则左值的类型由右值推导得出。 

    16、常量(const)不能使用:=。

    17、只有for循环,并且没有圆括号,还可以在没表达式时省略分号。没有while循环。

    // 死循环
    for {
    }

    18、if条件语句没有圆括号。条件表达式前面可以有语句,并且语句中的变量可以在if和else中使用。

    19、switch条件语句没有圆括号。条件表达式前面可以有语句。没有条件表达式,则等价于true。从上到下执行,直到匹配成功。 

    20、defer:延迟函数调用。类似Objective-C的dispatch_async。defer函数会被压栈。 

    21、指针不能运算。跟C/C++不同。

    var p * int

    22、结构体,利用点号访问字段。结构体指针也是用点号访问字段。

    type DefaultCreator struct {
    	clientSet *kubernetes.Clientset
    }

    23、结构体文法,通过字段值列表来创建一个结构体,键值对可以只列出部分字段。

    type Vertex struct {
    	X, Y int
    }
    var (
    	v1 = Vertex{1, 2}  // 类型为 Vertex
    	v2 = Vertex{X: 1}  // Y:0 被省略
    	v3 = Vertex{}      // X:0 和 Y:0
    	p  = &Vertex{1, 2} // 类型为 *Vertex
    )

    24、数组,长度是类型的一部分,不能改变。 

    var a [2]string
    a[0] = "Hello"
    a[1] = "World"
    fmt.Println(a[0], a[1])
    fmt.Println(a)
    

    25、slice(切片),用make函数创建,用append函数添加元素。

    // 序列
    p := []int{2, 3, 5, 7, 11, 13}
    len(p)
    p[low:high] // 从下标low到high-1,省略low表示0,省略high表示len(p)
    
    b := make([]int, 0, 5) // len(b)=0, cap(b)=5
    
    // 如果s太小,会分配更大的数组
    func append(s []T, vs ...T) []T
    

    26、for循环可以用range遍历slice和map。类似Python。

    var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
    for i, v := range pow {
    
    }
    

    27、range遍历可以使用下划线忽略key(slice的下标)和value。

    for _, val := range pow {
    
    }

    28、map,用make函数创建。  

    type Vertex struct {
    	Lat, Long float64
    }
    
    var m map[string]Vertex // 不能添加元素
    
    m = make(map[string]Vertex) // 用make才能添加元素
    m["Bell Labs"] = Vertex{
    	40.68433, -74.39967,
    }
    

    29、map文法。类似结构体文法,不过有键。

    type Vertex struct {
    	Lat, Long float64
    }
    
    var m = map[string]Vertex{
    	"Bell Labs": Vertex{
    		40.68433, -74.39967,
    	},
    	"Google": Vertex{
    		37.42202, -122.08408,
    	},
    }
    var m = map[string]Vertex{
    	"Bell Labs": {40.68433, -74.39967},
    	"Google":    {37.42202, -122.08408},
    }
    
    delete(m, "Google") // 删除键值对
    v, ok := m["Answer"] // 检查是否包含键值对
    

    30、函数也是值。类似C/C++函数指针。 

    hypot := func(x, y float64) float64 {
    		return math.Sqrt(x*x + y*y)
    	}
    hypot(3, 4)

    31、闭包

    func adder() func(int) int {
    	sum := 0
    	return func(x int) int {
    		sum += x
    		return sum
    	}
    }
    
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
    	pos(i)
    	neg(-2*i)
    } 

    32、方法:没有类。包内任意数据类型都可以定义任意方法。但是其他包和基础数据类型不行。

    type Vertex struct {
    	X, Y float64
    }
    // Abs方法接收器是Vertex结构体的指针,即方法属于哪个数据类型
    func (v *Vertex) Abs() float64 {
    	return math.Sqrt(v.X*v.X + v.Y*v.Y)
    }
    v := &Vertex{3, 4}
    // 方法接收器通过点号访问方法
    v.Abs()

    33、方法接收器是指针:1、可以避免方法调用时值拷贝;2、可以修改接收器。 

    34、接口类型是一组方法的集合。接口类型的值可以是实现接口方法的任何类型。 

    type Abser interface {
    	Abs() float64
    }
    
    type Vertex struct {
    	X, Y float64
    }
    func (v *Vertex) Abs() float64 {
    	return math.Sqrt(v.X*v.X + v.Y*v.Y)
    }
    
    var a Abser
    v := Vertex{3, 4}
    a = &v
    

    35、隐式接口。 

    36、fmt包中的Stringer接口,error接口。io包中的Reader接口。image包。

    type Stringer interface {
        String() string
    }
    
    // nil表示成功
    type error interface {
        Error() string
    }

    37、http包,实现Handler接口来响应http请求。

    package http
    
    type Handler interface {
        ServeHTTP(w ResponseWriter, r *Request)
    }

    38、goroutine,轻量级线程。其实就是协程。共享进程的地址空间。

    go f(x, y, z) // 创建一个新的goroutine来运行f函数。

    39、channel,有类型的管道。类似C/C++中的pipe。 

    func sum(a []int, c chan int) {
    	sum := 0
    	for _, v := range a {
    		sum += v
    	}
    	c <- sum // 将和送入 c
    }
    
    a := []int{7, 2, 8, -9, 4, 0}
    
    c := make(chan int)
    go sum(a[:len(a)/2], c)
    go sum(a[len(a)/2:], c)
    x, y := <-c, <-c // 从 c 中获取
    
    // 缓冲channel,100是缓冲的长度,缓冲满时,发送阻塞;缓冲空时,接收阻塞。
    ch := make(chan int, 100)
    

    40、for i := range ch循环会不断从channel接收值,直到channel被发送方关闭。  

    v, ok := <-ch // 检查channel是否关闭

    41、select,可以让一个goroutine在多个通信操作上阻塞等待,默认是default分支,语法很像switch。其实就是Linux内核中select的功能。

    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
    		}
    	}
    }
    
    c := make(chan int)
    quit := make(chan int)
    go func() {
    	for i := 0; i < 10; i++ {
    		fmt.Println(<-c)
    	}
    	quit <- 0
    }()
    fibonacci(c, quit)

    42、指针也是利用点号来访问。 

    二、项目开发

    1、使用go命令行工具,需要按照固定目录结构来组织代码。因为它是为了维护公共代码库(例如github)中的开源代码而设计的。 

    2、GOPATH环境变量,指定工作目录。不能跟Go的安装目录相同。工作目录的bin子目录要添加到PATH环境变量中。

    export PATH=$PATH:$GOPATH/bin

    3、工作目录包含3个子目录:bin(可执行命令),pkg(包对象),src(源文件,按包组织,每个目录一个包)。

    bin/
    	streak                         # 可执行命令
    	todo                           # 可执行命令
    pkg/
    	linux_amd64/
    		code.google.com/p/goauth2/
    			oauth.a                # 包对象
    		github.com/nf/todo/
    			task.a                 # 包对象
    src/
    	code.google.com/p/goauth2/
    		.hg/                       # mercurial 代码库元数据
    		oauth/
    			oauth.go               # 包源码
    			oauth_test.go          # 测试源码
    	github.com/nf/
    		streak/
    		.git/                      # git 代码库元数据
    			oauth.go               # 命令源码
    			streak.go              # 命令源码
    		todo/
    		.git/                      # git 代码库元数据
    			task/
    				task.go            # 包源码
    			todo.go                # 命令源码

    4、包路径,可以是任意的唯一路径。

    // 比较好的规范。基本路径
    $GOPATH/src/github.com/yangwenhuan

    5、构建并安装。构建好的二进制,默认安装在bin目录下。

    // helloworld目录下有helloworld.go。
    // 可以在任意路径执行这个命令,go命令行工具会根据GOPATH 到github.com/yangwenhuan/helloworld路径下查找源文件。
    // 如果在helloworld目录下,直接执行go install即可。
    go install github.com/yangwenhuan/helloworld
    
  • 相关阅读:
    企业如何利用大数据?八个典型应用案例告诉你
    无焦点下获取条码枪返回值的Hook(再次改良版)
    combining-filters
    为Elasticsearch添加中文分词,对比分词器效果
    ElasticSearch NEST搜索
    How to write date range query in Nest ElasticSearch client?
    ElasticSearch关联查找
    form-inline+form-group 实现表单横排显示(Bootstrap)
    Elastic Search 5.x Nest Multiple Queries C#
    mysql 查看索引
  • 原文地址:https://www.cnblogs.com/yangwenhuan/p/10951886.html
Copyright © 2020-2023  润新知