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

Golang中*[]*types.a与[]*types.b的区别及函数参数解析

Go语言参数类型解析:以Congress.Finalize函数为例

先看你给出的函数声明:

func (c *Congress) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs *[]*types.Transaction, uncles []*types.Header, receipts *[]*types.Receipt, systemTxs []*types.Transaction) error {

1. 目标参数含义解析

uncles []*types.Header

这是一个切片,元素类型为*types.Header(指向types.Header结构体的指针)。Go语言中切片本身是包含底层数组指针、长度、容量的结构体,传递切片时是值拷贝,但底层数组不会被复制:

  • 函数内部修改切片元素(比如修改某个*types.Header指向的结构体字段),外部能同步看到变化;
  • 但如果对切片本身做追加、截断等修改(改变切片的长度/容量),外部不会同步,因为操作的只是切片结构体的副本。

在区块链场景中,uncles代表叔块头列表,这里用切片传递,说明函数仅需读取叔块数据或修改叔块头的内部字段,无需替换整个叔块列表。

txs *[]*types.Transaction

这是一个指向切片的指针,切片的元素是*types.Transaction(指向交易结构体的指针)。传递切片指针的核心目的是让函数能直接修改原切片本身:

  • 比如追加新交易、清空切片、替换整个切片内容等操作,都会直接作用到外部传入的切片上,而非副本。

Finalize作为区块最终处理函数,可能需要对交易列表做结构性调整(比如移除无效交易),因此用指针传递切片,确保外部能拿到修改后的最终交易列表。

2. *[]*types.a与[]*types.b的核心区别

[]*types.b(元素为指针的切片)

  • 本质:Go原生切片类型,内部封装底层数组指针、长度、容量;
  • 传递方式:值传递,函数接收的是切片结构体的副本;
  • 修改范围:可修改切片元素的内部数据(因为元素是指针),但无法修改切片本身的长度、容量或替换整个切片;
  • 使用场景:仅需读取切片内容或修改元素内部数据,无需改变切片结构时使用。

*[]*types.a(指向元素为指针的切片的指针)

  • 本质:指向切片的指针,目标对象是一个切片;
  • 传递方式:传递指针的内存地址,函数可直接操作原切片结构体;
  • 修改范围:既能修改切片元素的内部数据,也能直接修改切片的长度、容量,甚至替换整个切片;
  • 使用场景:需要对切片本身做结构性修改(追加、截断、替换),或不想通过返回值传递修改后的切片时使用。

举个极简示例辅助理解:

// 接收[]*int,无法修改原切片长度
func modifySlice(s []*int) {
    *s[0] = 100 // 修改元素内容,外部可见
    s = append(s, new(int)) // 追加操作仅作用于副本,外部无变化
}

// 接收*[]*int,可修改原切片长度
func modifySlicePtr(s *[]*int) {
    *(*s)[0] = 200 // 修改元素内容,外部可见
    *s = append(*s, new(int)) // 追加操作直接作用于原切片,外部同步变化
}

内容的提问来源于stack exchange,提问作者FLAME'S KING

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 23:15:55