Go语言核心36讲(郝林)笔记
谛听-
线上幽灵
展开
-
go---库源码文件
源文件和库文件放在同一文件夹下同一个目录下的源码文件都应被声明属于同一个代码包。源码文件声明的包名可以于其所在目录的名称不同,只要这些文件声明的包名一致就可以了。demo.gopackage mainimport ( "flag" // 接收和解析命令参数)var name stringfunc init(){ /* 第 1 个参数为存储改命令参数值的地址 第 ...原创 2019-03-13 21:09:52 · 417 阅读 · 0 评论 -
go---命令源码文件
如果一个源码文件声明属于main包,并且包含一个无参数声明且无结果声明的 main 函数,那么它就是命令源码文件。package mainimport "fmt"func main(){ fmt.Println("Hello, world!")}根据运行程序时根据给定的参数问候某人:package mainimport ( "flag" // 接收和解析命令参数 ...原创 2019-03-13 20:15:00 · 263 阅读 · 0 评论 -
go---条件变量 sync.Cond
条件变量的初始化离不开互斥锁,它的方法有的也是基于互斥锁的。条件变量可以协调想要访问共享资源的线程。当共享资源的状态发生变化时,它可以被用来通知被互斥锁阻塞的线程。条件变量的 Wait 方法做了什么?把调用它的 goroutine 加入到当前条件变量的通知队列中。解锁当前的条件变量基于的那个互斥锁。所以在调用该 Wait 方法前,必须先锁定互斥锁,否则会引发不可恢复的 panic。让...原创 2019-03-18 20:54:19 · 383 阅读 · 0 评论 -
go---临时对象池 sync.Pool
可以把临时对象池当作针对某种数据的缓存来用。sync.Pool 有一个 New 字段,初始化池的时候最好给定它。sync.Pool 只有两个方法:Put 和 Get。当临时对象池中的对象在一段时间内不被使用时,会被 Go 语言运行时系统中的垃圾回收器及时清理掉。从 sync.Pool 中获取临时对象的步骤:package mainimport ( "bytes" "fmt" "...原创 2019-03-25 19:08:35 · 353 阅读 · 0 评论 -
go---bufio 包中的数据类型
bufio.Reader 中的缓冲区package mainimport ( "fmt" "bufio" "strings")func main() { comment := "Package bufio implements buffered I/O. " + "It wraps an io.Reader or io.Writer object, " + "creat...原创 2019-03-29 21:05:23 · 180 阅读 · 0 评论 -
go---并发安全字典 sync.Map
为了进一步明确并发安全字段中键值的实际类型,有两种方案:在编码时就完全确定键和值的类型,然后利用 Go 语言的编译器检查。接受动态的类型设置,并在程序运行时通过反射操作进行检查。前一种方案在扩展性方面有所欠缺,后一种方案通常会影响程序的性能。sync.Map 中的 read 与 dirty 字段:sync.Map 中的 read 与 dirty 互换:...原创 2019-03-26 13:53:12 · 771 阅读 · 0 评论 -
go---使用 os 包中的API
os 包中提供平台不相关的 API。os.File 操作文件的方式package mainimport ( "fmt" "os" "path/filepath" "syscall")func main() { // os.Create: 根据给定的路径创建一个新的文件 // 返回一个 File 值和一个错误值 // 在返回的 File 值上可对相应的文件进行读写操作 ...原创 2019-03-30 14:13:26 · 447 阅读 · 0 评论 -
go---访问网络服务
syscall.Socketpackage mainimport ( "fmt" "syscall")func main() { fd1, err := syscall.Socket( syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP) if err != nil { fmt.Printf("socke...原创 2019-03-30 15:59:40 · 316 阅读 · 0 评论 -
go---原子操作
因为原子操作不能被中断,所以它需要足够简单,并且要求快速。因此,操作系统层面只对二进制位或整数的原子操作提供了支持。原创 2019-03-23 20:42:23 · 567 阅读 · 0 评论 -
go---基于HTTP协议的网络服务
http.Getpackage mainimport ( "fmt" "net/http")func main() { host := "baidu.com" url1 := "http://" + host fmt.Printf("Send request to %q with method GET ...\n", url1) // 第一个结果值的类型为 *http.R...原创 2019-03-30 20:49:20 · 851 阅读 · 0 评论 -
go---unicode 与字符编码
package mainimport ( "fmt")func main() { str := "Go爱好者" fmt.Printf("The string: %q\n",str) // 当 string 转换为 []rune 时,字符串会被拆分成一个个 Unicode 字符 fmt.Printf(" => runs(char): %q\n", []rune(str))...原创 2019-03-26 19:52:36 · 1012 阅读 · 0 评论 -
go--- strings 包与字符串操作
与 string 值相比,strings.Builder 类型的值的优势:已存在的内容不可变,但可以拼接更多的内容;减少了内存分配和内容拷贝的次数;可将内容重置,可重用值。与 string 值相比,Builder 值的优势主要体现在字符串拼接方面。package mainimport ( "fmt" "strings")func main() { // 拼接方法 /...原创 2019-03-26 20:57:12 · 287 阅读 · 1 评论 -
go---sync.WaitGroup 和 sync.Once
sync.WaitGroup 是开箱即用的,也是并发安全的,一旦被真正使用后就不能被复制了。WaitGroup 类型有三个指针方法:Add:计数器加一Done :计数器减一,最好挂在 defer 语句中Wait:阻塞当前 goroutine,直到计数器归零package mainimport ( "fmt" "sync" "sync/atomic" "time")f...原创 2019-03-23 21:18:23 · 258 阅读 · 0 评论 -
go---context.Context 类型
如果不能一开始就确定子任务的 goroutine 的数量,那么使用 WaitGroup 值是有风险的。原创 2019-03-24 17:22:48 · 432 阅读 · 0 评论 -
go---bytes 包与字节串操作
Buffer 值的长度是未读内容的长度,而不是已存内容的总长度。原创 2019-03-27 20:23:21 · 1225 阅读 · 2 评论 -
go---sync.Mutex 与 sync.RWMutex
同步的用途是避免多个线程在同一时刻操作同一个共享资源。一个互斥锁只保护一个临界区或一组相关临界区。一旦声明了 sync.Mutex 类型的变量,就可以直接使用了。package mainimport ( "fmt" "flag" "bytes" "io" "io/ioutil" "log&a原创 2019-03-18 19:25:13 · 424 阅读 · 0 评论 -
go---测试的基本规则和流程
测试源码文件的主名称应该以被测试源码文件的主名称为前导,并且以”_test“为后缀。Go 语言对测试函数的名称和签名的规定:对于功能测试函数,名称前缀必须为 Test,唯一参数类型为 *testing.T对于性能测试函数,名称前缀必须为 Benchmark,唯一参数类型为 *testing.B对于示例测试函数,名称前缀必须为 Example,参数没有规定。只有测试源码文件的名称对了,...原创 2019-03-17 21:20:52 · 413 阅读 · 0 评论 -
go---panic 函数、recover 函数以及 defer 语句
panic 也可被称为运行时恐慌,是一种只能在程序运行期间跑车的程序异常。如果不处理,panic 就会导致程序崩溃并终止运行。recover 专用于回复 panic。defer 语句是被用来延迟执行代码的,延迟到语句所在函数即将结束的那一刻。package mainimport ( "fmt" "errors")func main() { fmt.Println(&原创 2019-03-17 20:02:53 · 291 阅读 · 0 评论 -
go--- =和 :=
声明变量方式一:基本方式= 使用必须使用先 var 声明package mainimport "fmt" func main(){ var name = "Tom" fmt.Println(name)}声明变量方式二:短变量声明:= 是声明并赋值,不需要var关键字只能在函数体内部原创 2019-03-14 12:33:41 · 1056 阅读 · 3 评论 -
go---判断变量类型、别名类型
package mainimport ( "fmt" )var container = []string{"zero", "one", "two"}func main(){ container := map[int]string{0: "zero&am原创 2019-03-14 18:23:47 · 692 阅读 · 0 评论 -
go---数组和切片
数组的长度的固定的,切片的长度是可变的。数组的长度是其类型声明的一部分。数组可以被叫做切片的底层数组,而切片可以被看作是对数组的某个连续片段的引用。切片的容量可以被看作是透过该窗口最多可以看到的底层数组中元素的个数。在底层数组不变的情况下,切片代表的窗口可以向右扩展,直到底层数组的末尾。切片的长度与容量:package mainimport "fmt"func main(){...原创 2019-03-14 18:55:52 · 139 阅读 · 0 评论 -
go---字典的操作和约束
go 的字典类型是一个哈希表的特定实现,键的类型是受限的,但元素可以是任意类型的。字典的用法:package mainimport "fmt"func main(){ aMap := map[string]int { "one": 1, "two": 2, "three": 3, } k := "two" v, ok := aMap[k] if ok { ...原创 2019-03-14 19:43:23 · 300 阅读 · 0 评论 -
go---通道的基本操作
通道类型是 go 自带的、唯一一个可满足并发安全的类型。使用 make 声明并初始化一个通道。一个通道相当于一个 FIFO 队列。元素的发送和接收都用到接送操作符 <-。package mainimport "fmt"func main(){ ch1 := make(chan int, 3) // 声明并初始化了一个元素类型为 int、容量为 3 的通道 ch1 ch1 ...原创 2019-03-14 20:35:15 · 655 阅读 · 0 评论 -
go---通道的高级玩法
通道一般指双向通道,也可定义单向通道。单通道最主要的用途是约束其它代码的行为。package mainimport ( "fmt" "math/rand")func main(){ recvChan := make(chan <- int, 1) // 只能收不能发的通道 recvChan <- rand.Intn(1000) sendChan := mak...原创 2019-03-14 21:16:24 · 355 阅读 · 0 评论 -
go---使用函数的正确姿势
函数是一等公民,函数类型是一等的数据类型。函数值是能被随意传播的独立逻辑组件。package mainimport ( "fmt")// 函数声明,名叫 Printer// 参数:contents string// 返回的结果列表:n int, err errortype Printer func(contents string) (n int, err error)//...原创 2019-03-15 12:44:48 · 201 阅读 · 0 评论 -
go---结构体及其方法的使用法门
结构体的方法package mainimport ( "fmt")type AnimalCategory struct { kingdom string // 界 phylum string // 门 class string // 纲 order string // 目 family string // 科 genus string // 属 specie...原创 2019-03-15 13:21:13 · 263 阅读 · 0 评论 -
go---接口类型的合理运用
接口的实现package mainimport ( "fmt")// 接口中是方法的定义type Pet interface { SetName(name string) Name() string}type Dog struct { name string}// *Dog 的方法集合中有 Pet 接口的全部方法// *Dog 就是 Pet 接口类型的实现类型,...原创 2019-03-15 20:32:23 · 381 阅读 · 0 评论 -
go---关于指针的有限操作
对于不可变的值、临时结果、不安全的操作结果,均不可寻址。package maintype Named interface { Name() string}type Dog struct { name string}func (dog *Dog) SetName(name string) { dog.name = name}func (dog Dog) Name() s...原创 2019-03-17 15:14:08 · 165 阅读 · 0 评论 -
go---go 语句及其执行规则
package mainimport ( "fmt")func main() { for i := 0; i &lt; 10; i++ { go func() { fmt.Println(i) }() }}不会打印任何内容:当程序执行到一条 go 语句时,Go 语言运行时系统会试图从某个存放空闲的 goroutine 的队列中获取一个 goroutine,找...原创 2019-03-17 16:38:19 · 575 阅读 · 0 评论 -
go---if 语句、for 语句和 switch 语句
if、forpackage mainimport "fmt"func main() { numbers1 := []int{1, 2, 3, 4, 5, 6} // numbers 是一个切片,迭代变量就有两个 // 右边表示当前的元素值,左边表示该元素值在切片中的索引值 // 只有一个迭代变量时,代表该元素值在切片中的索引值 for i := range numbers1 ...原创 2019-03-17 17:22:47 · 182 阅读 · 0 评论 -
go---错误处理
package mainimport ( "fmt" "errors")func echo(request string) (response string, err error) { if request == "" { err = errors.New("empty request") return } response = fmt.Sprintf("echo: %...原创 2019-03-17 19:30:29 · 171 阅读 · 0 评论 -
go---io 包中的接口和工具
package mainimport ( "bytes" "fmt" "io" "strings")func main() { // strings.Builder 主要用于构建字符串,实现的接口如下 builder := new(strings.Builder) _ = interface{}(builder).(io.Writer) _ = interface{}(b...原创 2019-03-28 20:02:28 · 386 阅读 · 2 评论