Skip to content

Latest commit

 

History

History
135 lines (110 loc) · 4.43 KB

coding_guidelines.md

File metadata and controls

135 lines (110 loc) · 4.43 KB

代码指导

基本约束

  • 所有应用的 main 包需要有 APP_VER 常量表示版本,格式为 X.Y.Z.Date [Status],例如:0.7.6.1112 Beta

  • 单独的库需要有函数 Version 返回库版本号的字符串,格式为 X.Y.Z[.Date]

  • 当单行代码超过 80 个字符时,就要考虑分行。分行的规则是以参数为单位将从较长的参数开始换行,以此类推直到每行长度合适:

     So(z.ExtractTo(
     	path.Join(os.TempDir(), "testdata/test2"),
     	"dir/", "dir/bar", "readonly"), ShouldBeNil)
  • 当单行声明语句超过 80 个字符时,就要考虑分行。分行的规则是将参数按类型分组,紧接着的声明语句的是一个空行,以便和函数体区别:

     // NewNode initializes and returns a new Node representation.
     func NewNode(
     	importPath, downloadUrl string,
     	tp RevisionType, val string,
     	isGetDeps bool) *Node {
    
     	n := &Node{
     		Pkg: Pkg{
     			ImportPath: importPath,
     			RootPath:   GetRootPath(importPath),
     			Type:       tp,
     			Value:      val,
     		},
     		DownloadURL: downloadUrl,
     		IsGetDeps:   isGetDeps,
     	}
     	n.InstallPath = path.Join(setting.InstallRepoPath, n.RootPath) + n.ValSuffix()
     	return n
     }
  • 分组声明一般需要按照功能来区分,而不是将所有类型都分在一组:

     const (
     	// Default section name.
     	DEFAULT_SECTION = "DEFAULT"
     	// Maximum allowed depth when recursively substituing variable names.
     	_DEPTH_VALUES = 200
     )
    
     type ParseError int
    
     const (
     	ERR_SECTION_NOT_FOUND ParseError = iota + 1
     	ERR_KEY_NOT_FOUND
     	ERR_BLANK_SECTION_NAME
     	ERR_COULD_NOT_PARSE
     )
  • 当一个源文件中存在多个相对独立的部分时,为方便区分,需使用由 ASCII Generator 提供的句型字符标注(示例:Comment):

     // _________                                       __
     // \_   ___ \  ____   _____   _____   ____   _____/  |_
     // /    \  \/ /  _ \ /     \ /     \_/ __ \ /    \   __\
     // \     \___(  <_> )  Y Y  \  Y Y  \  ___/|   |  \  |
     //  \______  /\____/|__|_|  /__|_|  /\___  >___|  /__|
     //         \/             \/      \/     \/     \/
  • 函数或方法的顺序一般需要按照依赖关系由浅入深由上至下排序,即最底层的函数出现在最前面。例如,下方的代码,函数 ExecCmdDirBytes 属于最底层的函数,它被 ExecCmdDir 函数调用,而 ExecCmdDir 又被 ExecCmd 调用:

     // ExecCmdDirBytes executes system command in given directory
     // and return stdout, stderr in bytes type, along with possible error.
     func ExecCmdDirBytes(dir, cmdName string, args ...string) ([]byte, []byte, error) {
     	...
     }
    
     // ExecCmdDir executes system command in given directory
     // and return stdout, stderr in string type, along with possible error.
     func ExecCmdDir(dir, cmdName string, args ...string) (string, string, error) {
     	bufOut, bufErr, err := ExecCmdDirBytes(dir, cmdName, args...)
     	return string(bufOut), string(bufErr), err
     }
    
     // ExecCmd executes system command
     // and return stdout, stderr in string type, along with possible error.
     func ExecCmd(cmdName string, args ...string) (string, string, error) {
     	return ExecCmdDir("", cmdName, args...)
     }
  • 结构附带的方法应置于结构定义之后,按照所对应操作的字段顺序摆放方法:

     type Webhook struct { ... }
     func (w *Webhook) GetEvent() { ... }
     func (w *Webhook) SaveEvent() error { ... }
     func (w *Webhook) HasPushEvent() bool { ... }
  • 如果一个结构拥有对应操作函数,大体上按照 CRUD 的顺序放置结构定义之后:

     func CreateWebhook(w *Webhook) error { ... }
     func GetWebhookById(hookId int64) (*Webhook, error) { ... }
     func UpdateWebhook(w *Webhook) error { ... }
     func DeleteWebhook(hookId int64) error { ... }
  • 如果一个结构拥有以 HasIsCanAllow 开头的函数或方法,则应将它们至于所有其它函数及方法之前;这些函数或方法以 HasIsCanAllow 的顺序排序。

  • 变量的定义要放置在相关函数之前:

     var CmdDump = cli.Command{
     	Name:  "dump",
     	...
     	Action: runDump,
     	Flags:  []cli.Flag{},
     }
    
     func runDump(*cli.Context) { ...
  • 在初始化结构时,尽可能使用一一对应方式:

     AddHookTask(&HookTask{
     	Type:        HTT_WEBHOOK,
     	Url:         w.Url,
     	Payload:     p,
     	ContentType: w.ContentType,
     	IsSsl:       w.IsSsl,
     })