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

Go中*[]Type与[]*Type的区别及元素取值(附C语言类比)

详解Go中[]Person与[]Person的差异(附C语言类比)

首先先修正一下你给出的Go结构体定义(Go里结构体必须用struct关键字,而且首字母大写的字段才能被包外访问,小写字段是包内私有):

type Person struct { 
    Name string 
    Age int  // 这里把age改成Age,方便外部访问
}
type People struct { 
    City string 
    List []*Person // 切片元素是Person指针
}
type People2 struct { 
    City string 
    List *[]Person // 指向Person切片的指针
}

1. []*Person 是什么?怎么获取元素?

含义

[]*Person 是一个切片,切片中的每个元素都是指向Person结构体的指针。

用C语言类比的话,这就相当于你在C里定义的动态指针数组:

// 假设已经malloc分配了足够的内存
Person** list = (Person**)malloc(10 * sizeof(Person*));

每个list[i]都是一个Person*指针,可以指向栈上或者堆上的Person实例。

获取元素值

因为切片里的元素是指针,你可以直接通过索引访问指针,然后用.(Go会自动解引用指针)获取字段:

// 假设people是People类型的实例,且List已经有元素
name := people.List[0].Name
age := people.List[0].Age
// 等价于显式解引用:(*people.List[0]).Name

如果你要修改Person的字段,直接修改就行,因为操作的是指针指向的原实例,会影响底层对象。

2. *[]Person 是什么?怎么获取元素?

含义

*[]Person 是一个指向Person类型切片的指针。

首先要知道:Go的切片本身是一个包含三个字段的结构体(类比C的自定义结构体):

// 模拟Go切片的C结构体
typedef struct {
    Person* data;  // 指向底层数组的指针
    int len;       // 切片长度
    int cap;       // 切片容量
} GoSlice;

那么*[]Person就相当于C里的GoSlice*——也就是指向这个切片结构体的指针,而不是指向底层数组的指针。

获取元素值

你需要先解引用指针拿到切片本身,再通过索引访问里面的Person值:

// 假设people2是People2类型的实例,且List已经指向一个有效的切片
name := (*people2.List)[0].Name
age := (*people2.List)[0].Age

这里必须先解引用指针(*people2.List)得到切片,才能用索引访问元素。如果要修改切片的长度(比如append扩容),或者替换整个切片,就需要用这个指针,否则修改的只是切片的副本。

核心差异总结

类型本质C语言类比常见使用场景
[]*Type元素为指针的切片Type**(指针数组)需要存储多个独立的Type实例,修改实例字段会直接生效
*[]Type指向Type切片的指针指向切片结构体的指针需要修改切片本身(比如append扩容、替换整个切片),或者在函数中传递切片避免拷贝

简单说:[]*Type是“装着指针的切片”,*[]Type是“指向切片的指针”,两者完全不是一回事。

内容的提问来源于stack exchange,提问作者Alex T. Liu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:38:59