指针

指针变量是存储别的变量地址为自己的值的变量,我们常用的指针方法如下,通过&取变量地址,*p获取指向变量的值(在右边为取值,左边为指向的原始值赋值)。

    x := 1
    p := &x
    *p = 2
    fmt.Printf("%T", p)  // *int
    fmt.Printf("%v", *p) //  1
    fmt.Printf("%v", x)  // 2

在Go语言中,返回函数中局部变量的地址也是安全的。例如下面的代码,调用f函数时创建局部变量v,在局部变量地址被返回之后依然有效,因为指针p依然引用这个变量。

var p = f()
func f() *int {
    v := 1
    return &v
}

调用结果如下
fmt.Println(f() == f()) // "false"
new()

new也是一种内建的创建变量的方法,主要通过new(T)来返回一个匿名变量地址,指针类型为*T,初始化值为0。且每次返回的地址都不相同。下面的代码作用都是一样的。

func newString() *string {
    return new(string)
}

func newString() *string {
    var str string
    return &str
}

new函数使用通常相对比较少,因为对于结构体来说,直接声明更灵活。如果想自定义new,可以这么写。

func delta(old, new int) int { return new - old }

在该函数内部,默认new是一个整型变量,而不是内建函数new()。

make()

make也是一个内建函数,用来为 slice,map 或 chan 类型分配内存和初始化一个对象。

func make(t Type, size ...IntegerType) Type

make([]int,0,10) // make(类型,长度,内存大小)

new 的作用是初始化一个指向类型的指针(*T),make 的作用是只为 slice,map 或 chan 初始化并返回引用(T)。
make返回的还是这三个引用类型本身,而new返回的是指向类型的指针。