Skip to main content

go 命名返回值

在你的代码中:

func (apiService *ApiService) GetApiById(id int) (api system.SysApi, err error) {
err = global.GVA_DB.First(&api, "id = ?", id).Error
return
}

虽然看起来没有显式地声明 api,但实际上它已经隐式声明了。这是 Go 语言中的一种特性,称为命名返回值


1. 命名返回值

在 Go 中,当函数的返回值在函数签名中被命名时,这些返回值会被隐式声明为函数体中的局部变量。

在你的代码中,函数签名是:

func (apiService *ApiService) GetApiById(id int) (api system.SysApi, err error)
  • apierr 是命名返回值。
  • 它们在函数体内被隐式声明为局部变量,相当于在函数体的顶部自动添加了以下代码:
var api system.SysApi
var err error

因此,在函数体中,你可以直接使用 apierr,无需显式声明它们。


2. 代码解析

err = global.GVA_DB.First(&api, "id = ?", id).Error
  • api 是函数的命名返回值,已经被隐式声明为类型为 system.SysApi 的变量。
  • global.GVA_DB.First(&api, "id = ?", id) 会将查询结果赋值到 api 中。
  • 如果查询过程中发生错误,Error 会返回一个错误值,并赋值给 err

最后,通过 return 语句返回 apierr。由于返回值是命名的,return 可以省略具体的变量名,直接写 return 即可。


3. 等价代码(不使用命名返回值)

如果不使用命名返回值,上述代码可以改写为以下形式:

func (apiService *ApiService) GetApiById(id int) (system.SysApi, error) {
var api system.SysApi
var err error
err = global.GVA_DB.First(&api, "id = ?", id).Error
return api, err
}

这里显式地声明了 apierr,并在 return 中明确返回它们。


4. 命名返回值的优点

使用命名返回值有以下优点:

  • 代码更简洁:不需要显式声明返回值变量。
  • 方便处理默认值:即使函数中没有显式赋值,命名返回值也会被初始化为其类型的零值。例如:
    • api 会被初始化为 system.SysApi 的零值。
    • err 会被初始化为 nil

5. 命名返回值的注意事项

虽然命名返回值很方便,但需要注意以下几点:

  1. 可能引起混淆:如果函数体较长,命名返回值可能让人忘记它们已经被隐式声明,导致误以为它们是未声明的变量。
  2. 容易遗漏返回值:如果函数体中没有对某个命名返回值赋值,它会以零值返回,可能导致意外行为。

总结

  • 在你的代码中,apierr 是函数签名中定义的命名返回值,已经被隐式声明为局部变量。
  • 因此,函数体中可以直接使用它们,而无需显式声明。