行分隔符
在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾,因为这些工作都将由 Go 编译器自动完成。
如果你打算将多个语句写在同一行,它们则必须使用 ; 人为区分,但在实际开发中我们并不鼓励这种做法。
以下为两个语句:
或者
不加分号编译错误
注释
注释不会被编译,每一个包应该有相关注释。
单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾。如:
标识符
标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。
Go 语言的空格
Go 语言中变量的声明必须使用空格隔开,如:var age int
语句中适当使用空格能让程序更易阅读。
无空格:
age=age01+age02
在变量与运算符间加入空格,程序看起来更加美观,如:
age = age01 + age02
Go 程序的一般结构
Go 程序是通过 package 来组织的。
只有 package 名称为 main 的包可以包含 main 函数。
一个可执行程序有且仅有一个 main 包。
通过 import 关键字来导入其他非 main 包。
可以通过 import 关键字单个导入:
也可以同时导入多个:
使用 <PackageName>.<FunctionName> 调用:
省略调用(不建议使用):
前面加个点表示省略调用,那么调用该模块里面的函数,可以不用写模块名称了:
行长约定
一行最长不超过80个字符,超过的请使用换行展示,尽量保持格式优雅。
package名字
保持package的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,尽量和标准库不要冲突。
import 规范
如果你在一个文件里面引入了一个package,还是建议采用如下格式:
import (
"fmt"
)
如果你的包引入了三种类型的包,标准库包,程序内部包,第三方包,建议采用如下方式进行组织你的包:
import (
"encoding/json"
"strings"
"myproject/models"
"myproject/controller"
"myproject/utils"
"github.com/astaxie/beego"
"github.com/go-sql-driver/mysql"
)
有顺序的引入包,不同的类型采用空格分离,第一种实标准库,第二是项目包,第三是第三方包。
在项目中不要使用相对路径引入包:
// 这是不好的导入
import “../net”
// 这是正确的做法
import “github.com/repo/proj/src/net”
变量申明
变量名采用驼峰标准,不要使用_
来命名变量名,多个变量申明放在一起
var (
Found bool
count int
)
在函数外部申明必须使用var,不要采用:=
,容易踩到变量的作用域的问题。
自定义类型的string循环问题
如果自定义的类型定义了String方法,那么在打印的时候会产生隐藏的一些bug
type MyInt int
func (m MyInt) String() string {
return fmt.Sprint(m) //BUG:死循环
}
func(m MyInt) String() string {
return fmt.Sprint(int(m)) //这是安全的,因为我们内部进行了类型转换
}
struct规范
struct申明和初始化格式采用多行:
定义如下:
type User struct{
Username string
Email string
}
初始化如下:
u := User{
Username: "astaxie",
Email: "[email protected]",
}
recieved是值类型还是指针类型
到底是采用值类型还是指针类型主要参考如下原则:
func(w Win) Tally(playerPlayer)int //w不会有任何改变
func(w *Win) Tally(playerPlayer)int //w会改变数据
带mutex的struct必须是指针receivers
如果你定义的struct中带有mutex,那么你的receivers必须是指针
常量均需使用全部大写字母组成,并使用下划线分词:
const APP_VER = "1.0"
- 1
如果是枚举类型的常量,需要先创建相应类型:
type Scheme string
const (
HTTP Scheme = "http"
HTTPS Scheme = "https"
)
- 1
- 2
- 3
- 4
- 5
- 6
如果模块的功能较为复杂、常量名称容易混淆的情况下,为了更好地区分枚举类型,可以使用完整的前缀:
type PullRequestStatus int
const (
PULL_REQUEST_STATUS_CONFLICT PullRequestStatus = iota
PULL_REQUEST_STATUS_CHECKING
PULL_REQUEST_STATUS_MERGEABLE
)
导入package的方式和注意事项
逐个导入:
import "fmt" import "os" import "time"
- 1
- 2
- 3
统一导入:
import ( "fmt" "os" "time" )
- 1
- 2
- 3
- 4
- 5
导入包之后,就可以使用格式. 来对包中的函数进行调用
注意: 如果导入了包未被调用,则其中的函数或类型将会报出编译错误
package 别名的使用
当导入第三方包时,包名很可能非常接近或相同,需要使用别名来进行区别和调用如:
import std "fmt" func main() { std.Println("HelloWorld!"); }
- 1
- 2
- 3
- 4
- 5
省略调用如:
import . "fmt" func main() { Println("HelloWorld!"); }
- 1
- 2
- 3
- 4
省略调用的注意事项:不可与别名同时使用且不建议在实际项目中采用
可见性规则
Go语言中,使用大小写来决定该常量、变量、类型、接口、结构或函数是否可以被外部包所调用。
函数名首字母小写即为 private :
函数名首字母大写即为 public :