Go 的具名返回值:先声明,再往里填
函数签名里不但写出返回类型,还给每个返回值起名字。这些名字在函数一进来就已经存在,零值可用,最后可以只写 return。
和普通返回差在哪
普通写法:类型在括号里,返回时把值按顺序递出去。
1 | func Depth() ([]*PriceLevel, []*PriceLevel) { |
具名写法:每个返回值有名字。这些名字是函数里的局部变量。
1 | func (ob *OrderBook) Depth() (asks, bids []*PriceLevel) { |
return 后面可以不写东西,叫 naked return(裸返回):把具名变量的当前值原样返回。
进来就是零值
具名返回值在函数开头就分配好了,没赋值也是该类型的零值:切片是 nil,error 是 nil,decimal.Decimal 是 0。
所以 processQueue 可以先记下还没吃掉的量,循环里再改:
1 | func (ob *OrderBook) processQueue(...) ( |
调用方仍然按位置接:
1 | ordersDone, partialDone, partialProcessed, quantityLeft := ob.processQueue(bestPrice, quantity) |
名字只在函数内部当变量用,不影响外面怎么命名。
为什么订单簿爱用它
撮合一次要带回好几样东西:done、partial、已成交量、剩余量、err。具名之后,循环中间可以直接写 done = append(done, ...)、partial = ...,最后一行 return 即可。ProcessMarketOrder、ProcessLimitOrder 都是这个用法。
校验失败时不必用裸返回,按位置写清楚更安全:
1 | if quantity.Sign() <= 0 { |
注意两点
- 裸返回在长函数里不好读。 读者要回到签名才能确认带出去的是什么。短函数、或返回值本身就是在攒结果(像
Depth)时最合适。 defer能改具名返回值。defer在return之后、函数真正退出之前跑,改的是已经填好的那个变量。订单簿里没用这个技巧,知道有这回事即可。
一句话:具名返回值 = 返回槽位提前变成局部变量;return 可以不带参数,把槽位里的值交出去。
- Title: Go 的具名返回值:先声明,再往里填
- Author: Jeffery
- Created at : 2026-09-06 14:40:00
- Updated at : 2026-09-06 07:11:38
- Link: https://redefine.ohevan.com/2026/09/06/Go具名返回值/
- License: This work is licensed under CC BY-NC-SA 4.0.
Comments