Go文件布局

  • General Documentation: 对整个模块和功能的完整描述注释,写在文件头部。
  • package:当前package定义
  • import:包含的头文件
  • const:常量
  • var: 全局变量定义
  • Typedefs: 类型定义
  • 成员函数定义
  • functions:函数实现
/*
 this is description
*/

package service

import (
    "fmt"
    "time" 
)

const (
    version = "1.0.0"
)


var errTooLarge = errors.New("http: request too large")


type Module interface {
    Init(cfg Config, cbs *Callbacks) error
}

type Modules struct {
    name string
}

func (b *Modules) foo(){
    // ...
}

func foo() {
    //... 
}

函数规则:

  1. 对于“逻辑判断型”的函数,返回值的意义代表“真”或“假”,返回值类型定义为bool 
  2. 对于“操作型”的函数,返回值的意义代表“成功”或“失败”,返回值类型定义为error

  3. 对于“获取数据型”的函数,返回值的意义代表“有数据”或“无数据/获取数据失败”,返回值类型定义为(data, error)

    • 正常情况下,返回为:(data, nil)
    • 异常情况下,返回为:(data, error)
  4. 函数返回值小于等于3个,大于3个时必须通过struct进行包装

函数参数不建议超过3个,大于3个时建议通过struct进行包装

type student struct {
    name     string
    email    string
    id       int
    class    string
}

// bool
func isWhiteCat() bool {
    // ... 
}

// error
func deleteData() error {
    // ... 
}

//
func getData() (data, error) {
    // ... 
}
  1. error string尽量使用小写字母,并且结尾不带标点符号
  2. 除非出现不可恢复的程序错误,不要使用panic,用多返回值和error

  3. 如果临界区内的逻辑较复杂、无法完全避免panic的发生,则要求适用defer来调用Unlock,即使在临界区过程中发生了panic, 也会在函数退出时调用Unlock释放锁

// GOOD:
func doDemo() {
    lock.Lock()
    defer lock.Unlock()
    // step1
}


// BAD:
func doDemo() {
    lock.Lock()
    // step1
    lock.Unlock()
}

-------------------------------------------------------------

// BAD:(造成临界区扩大)
func doDemo() {
    lock.Lock()
    defer lock.Unlock()
    
    // step1:

    // step2: 
}

// GOOD:
func doDemo() {
    func() {  // 使用单独的匿名函数,有自己专属的访问临界区
        lock.Lock()
        defer lock.Unlock()
        
        // step1: 
    }()
    
    // step2: 
}

  • 除非特殊原因,不建议使用unsafe package
    • 比如进行指针和数值uintptr之间转换就是一个特殊原因

你可能感兴趣的:(Golang,golang)