Golang Code Specification

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Golang Code Specification

Reference https://golang.org/doc/effective_go.html

Project directory Structure specification

packpack.sh 自动打包的脚本,生成类似xxxx.20170713_14:45:35.tar.gz的文件,放在pack文件下└── src 该项目的源代码    ├── main 项目主函数    ├── model 项目代码    ├── research 在实现该项目中探究的一些程序    └── vendor 存放go的库        ├── github.com/xxx 第三方库        └── xxx.com/obc 公司内部的公共库

The directory structure of the project is as concise and clear as possible

File name naming specification

In lowercase, as far as possible to see the name of meaning, see the file name can know the approximate content of the document, for the source code files, file name to represent a module implementation of the function.

Naming conventions

Package Name

Package name in lowercase, use short name, try not to conflict with standard library

Interface Name

The interface name of a single function is suffixed with "er", such as Reader,writer

The implementation of the interface removes the "ER"

interface {        Read(p []byteint, err error)}

Two functions Interface name synthesis two function names

interface {    Write([]byte) (int, error)    Flush() error}

Interface names of more than three functions, similar to struct names

interface {    Start([]byte)     error    Recover()}

Variable

Global variables: Using the Hump naming method, only the global variables within the package, the outer reference needs to write the interface, provide the call local variables: Camel, lowercase letter Start

Constant

Constant: Uppercase with underscore

Import specification

Import in the case of multiple lines, Goimports will automatically help you format, in a file to introduce a package, it is recommended to use the following format:

import (    "fmt")

If your package introduces three types of packages, standard library packages, program internals, and third-party packages, it is recommended that you organize your packages in the following ways:

import (    "encoding/json"    "strings"    "myproject/models"    "myproject/controller"    "git.obc.im/obc/utils"    "git.obc.im/dep/beego"    "git.obc.im/dep/mysql")  

Do not use relative paths to introduce packages in your project:

It's not good to import

import “../net”

That's the right thing to do.

import “xxxx.com/proj/net”

Name of function

Function name using hump naming method, try not to use underline

Error handling

Error is returned as the value of the function, and error must be processed as soon as possible
Processing with a separate error stream
Do not use this method

    ifnil {        // error handling    else {        // normal code    }

Instead, use the following method

    ifnil {        // error handling        return// or continue, etc.    }    // normal code

If the return value needs to be initialized, use the following method

x, err := f()ifnil {    // error handling    return}// use x

Panic

Disabling panic in logical processing
In the main package only if it is not possible to run the case of panic, such as the file can not be opened, the database can not be connected to cause the program does not work properly, but for the other package external interface can not be panic, can only be used within the packet. It is recommended that you use log in the main package. Fatal to log errors so that the program can be terminated by log.

Recover

Recover is used to capture runtime anomalies, prohibit misuse of recover, and try not to use Recover,recover in the development testing phase where you think there will be unexpected anomalies.

func server(workChan <-chan *Work) {    for work := range workChan {        go safelyDo(work)    }}func safelyDo(work *Work) {    defer func() {        if err := recover(); err != nil {            log.Println("work failed:", err)        }    }()    // do 函数可能会有不可预期的异常    do(work)}

Defer

Defer is performed before the function return, it is good for some resources to be recycled defer, but it is also forbidden to misuse defer,defer to consume performance, so frequently called functions do not use defer as much as possible.

//Contents Returns the file ' s Contents as a string.func Contents(filename string) (string, error) {F, err: = OS. Open (filename)ifErr! = Nil {return "", err} defer F.close ()//F.close'll run when we ' re finished.    varresult []byteBUF: = make ([]byte, -) for{N, err: = F.read (buf[0:]) result = Append (result, buf[0: n] ...)//Append is discussed later.        ifErr! = Nil {ifErr = = Io. EOF { Break}return ""Err//F'll be closed if we return here.}    }return string(result), nil//F'll be closed if we return here.}

Control structure

If

If the initialization statement is accepted, the Convention establishes the local variable as follows

if err := file.Chmod(0664err != nil {    return err}

For

Creating local variables with short declarations

0for010; i++ {    sum += i}

Range

If you only need the first item (key), discard the second one:

for key := range m {    if key.expired() {        delete(m, key)    }}

If only the second item is required, place the first item as an underscore

0forvalue := range array {    value}

Return

Return as soon as possible: Once an error occurs, go back immediately

f, err := os.Open(name)ifnil {    return err}d, err := f.Stat()ifnil {    f.Close()    return err}codeUsing(f, d)

Receiver of the method

The name generally takes the first letter of Strcut and is lowercase, not this,me or self

    type T struct{}     func (p *T)Get(){}

If the recipient is Map,slice or Chan, do not pass the pointer

 //map  package main< Span class= "Hljs-title" >import   ("FMT")  type MP  [string ]string  func   (M MP)  set   (k, v string )   {M[k] = v} func main   ()   {m: = Make (MP) M.set ( "K" , ) fmt. Println (M)}  
//Channelpackage mainimport (    "fmt")type ch chan interfaceinterface{}) {    interface{} {    return <-c}func main() {    1)    c.Push("i")    fmt.Println(c.Pop())}

If you need to modify the slice, re-assign the value by returning the value

//Slicepackage mainimport (    "fmt")type slice []bytefunc main() {    0)    s = s.addOne(42)    byte) []byte {    return append(s, b)}

If the recipient contains sync. Mutex or a struct similar to a synchronization field, you must use pointer passing to avoid copying

package mainimport (    "sync")type T struct {    lock() {    t.m.Lock()}/*Wrong !!!func (t T) lock() {    t.m.Lock()}*/func main() {    new(T)    t.lock()}

If the recipient is a large struct or array, it is more efficient to pass the pointer.

 package mainimport   ( "FMT" )  type T struct   {data [1024 ]byte }func (t *t) Get ( ) byte  {return  t.data[ 0 ]} func main   ()   {t: = new  (t) fmt. Println (T.get ())}  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.