1.结构体和方法

  • go 语言仅支持封装,不支持继承和多态
  • go语言没有 class,只有 struct

1.1 结构的创建

root.left = &treeNode{}
root.right = &treeNode{5, nil, nil}
root.right.left = new(treeNode)
  • 不论地址还是结构本身,一律使用.来访问成员
func createNode(value int) *treeNode {
	return &treeNode{value: value}
}

root.left.right = createNode(2) //使用自定义工厂函数

注意上述代码中,createNode返回了局部变量的地址, 这种方式在C/C++中是会出错的,但是因为golang的内存管理不需要用户关心,所以显得非常的简便。

1.2 结构创建在堆上还是栈上?

作为golang的用户,我们其实不用考虑它在哪里,因为Golang的编译器对代码进行分析,然后决定将结构创建在哪里。下面就是Golang官方FAQ:

How do I know whether a variable is allocated on the heap or the stack? From a correctness standpoint, you don't need to know. Each variable in Go exists as long as there are references to it. The storage location chosen by the implementation is irrelevant to the semantics of the language. The storage location does have an effect on writing efficient programs. When possible, the Go compilers will allocate variables that are local to a function in that function's stack frame. However, if the compiler cannot prove that the variable is not referenced after the function returns, then the compiler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors. Also, if a local variable is very large, it might make more sense to store it on the heap rather than the stack. In the current compilers, if a variable has its address taken, that variable is a candidate for allocation on the heap. However, a basic escape analysis recognizes some cases when such variables will not live past the return from the function and can reside on the stack.

1.3 为结构定义方法

func (node treeNode) print(){
	fmt.Print(node.value, " ")
}
  • 显示定义和命名方法接收者
  • 使用指针作为方法接收者, 只有使用指针才可以改变结构内容
func (node *treeNode) setValue(value int) {
	node.value = value
}
  • nil 指针也可以调用方法!

1.4 值接收者 vs 指针接收者

  • 要改变内容必须使用指针接收者
  • 结构过大也考虑使用指针接收者(性能考虑)
  • 一致性:如有指针接收者,最好都是指针接收者
  • 值接收者是golang特有
  • 值/指针接收者均可接收值/指针

2.包和封装

2.1 封装

  • 名字一般使用 CamelCase
  • 首字母大写:public
  • 首字母小写:private

2.2 包

  • 每个目录一个包
  • main 包包含可执行入口
  • 为结构定义的方法必须放在同一包内
  • 可以是不同文件

2.3 golang中如何扩充系统类型或者别人的类型

  • 定义别名
  • 使用组合

3. GOPATH以及目录结构

3.1 GOPATH 环境变量

  • Unix, Linux默认在~/go, Windows默认在%USERPROFILE%\go
  • 官方推荐:所有项目和第三方库都放在同一个 GOPATH
  • 也可以将每个项目放在不同的 GOPATH
  • 以 Mac 为例(~/.bash_profile)
export GOPATH=/Users/alan/go
export PATH="$GOPATH/bin:$PATH"

3.2 go get 获取第三方库

  • go get 命令演示
  • 使用 gopm 来获取无法下载的包(如官网 golang.org 下的包)
go get github.com/gpmgo/gopm
gopm -g -v -u golang.org/x/tools/cmd/goimports # 未 build 执行下面的命令 build 到 bin(PATH) 目录
go install golang.org/x/tools/cmd/goimports
  • go build 来编译
  • go install 产生 pkg 文件和可执行文件
  • go run 直接编译运行

3.3 GOPATH下目录结构

src
    git repository 1
    git repository 2
pkg
    git repository 1
    git repository 2
bin
    执行文件1, 2, 3…