《GO语言实战》——笔记
第一章 简介
- goroutine
goroutine很想线程,但是它占用的内存远少于线程,需要的代码 - 通道
channel是一种内置的数据结构,可以让用户在不同的goroutine之间同步发送具有类型的数据 - Go语言类型系统
Go语言提供了灵活的,邬吉成的类型系统,无需降低运行性能就能最大成都上复用代码。
组合
(composition)设计模式,只需要简单的讲一个类型嵌入到另一个类型,就能复用所有的功能。- 内存管理
Go也拥有垃圾回收机制。
2.一个包定义一组编译过的代码,类似于命名空间。
import (
"log"
"os"
_ "github.com/goinaction/code/chapter2/sample/matchers"
)
"_" 是为了让go语言对包做初始化,但是并不使用包里的标识符。为了让程序的可读性更强,go编译器不允许声明某个导入却不使用, 下划线是让编译器接收这种导入。
func init() {
loc.SetOutput(os.Stdout)
}
程序中每个代码文件里的init函数都会在main函数执行前调用。
标识符以大写字母开头,为公开。 如果以小写字母开头则是不公开。不能被其他包中对象引用。
make(map[string]string)
map是Go语言里的一个引用类型,需要使用make来构造。
feeds, err := RetrieveFeeds()
:= 简化变量声明运算符。 这个运算符和var声明的变量没有任何区别
restuls := make(chan *Result)
在 go语言中, channel, map和 slice 一样,也是引用类型。不过通道本身实现的是一组带类型的值,这组值用于在goroutine之间传递数据。通道内制同步机制,从而可以保证通信安全。
如果main函数返回,整个程序也就终止了,Go程序终止时,还会关闭所有之前启动而且还在运行 goroutine
for _, feed := range feeds {
}
for range实现对切片迭代,range可以用于迭代数组,字符串,切片,映射和通道。使用for range时,会返回两个值,第一个值时迭代的元素在切片里元素的位置,第二个时元素值的一个副本。
下划线标识符时占位符, 占据保存range 返回的索引值变量的位置。
matcher, exists := matchers[feed.Type]
if !exists {
// business logic
}
go func(param int) {
// code
}{x}
使用关键字go 启动一个goroutine,并对这个goroutine做并发调度
在go语言中, 所有的变量都以值的方式传递
Go语言支持闭包,
因为有闭包,函数可以直接访问那些没有作为参数的变量。匿名函数并没有拿到这些变量的而副本,而是直接访问外层函数作用域中声明的这些变量。
type Feed struct {
Name string `json:"site"`
URI string `json:"link"`
Type string `json:"type"`
}
"`"
里面的部分被称作为标记。这个标记里描述了JSON解码的元数据。defer file.Close()
defer关键字安排随后的函数调用在函数返回后才会执行。
func (dec *Decoder) Decode(v interface{}) error
Decode方法接受一个类型为interface{}的值作为参数。 这个类型在Go语言里很特殊,一般会配合reflect包里提供的反射功能一起使用。
type Matcher interface {
Search(feed * Feed, searchTerm string) ([]*Result, error)
}
声明一个接口
命名的时候,如果接口类型值包含一个方法,那么这个类型的名字以er结尾.
如果要让用户定义的类型实现一个接口,这个用户定义的类型要实现接口类型里面声明的所有方法。
func (m defaultMatcher) Search(feed *Feed, serachTerm string) ([]*Result, error) {
return nil, nil
}
Search方法于 defaultMatcher类型的值绑定在一起,意味着我们可以使用defaultMatcher类型的值或者指针来调用Search方法。
因为大部分方法在被调用后都需要维护接收者的值的状态,所以最佳实践是,将方法的接收者声明为指针。
与直接通过值或者指针调用方法不同,如果直接通过接口类型的值调用方法,规则有很大不同。
- 使用指针作接收者声明方法,只能在接口类型的值是一个指针的时候被调用。
- 使用值作为接受者声明方法,在接口类型的值为值或指针的时候豆科鱼i被调用。
- 同一个目录下,所有的.go文件必须同一个包名
- main的包具有特殊的含义。Go语言的编译程序会试图把这种名字的包编译为二进制可执行文件。
import (
"fmt"
"strings"
)
- 如果需要导入多个包,习惯上是将import语句包装在一个导入块中。
GOPATH指定的这些目录就是开发者的个人工作空间。
一旦编译器找到一个满足import的语句的包,就会进一步停止查找。
go get 远程导入 获取任意指定的url的包
go vet 代码检查
go fmt 代码格式化
第四章 数组、切片和映射 数组
- 声明
var array [5]int array := [5]int{1,2,3,4,5}// 自动计算长度 array := [...]int{1,2,3,4,5
array := [5]*int{0: new(int), 1: new(int)}
*array[0] = 10
*array[1] = 20
赋值数组指针值会复制指针的值,不会复制指针所指向的值。
array1 := [2]*string{new(string),new(string)}
var array2 [2]*string*array1[0] = "Red"
*array1[1] = "Blue"
array2 = array1*array2[0] ="black"fmt.Println(*array1[0])
fmt.Println(*array2[0])
在函数间传递数组
【《GO语言实战》——笔记】在函数间传递变量是,总是以值的方式传递。
如果比那辆是一个数组,意味着整个数组,不管有多长,都会完整复制,并传递给函数。
使用指针会更有效的利用内存,性能也更好。
var array [1e6]intfoo(&array)
Q
goroutine实现原理?
select 多路复用?
init 函数的执行顺序
匿名函数的匿名函数可以访问最外层的变量吗?(闭包有层级限制吗?)
interface {} ??
推荐阅读
- 慢慢的美丽
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 《跨界歌手》:亲情永远比爱情更有泪点
- 诗歌:|诗歌: 《让我们举起世界杯,干了!》
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- 人间词话的智慧
- 《一代诗人》37期,生活,江南j,拨动心潭的一泓秋水
- 广角叙述|广角叙述 展众生群像——试析鲁迅《示众》的展示艺术
- 书评——《小行星》