golang 中时候用指针什么时候用普通对象?

golang 中的指针已经和c++中的指针不太一样了,至少不用解指针,也不用delete,所以感觉传递参数的时候感觉用对象和指针差不多,至少全局变量在保存的时候好像都一样

什么时候用指针呢?什么时候用对象呢

阅读 8.7k
5 个回答
  1. Go的函数调用是值传递,所以如果传对象会进行拷贝.所以一般情况下使用指针,如果要修改参数,则必须使用指针
  2. 当然如果参数的结构不大,并且是无状态的结构,则可以使用结构..
  • 在定义方法时,使用指针,可以修改对象值;使用对象,则无法修改。
  • delete 是不需要(golang 有gc);但是解指针在特定的地方还是会用到的。比如如下代码:
import "fmt"

func main(){
    data := 1
    pointer := &data

    PrintInt(*pointer)
}


func PrintInt(integer int){
    fmt.Println(integer)
}
// 下例子说明结构体的 receive 是否需要指针问题
type Config struct {
    addr string 
}

// 需要访问内部属性并且修改,应该为引用类型
func (c *Config) SetAddr(addr string)  {
    // c 是一个指针类型
    // golang 在内部已经做出了指向,访问属性则直接给出属性值, 而不需要先用指针得到值,再用值去拿到需要得到的属性
    // 下面的一部,代替了注释中的3步 .
    
    c.addr = addr 
    
    // not that:
    // cVal := *c
    // cVal.addr = addr 
    // *c = cVal
}

// 只需要读,不需要写,可以不用指针类型
func (c Config)GetAddr() string {
    return c.addr
}

type Server struct{
    config *Config
}

// 传递的是指针, 内存占用为 只发生了 config指针的地址的拷贝.
// 通过该指针,可以访问到外部的Config
func NewServer(config *Config) {
}

// 传递的是值 . 内存发生了 config值的拷贝, 如果该结构体的内存占用比较大
// 这种方式传递显然是对性能不好的
func NewServer2(config Config) {
}
  • 对于golang语言本身,有几个是默认指针传递的 map, slice

// 可以理解为  map|slice|chan 本身就是一个指针
// 如果传递指针的指针 就没多大的意义了
func main(){
    var m = map[string][string]{
        "foo":"bar",
    }
    
    change(m)
    fmt.Println(m["foo"]) // changed
    
    changePtr(&m)
    fmt.Println(m["foo"]) // changed2
}

// map传递的是 m 的指针的地址,但是函数内部拿到的 map 是可以访问实际的map的,
// 只发生了指针的拷贝,而没有发生值的拷贝
func change(m map[string]string) {
    m["foo"] = "changed"
}

// 如果传递指针会怎么样
func changePtr(m *map[string]string) {
    // 需要先通过指针拿到值
    mVal := *m
    mVal["foo"] = "changed2"
}

这么打个比喻:
初始化 爸爸姓名:张三,儿子姓名:张四

指针传递:
爸爸改姓为:李(李三),那么儿子姓名则为:李四

值传递:
爸爸改姓为:李(李三),儿子姓名仍为:张四

其实就两点,一是,如果数据结构比较大,建议采用指针,不会发生值拷贝。二是,如果需要修改结构的话,必须用指针。

还有最后一点,如果是 chan、slice、map,如果不需要修改它的值,值传递即可,虽然它们的数据量可能很大,但可把他们理解为其他语言的引用类型,其实本质也是结构体,只不过内部是包含指针属性。

1 篇内容引用
推荐问题
宣传栏