You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中为引用类型声明指针是否存在优势?

Go语言引用类型参数使用指针的优势分析

在Go语言中,切片、映射(map)、通道(channel)、指针及函数这类引用类型作为函数参数时,我们可以选择直接传值或者传指针。比如下面的示例代码中,两种传参方式都能实现修改原切片元素的效果,但传指针的方式是否具备实际优势?

package main

import (
    "fmt"
)

func main() {
    s := []string{"one", "two"}
    changeValue(0, s)
    fmt.Println(s) // 输出: [newOne two]

    s = []string{"one", "two"}
    changeValue2(0, &s)
    fmt.Println(s) // 输出: [newOne two]
}

func changeValue(i int, v []string) {
    v[i] = "newOne"
}

func changeValue2(i int, v *[]string) {
    (*v)[i] = "newOne"
}

核心区别与指针方式的适用场景

  • 修改引用类型本身的结构时必须用指针
    你提到的示例中,两种方式都能修改切片元素,是因为切片本身包含指向底层数组的指针,传值时复制的是切片的结构体(包含指针、长度、容量),所以依然能通过这个副本的指针修改底层数组。但如果需要修改切片本身的结构(比如调用append后需要让原切片指向新的底层数组),直接传值就不行了,必须传指针:

    func appendValue(v []string) {
        v = append(v, "three") // 这里修改的是切片副本,原切片不会变化
    }
    
    func appendValue2(v *[]string) {
        *v = append(*v, "three") // 修改的是原切片本身,原切片会新增元素
    }
    

    这种场景下,指针方式是唯一能实现需求的选择。

  • 性能层面的差异微乎其微
    你说得没错,传指针时依然会复制这个指针值(8字节,64位系统),而切片结构体本身的大小也是24字节(指针、长度、容量各8字节),两者的复制成本都极低,除非在超高频调用的场景下,否则性能差异可以忽略不计。

  • 可读性与代码意图的明确性
    使用指针作为参数,能更清晰地向代码阅读者传达:这个函数可能会修改传入的引用类型本身的结构,而不仅仅是它指向的数据。如果只是修改底层数据,直接传值的写法更符合Go的惯用风格,也更简洁。

其他引用类型的情况

  • 映射(map)、通道(channel):它们本身就是引用类型,传值时复制的是指向底层数据结构的指针,所以修改映射内容、操作通道时直接传值即可。只有当你需要替换整个map/channel的引用时,才需要传指针,但这种场景非常少见。
  • 指针类型:如果参数本身就是指针,再传指针就是二级指针了,只有在需要修改原指针指向的情况下才会用到,比如初始化一个指针变量。
  • 函数类型:函数本身也是引用类型,传值时复制的是函数指针,通常直接传值即可,传指针的场景极少。

内容的提问来源于stack exchange,提问作者zidk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 01:52:17