Go

Go 1.8的几个新特性

2017-02-17
Go

Go1.8发布了,这里先简单学习一下Go1.8的几个新特性。

新的切片排序Api #

在以前要对切片排序要实现sort.Interface接口:

 1package main
 2
 3import (
 4	"fmt"
 5	"sort"
 6)
 7
 8type Person struct {
 9	Name string
10	Age  int
11}
12
13func (p Person) String() string {
14	return fmt.Sprintf("%s: %d", p.Name, p.Age)
15}
16
17// ByAge implements sort.Interface for []Person based on
18// the Age field.
19type ByAge []Person
20
21func (a ByAge) Len() int           { return len(a) }
22func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
23func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
24
25func main() {
26	people := []Person{
27		{"Bob", 31},
28		{"John", 42},
29		{"Michael", 17},
30		{"Jenny", 26},
31	}
32
33	fmt.Println(people)
34	sort.Sort(ByAge(people))
35	fmt.Println(people)
36
37}

现在只需这样做:

...

Go语言中关于JSON的整理

2017-01-22
Go

JSON作为一种在不同平台间的数据交换格式,Go的标准包encoding/json中实现了对json的编码(marshal)和解码(unmarshal)功能。

json.Marshal #

json.Marshal函数实现Json的编码:

  • 如果给定的值不等于nil并且实现了json.Marshaler接口,调用json.Marshaler的MarshalJSON方法完成编码
  • 如果没有实现json.Marshaler接口,而是实现了encoding.TextMarshaler,将调用其MarshalText完成编码
  • 否则将按照下面的默认情况进行编码:
    • bool 编码为 JSON boolean
    • 整形,浮点型等数值 编码为 JSON number
    • string 编码为 JSON string
    • array和slice编码为JSON array, []byte作为例外会被编码成base64 string
    • map[string]interface{}编码为JSON object
    • struct编码为JSON object(只适用struct的可导出字段)
    • nil编码为JSON null

json tag定制struct编码 #

  • json:"-"忽略字段

    ...

Golang 1.7 GC的简单理解

2016-12-20
Go

从Go 1.7 runtime包理解Golang GC #

Go也是垃圾回收的,实现方式和别的语言不太一样。

先从Go的标准库的runtime包说起,这个包有很多运行时相关的类型和函数。

调用runtimea.GC()可以触发GC,但我们一般不会这么做,先读一下这个函数的注释说明。

1GC runs a garbage collection and blocks the caller until the garbage collection is complete. 
2It may also block the entire program

大概的意思是,Go的GC触发时会阻塞整个程序的运行。这个在垃圾回收里面有一个比较有名的名词叫STW,Stop the World。就是说程序在GC时“整个世界会停止下来”。 Go垃圾回收的STW一直是Go语言被指责和诟病最多的地方,也是Go的每个版本都努力改进的地方。

...

从源码理解Go:map

2016-11-15
Go

map的内部结构 #

Go中的map使用哈希表实现的,在源码go runtime/hashmap.go中可以看到对应实现。

 1// A header for a Go map.
 2type hmap struct {
 3	// Note: the format of the Hmap is encoded in ../../cmd/internal/gc/reflect.go and
 4	// ../reflect/type.go. Don't change this structure without also changing that code!
 5	count     int // # live cells == size of map.  Must be first (used by len() builtin)
 6	flags     uint8
 7	B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
 8	noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
 9	hash0     uint32 // hash seed
10
11	buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
12	oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
13	nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)
14
15	// If both key and value do not contain pointers and are inline, then we mark bucket
16	// type as containing no pointers. This avoids scanning such maps.
17	// However, bmap.overflow is a pointer. In order to keep overflow buckets
18	// alive, we store pointers to all overflow buckets in hmap.overflow.
19	// Overflow is used only if key and value do not contain pointers.
20	// overflow[0] contains overflow buckets for hmap.buckets.
21	// overflow[1] contains overflow buckets for hmap.oldbuckets.
22	// The first indirection allows us to reduce static size of hmap.
23	// The second indirection allows to store a pointer to the slice in hiter.
24	overflow *[2]*[]*bmap
25}
26
27// A bucket for a Go map.
28type bmap struct {
29	// tophash generally contains the top byte of the hash value
30	// for each key in this bucket. If tophash[0] < minTopHash,
31	// tophash[0] is a bucket evacuation state instead.
32	tophash [bucketCnt]uint8
33	// Followed by bucketCnt keys and then bucketCnt values.
34	// NOTE: packing all the keys together and then all the values together makes the
35	// code a bit more complicated than alternating key/value/key/value/... but it allows
36	// us to eliminate padding which would be needed for, e.g., map[int64]int8.
37	// Followed by an overflow pointer.
38}

先删掉代码原有注释,以便于查看:

...

从源码理解Go:slice

2016-11-15
Go

slice的内部结构 #

一个slice本质上是一个数组的某个部分的引用。在go runtime/slice.go源码中定义了slice的结构:

1type slice struct {
2	array unsafe.Pointer
3	len   int
4	cap   int
5}

可以看到在Go的内部,slice是一个包含3个字段的结构体:

...

Go编程的三十六个套路: int与[]byte互转用于数据传输

2016-03-01
Go

1. encoding/binary包简介 #

在用Go进行数据传输的场景下,例如文件传输或文件存储时,需要将Go的数据例如int转换为[]byte。 得到的[]byte可以进一步在网络上传输或写入到文件中。这个场景需要借助go标准库中的encoding/binary包来实现。

encoding/binary包实现了简单的数字与字节序列的转换以及变长值的编解码。 一个定长值是指要么是固定长度的数字类型(int8, uint8, int16, float32, complex64, …)或者只包含定长值的结构体或者数组。

...

Golang 笔记:临时对象池sync.Pool

2015-02-03
Go

sync.Pool可以被看做是存放可被重用的值的容器,这个容器具有以下特性:可自动伸缩、高效、并发安全。 因为它的使用场景并不适用于诸如数据库连接池这类需要我们自己管理生命周期的资源对象的池化场景,所以一般把sync.Pool称为临时对象池(其实叫做临时对象缓存更合适),主要用来存放已经分配的但是暂时不需要使用的对象,在需要使用的时候再从临时对象池中取出。

...

Golang 笔记:channel

2015-01-05
Go

CSP(CommunicatingSequentialProcess)中文翻译"通信顺序进程"或"交换信息的循序进程", CSP描述了一种并发系统进行交互的模式。 CSP允许使用进程组件来描述系统,这些进程组件独立运行并且通过消息传递的方式通信。

...

© 2024 青蛙小白