Golang中哪种"return"写法更好?
Golang中哪种"return"写法更好? 抱歉问这么简单的问题:
哪种"return"方式性能更好或您通常使用哪种?(当您有很多返回值时)
这里是代码示例:
还有下面的代码:
A
func getInfo(a int, b string , c bool, d int ) (aa int , bb string , cc bool, dd int){
a = aa
b = bb
c = cc
d = dd
return
}
B
func getInfo2(a int, b string , c bool, d int ) ( int ,string , bool, int) {
if "ok" == "ok" {
return 1, "good", true, 2
}
return 0, "", false, 0
}
C
type InfoParameters struct {
A int
B string
C bool
D int
}
type InfoReturns struct {
AA int
BB string
CC bool
DD int
}
func getInfo3(all InfoParameters) (*InfoReturns) {
if "ok" == "ok" {
all.A = 1
all.B = "good"
all.C = true
all.D = 2
return &InfoReturns{all.A,all.B,all.C,all.D }
}
return nil
}
提前感谢。
更多关于Golang中哪种"return"写法更好?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
通常应避免使用方案A,除非某个算法使用命名返回值能让代码更优雅。大多数情况下,这种方式反而会造成理解困难。
方案B可以接受,但由于返回参数过多会导致函数难以使用。这个方案我也建议避免。
方案C适用于需要向后兼容的场景(比如后续可能增加返回值,且这是库API的情况)。否则我可能会直接复制结构体而不是返回指针。
我通常不会编写具有这么多返回值的函数,除非在特定上下文中确实有必要。大多数情况下这会造成困惑,特别是当返回值类型各不相同时。
顺便提一下,如果使用命名返回值,可以这样写:
func getInfo() (a string, b err) { return "hello", nil }
也就是说仍然可以像普通函数那样使用return语句。这种方式既能让命名返回值在延迟函数中使用,又能起到文档说明的作用。你会经常看到这种编码风格。
在Go语言中,处理多个返回值时,通常推荐使用命名返回值(如示例A)或结构体封装(如示例C),而不是裸返回多个值(如示例B)。以下是具体分析:
1. 示例A:命名返回值
这种方式通过预定义返回变量,在函数体内直接赋值,并使用裸return语句返回所有值。它提高了代码的可读性,尤其在返回值较多时,能清晰看出每个返回值的含义。
func getInfo(a int, b string, c bool, d int) (aa int, bb string, cc bool, dd int) {
aa = a + 1 // 直接操作命名返回值
bb = b + " processed"
cc = !c
dd = d * 2
return // 裸返回,自动返回aa、bb、cc、dd
}
优点:
- 代码自文档化:从函数签名即可了解返回值用途。
- 减少错误:避免在
return语句中误序或遗漏值。 - 性能:与示例B相当,Go编译器会优化,无额外开销。
2. 示例B:直接返回多个值
这种方式在return语句中显式列出所有值,适用于返回值较少(如2-3个)的场景,但多个返回值时容易出错。
func getInfo2(a int, b string, c bool, d int) (int, string, bool, int) {
if condition {
return 1, "good", true, 2 // 显式返回所有值
}
return 0, "", false, 0
}
缺点:
- 可读性差:当返回值增多时,难以快速对应每个值的含义。
- 维护困难:修改返回值时需确保顺序一致。
3. 示例C:使用结构体封装
当返回值超过3-4个或逻辑复杂时,推荐使用结构体。它通过单一类型聚合数据,简化函数签名,并支持返回指针以减少值复制(尤其在大型结构体时)。
type InfoReturns struct {
AA int
BB string
CC bool
DD int
}
func getInfo3(params InfoParameters) *InfoReturns {
if condition {
return &InfoReturns{
AA: params.A + 1,
BB: params.B + " processed",
CC: !params.C,
DD: params.D * 2,
}
}
return nil
}
优点:
- 可扩展性:轻松添加新字段,无需修改函数签名。
- 清晰性:调用方通过字段名访问数据,避免混淆。
- 性能:返回指针可避免结构体复制,提升效率(但需注意nil情况)。
性能与使用建议
- 性能:三种方式在性能上无显著差异,Go编译器会进行内联和优化。结构体指针(示例C)在大型数据时可能更高效。
- 推荐场景:
- 2-3个返回值:使用示例B的直接返回。
- 多个相关返回值:使用示例A的命名返回值。
- 复杂数据或需扩展时:使用示例C的结构体。
在实际项目中,示例A和示例C更常见,因其提升可维护性。例如,标准库的os.Open返回文件句柄和错误,使用多值返回;而复杂API(如数据库查询)常用结构体封装结果。



