一个简单的demo说明Go语言中函数的最佳实践优雅的写法。
package main
import (
"encoding/json"
"fmt"
)
type User struct {
ID int
Name string
}
func main() {
// Retrieve the User profile
u, err := retrieveUser("sally")
if err != nil {
fmt.Println(err)
return
}
// Display the user profile
fmt.Printf("%+v\n", *u)
}
// 1. cool: 返回值只有两个;最好别超过三个,返回参数在标准库中你也是十分少见的
// 2. 返回参数的最佳实践应该是:error 在最后一个参数,另外再加上第二个参数。(也就是最多两个返回参数是最易读的)
// 3. (*User, error) 这里返回声明没有写为:(user *User, err error); 一个是为了便于阅读函数内部提高可读性,第二是避免出现 短式变量声明 中产生 变量阴影 shadows
func retrieveUser(name string) (*User, error) {
r, err := getUser(name)
// 此处 r 会在下文中继续引用 所以不适用如下的局部变量的方式写作
if err != nil {
return nil, err
}
var u User
// err = json.Unmarshal([]byte(r), &u)
// return &u, err // 这里返回的是 err 读者会去判断这个err到底是什么,是判断有错误的情况还是错误为nil的情况,不利于阅读
// 由上两行代码优化成如下行代码:
// 将 能确定的局部变量直接封死在局部范围内,不再带入后面的code中,影响阅读
if err := json.Unmarshal([]byte(r), &u); err != nil {
return nil, err
}
// 这里直接显示 返回nil ,读者一看就知道 描述的一定是成功无错误的情况
return &u, nil
}
func getUser(name string) (string, error) {
result := `{"id":42, "name":"sally"}`
return result, nil
}
总结:
由上述代码demo中,被注释的部分代码为不优雅不易于阅读的,其中大部分注意点都在注释中写清楚了,这里简单总结:
- 关于函数返回参数: 能不超过两个是最好的,最多包含三个。
- 关于 if err != nil 是提行写还是一行写完,主要在于下文是否要引用变量。如果能在局部域中结束的变量就一行搞定。
- 在函数末尾不要为了省略一两行代码就直接return含糊不清,未尽处理的error,不易于阅读理解。(直接清晰的 return nil 能够让读代码的人看见你是在讨论无错误的情况!)
- 最后 在 短式变量声明 代码中避免局部变量产生的 变量阴影 shadow
参考来源:
关于 变量阴影shadow 的参考文章:
Variable scopes and shadowing in Go