Go入门-Effective-Go

原文链接

链接

1. Effective GO

https://github.com/bingohuang/effective-go-zh-en

2. 格式化

在最开始学习GO的时候,写了几篇Blog,发现代码里面的对齐都是TAB,这让我很困惑,知道现在才知道,GO语言,默认使用TAB进行对齐。

当然GO还有自己的空格规则x<<8 + y<<16,向这份代码,我们根据空格就能知道计算的优先级了。

3. 注释

3.1. 包注释

Go语言要求package语句前加上注释,来介绍整个包,如果package包含多个文件,则只需要在其中一个文件中标注即可。

/*
Package regexp implements a simple library for regular expressions.

The syntax of the regular expressions accepted is:

    regexp:
        concatenation { '|' concatenation }
    concatenation:
        { closure }
    closure:
        term [ '*' | '+' | '?' ]
    term:
        '^'
        '$'
        '.'
        character
        '[' [ '^' ] character-ranges ']'
        '(' regexp ')'
*/
package regexp

需要注意的是,注释不是JavaDoc模式的,下面这种就不对了

/**
 *
 *  main
 *
 */
package main

3.2. 导出注释

在程序中,每个可导出(首字母大写)的名称都应该有文档注释。使用行注释的形式,行注释的第一行要以被导出的内容开头,并总结整个注释,如下,第一行以Compile开头

// Compile parses a regular expression and returns, if successful, a Regexp
// object that can be used to match against text.
func Compile(str string) (regexp *Regexp, err error) {

4. 命名

Go语言默认使用驼峰命名,请不要使用下划线

4.1. 包

包名用小写,不要带下划线,

不要使用import .的语句,很容易冲突

4.2. 字段Getter Setter

Getter方法不需要Get这个前缀,如下

obj.Owner()
obj.SetOwner(user)

4.3. 接口名

只包含一个方法的接口命名以er结尾。

5. 分号

在Go中,行末,不要加入分号。

分号其实是由词法分析器自动增加的。

6. 控制流

6.1. 变量重新声明

下面的这份代码,注意到其中的err申明了两次,上面这个err声明了两次,但是这并不是错误,编译器会帮忙解决这个问题,实际上err第二次只是被重新赋值而已。

package main

import (
    "fmt"
    "os"
)

func main() {
    f1, err := os.Open("file")
    fmt.Println(f1,err)

    f2, err := os.Open("file2")
    fmt.Println(f2,err)
}

当然这样的技巧只能在特殊情况才能生效

  • 本次声明与已声明的 v 处于同一作用域中(若 v 已在外层作用域中声明过,则此次声明会创建一个新的变量 §),
  • 在初始化中与其类型相应的值才能赋予 v,且
  • 在此次声明中至少另有一个变量是新声明的。

7. 函数

7.1. 可命名结果形参

在Go中,可以在函数上声明返回值变量,在返回的时候只需要一个return即可

package main

import (
    "fmt"
)

func f() (value int, info string) {
    value=1
    info="hello"
    return
}

func main() {
    fmt.Println(f())
}

7.2. Defer

defer是一种推迟执行的语法,被该关键词修饰的语句会在函数返回的时候执行

package main

import "fmt"

func f1(str string) {
    fmt.Println(str)
}

func main() {
    f1("hi1")
    defer f1("hi5")
    defer f1("hi4")
    defer f1("hi3")
    f1("hi2")
}
// 输出:
//hi1
//hi2
//hi3
//hi4
//hi5
//

8. 初始化

主要是init函数,一个文件可以有多个init函数,他们都会被调用,init函数在包的全局变量初始化以后执行

注意到下面这个代码,先输出abc, 与init的位置无关,init在全局变量之后执行

package main

import "fmt"

func p(str string) (int)  {
    fmt.Println(str)
    return 1;
}

var a = p("a")

func init() {
    p("init1")
}

var b = p("b")

func init() {
    p("init2")
}

var c = p("c")

func main() {
    p("main")
}
/*
输出:
a
b
c
init1
init2
 */
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值