• GO语言学习笔记(一) 概述


    第一章 概述

    该笔记参考 《Go语言学习笔记》

    学习go语言之前需要了解的内容:

    1. go语言的编译器将未使用的局部变量定义当作错误来处理
    2. go语言将未使用的导入,当作错误来处理

    GO语言的代码文件以.go命名,语句结束分号被默认省略,C样式的注释,入口函数main()没有参数,注意入口函数必须放在main包中。

    package main 
    
    func main(){
        println("hello world")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1. 基本语句

    包导入

    import (
        'fmt'
    )
    
    • 1
    • 2
    • 3

    流程控制

    方式一:

    	x := 100
    	if x > 0 {
    		print(x)
    	} else if x == 0 {
    		print(x)
    	} else {
    		print(x)
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方式二:

    func main() {
    	x := 100
    	switch {
    	case x > 0:
    		print("x")
    	case x == 0:
    		print("0")
    	case x < 0:
    		print("-x")
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    循环遍历
    方式一

    func main() {
    	for i := 0; i < 5; i++ {
    		println(i)
    	}
    
    	for i := 4; i >= 0; i-- {
    		println(i)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    方式二

    func main() {
    	x := 0
    	for x < 5 { // 相当于 while(x < 5)
    		println(x)
    		x++
    	}
    }
    // for 可以当作while来使用
    func main() {
    	x := 0
    	for { // equals to while(True)
    		println(x)
    		x++
    		if x >= 5 {
    			break
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    函数

    • 函数可以定义多个返回值,这一点和python很像, 甚至可以对其命名
    // div is the function name, and a, b are parameters
    // this functions has two returns, one is int type and the other is error type
    func div(a, b int) (int, error) {
    	if b == 0 {
    		return 0, errors.New("division by zero")
    	}
    	return a / b, nil
    }
    
    func main() {
    	a, b := 10, 0
    	c, err := div(a, b)
    	fmt.Println(c, err)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 函数是第一类型,可以作为参数,或者返回值
    // 函数作为返回值
    func test(x int) func() {
    	return func() {
    		println(x)
    	}
    }
    
    func main() {
    	x := 100
    	f := test(x)
    	f()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 用defer 定义延迟调用,无论函数是否出错,它都确保结束前被调用
    // 用defer 定义延迟调用,无论函数是否出错,它都确保结束前被调用
    func test_defer(a, b int) {
    	defer println("dispose...") // 通常用来释放资源,解除锁定,或者执行一些清理操作
    	// 可以定义多个defer, 按照FIFO顺序执行
    	println(a / b)
    }
    
    func main() {
    	test_defer(10, 5)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2. 数据

    切片 slice 可以实现类似动态数组的功能

    func main() {
    	// test_defer(10, 5)
    	x := make([]int, 0, 5) // 创建容量为5的切片
    	for i := 0; i < 8; i++ {
    		x = append(x, i) //追加数据
    	}
    	fmt.Println(x)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    map 字典, 将字典类型内置,可以直接从运行时层面获得性能优化

    func main() {
    	// test_defer(10, 5)
    	// x := make([]int, 0, 5) // 创建容量为5的切片
    	// for i := 0; i < 8; i++ {
    	// 	x = append(x, i) //追加数据
    	// }
    	// fmt.Println(x)
    	m := make(map[string]int) // 创建字典对象
    	m["a"] = 1                //  添加或设置
    	x, ok := m["b"]           //使用ok-idiom(习惯用语) 获取值,可以知道key/value是否存在
    	y, ok := m["a"]
    	fmt.Println(x, ok)
    	fmt.Println(y, ok)
    	delete(m, "a") // 删除字典中key="a"
    	z, ok := m["a"]
    	fmt.Println(z, ok)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    结构体 struct 可以匿名嵌入其他类型

    type user struct{  // 结构体类型 user 
    	name string 
    	age byte
    }
    
    type manager struct{ // 匿名嵌入其他类型
    	user
    	title string
    }
    
    func main() {
    	var m manager
    	m.name = "Alice"
    	m.age = 29
    	m.title = "CTO"
    	fmt.Println(m)
    }
    
    //  output 
    //  {{Alice 29} CTO}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    可以为当前包内的任意类型定义方法

    type X int
    
    func (x *X) inc() {
    	*x++
    }
    
    func main() {
    	var x X
    	x.inc()
    	println(x)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    还可以直接调用匿名字段的方法,这种方式可以实现与继承类似的功能

    import (
    	"fmt"
    )
    
    type user struct {
    	name string
    	age  byte
    }
    
    func (u user) toString() string {
    	return fmt.Sprintf("%+v", u)
    }
    
    type manager struct {
    	user
    	title string
    }
    
    func main() {
    	var m manager
    	m.name = "Alice"
    	m.age = 29
    	println(m.toString()) // 调用 user.toString()方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3. 接口

    接口采用了duck type 方式,也就是说无须在实现类型上添加显式声明

    import (
    	"fmt"
    )
    
    type user struct {
    	name string
    	age  byte
    }
    
    func (u user) toString() string {
    	return fmt.Sprintf("%+v", u)
    }
    
    func (u user) Print() {
    	fmt.Printf("%+v\n", u)
    }
    
    type Printer interface { // 接口类型
    	Print()
    }
    
    func main() {
    	var m user
    	m.name = "Alice"
    	m.age = 29
    	// 声明一个变量p 类型为Printer,
    	//该类型为一个接口类型, 因为m 实现了这个方法
    	// 所以 m可以赋值给p
    	var p Printer = m
    	p.Print()
    }
    
    • 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

    另外,go语言有空接口类型interface{},用途类似OOP里面的system.Object, 可接收任意类型的对象。

    4. 并发

    整个运行时完全并发化设计,凡是所见的,几乎都在以goroutine方式运行,这是一种比普通协程或线程更加高效的并发设计,能轻松创建和运行成千上万的并发任务。

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func task(id int) {
    	for i := 0; i < 5; i++ {
    		fmt.Printf("id = %d: %d\n", id, i)
    		time.Sleep(time.Second)
    	}
    }
    
    func main() {
    	go task(1)
    	go task(2) // 创建 goroutine
    
    	time.Sleep(time.Second * 6)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    通道 channel 与 goroutine 搭配,实现用通信代替内存共享的CSP模型

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func task(id int) {
    	for i := 0; i < 5; i++ {
    		fmt.Printf("id = %d: %d\n", id, i)
    		time.Sleep(time.Second)
    	}
    }
    
    // 消费者
    func consumer(data chan int, done chan bool) {
    	for x := range data { // 接收数据
    		println("recv:", x)
    	}
    	done <- true // 通知main, 消费结束
    }
    
    // 生产者
    func producer(data chan int) {
    	for i := 0; i < 4; i++ {
    		data <- i // 发送数据
    	}
    	close(data) // 生产结束,关闭通道
    }
    
    func main() {
    	done := make(chan bool) // 用于接收消费结束通道
    	data := make(chan int)  // 数据管道
    
    	go consumer(data, done) // 启动消费者
    	go producer(data)       // 启动生产者
    
    	<-done // 阻塞,直到消费者发回结束信号
    }
    
    • 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
  • 相关阅读:
    【c++】类和对象
    Oxidized-Docke配置
    Unity 编辑器资源导入处理函数 OnPostprocessTexture :深入解析与实用案例
    Error creating bean with name ‘apiModelSpecificationReader‘ defined in URL
    代数与逻辑:作业三 贝叶斯决策
    内容+货架“攻防一体”,京东能否上演“后来居上”?
    1-丁基-3-甲基咪唑醋酸盐[Bmim][Ac]|离子液体1,1,3,3,-四甲基胍乳酸盐TMGL
    MATLAB中chirp函数使用
    置信度--学习笔记
    分布式事务Seata
  • 原文地址:https://blog.csdn.net/Leesure_CSDN/article/details/125608946