go

1、Go提供了两种分配原语,即内建函数 new 和 make。 它们所做的事情不同,所应用的类型也不同。它们可能会引起混淆,但规则却很简单

new:用来分配内存的内建函数, 但与其它语言中的同名函数不同,它不会初始化内存,只会将内存置零。 也就是说,new(T) 会为类型为 T 的新项分配已置零的内存空间, 并返回它的地址,也就是一个类型为 *T 的值
make:内建函数 make(T, args) 的目的不同于 new(T)。它只用于创建切片、映射和信道,并返回类型为 T(而非 *T)的一个已初始化 (而非置零)的值

2、切片通过对数组进行封装,为数据序列提供了更通用、强大而方便的接口

func (f *File) Read(buf []byte) (n int, err error)
//Read 函数可接受一个切片实参 而非一个指针和一个计数
//该方法返回读取的字节数和一个错误值(若有的话)
//若要从更大的缓冲区 b 中读取前32个字节,只需对其进行切片即可
n, err := f.Read(buf[0:32])
//这种切片的方法常用且高效

创建等价的二维数组或切片,就必须定义一个数组的数组, 或切片的切片

type Transform [3][3]float64 
//一个 3x3 的数组,其实是包含多个数组的一个数组。
type LinesOfText [][]byte     
//包含多个字节切片的一个切片。

切片长度是可变的,因此其内部可能拥有多个不同长度的切片

3、映射是方便而强大的内建数据结构,它可以关联不同类型的值

var timeZone = map[string]int{
    "UTC":  0*60*60,
    "EST": -5*60*60,
    "CST": -6*60*60,
    "MST": -7*60*60,
    "PST": -8*60*60,
}

//赋值和获取映射值的语法类似于数组,不同的是映射的索引不必为整数
offset := timeZone["EST"]

4、Go并发
Go语言另辟蹊径,它将共享的值通过信道传递,实际上,多个独立执行的线程从不会主动共享

Go程具有简单的模型:它是与其它Go程并发运行在同一地址空间的函数
Go程在多线程操作系统上可实现多路复用,因此若一个线程阻塞,比如说等待I/O, 那么其它的线程就会运行
在函数或方法前添加 go 关键字能够在新的Go程中调用它。当调用完成后, 该Go程也会安静地退出

func Announce(message string, delay time.Duration) {
    go func() {
        time.Sleep(delay)
        fmt.Println(message)
    }()  // 注意括号 - 必须调用该函数。
}

5、信道与映射一样,也需要通过 make 来分配内存。其结果值充当了对底层数据结构的引用。 若提供了一个可选的整数形参,它就会为该信道设置缓冲区大小

ci := make(chan int)            // 整数类型的无缓冲信道
cj := make(chan int, 0)         // 整数类型的无缓冲信道
cs := make(chan *os.File, 100)  // 指向文件指针的带缓冲信道

猜你喜欢

转载自blog.csdn.net/xielinrui123/article/details/80614121
go