Go语言函数和最佳实践demo

一个简单的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中,被注释的部分代码为不优雅不易于阅读的,其中大部分注意点都在注释中写清楚了,这里简单总结:

  1. 关于函数返回参数: 能不超过两个是最好的,最多包含三个。
  2. 关于 if err != nil 是提行写还是一行写完,主要在于下文是否要引用变量。如果能在局部域中结束的变量就一行搞定。
  3. 在函数末尾不要为了省略一两行代码就直接return含糊不清,未尽处理的error,不易于阅读理解。(直接清晰的 return nil 能够让读代码的人看见你是在讨论无错误的情况!)
  4. 最后 在 短式变量声明 代码中避免局部变量产生的 变量阴影 shadow

参考来源:

Go Syntax - Function Idioms

关于 变量阴影shadow 的参考文章:

Golang Variable Shadowing

Shadowed variables

Variable scopes and shadowing in Go