1、结构和方法:
type treeNode struct{
value int
left,right *treeNode
}
func (root *treeNode) traverse(){
if root == nil {
return
}
root.left.traverse()
fmt.Print(root.Value)
root.right.traverse()
}
//go语言仅支持封装,不支持继承和多态
//go没有class,只有struct
//对象创建
var root treeNode
root = treeNode{value : 3}
root.left = &treeNode{} //指针也可以用.
root.right = &treeNode{5,nil,nil}
root.right.left = new(treeNode) //new是内建函数
//go语言没有构造函数的说法,用工厂方法
func createNode(value int) *treeNode{
return &treeNode{value:value} /go语言返回局部变量的地址,也不会出错,C++会报错
}
使用自定义工厂函数
注意返回了局部变量的地址!
结构创建在堆上还是栈上?
C++局部变量创建在栈上,函数一退出就被自动销毁,传出去就需要在堆上创建,在堆上创建需要手动释放,其他语言new也是分配在堆上,在堆上才有垃圾回收机制
go语言不需要知道结构创建在堆上还是栈上,有垃圾回收机制
go语言方法定义:
//值传递
func (node treeNode) print(){
fmt.Print(node.value)
}
func (node *treeNode) print(){
fmt.Print(node.value)
}
//指针接收者:调用的时候,不用传&,正常调用root.print()即可
//只有使用指针才可以改变结构内容
//nil指针也可以调用方法!
func (node *treeNode) setValue(value int){
if node == nil{ //看使用场景判断是否为nil
fmt.Println("hhh")
return
}
node,value = value
}
值接收者VS指针接收者:
要改变内容必须使用指针接收者
结构过大也考虑使用指针接收者一致性:如有指针接收者,最好都是指针接收者
值接收者是go语言特有,其他语言指针接收者比如this,self
值/指针接收者均可接收值/指针
2、包和封装:
名字一般使用CamelCase,每个单词首字母大写(针对包来说)
首字母大写:public
首字母小写:private
每个目录一个包
main包包含可执行入口
为结构定义的方法必须放在同一个包内
可以是不同的文件
struct结构的名字不需要重复package的名字,即包名package为tree包,struct"TreeNode"建议写成"Node"
3、扩展已有类型:
包:
为结构定义的方法必须放在同一个包内
可以是不同文件
go语言如何扩充系统类型或别人的类型?
1.定义别名
2.使用组合
//已有中序遍历:
func (root *treeNode) traverse(){
if root == nil {
return
}
root.left.traverse()
fmt.Print(root.Value)
root.right.traverse()
}
//现在写后序遍历:
type myTreeNode struct{
node *tree.Node //组合的方式
}
func (myNode *myTreeNode) postOrder(){
if myNode ==nil || myNode.node == nil{
return
}
//myTreeNode{myNode.node.Left}.postOrder() //调用必须是地址
//myTreeNode{myNode.node.Right}.postOrder()
left := myTreeNode{myNode.node.Left}
right := myTreeNode{myNode.node.Right}
left.postOrder()
right.
myNode.node.Print()
}
//使用别名
tyep Queue []int
func (q *Queue) Push(v int){
*q = append(*q,v)
}
func (q *Queue) Pop() int{
head := (*q)[0]
*q = (*q)[1:]
return head
}
func (q *Queue) IsEmpty() bool{
return len(*q) == 0
}
func main(){
q := queue.Queue{1}
q.Push(2) //指针接收者,会改变q的值
q.Push(3)
q.IsEmpty()
}
//q不是同一个slice
4、GOPATH以及目录结构:
go get获取第三方库
如果由于网络无法获取,使用gopm来获取无法下载的包
go get -v github.com/gpmgo/gopm //-v可以多输出一点信息
gopm get -g -v -u golang.org/x/tools/cmd/goimports
//go build golang.org/x/tools/cmd/goimports
go install golang.org/x/tools/cmd/goimports
go build来编译
go install产生pkg文件和可执行文件
go run 直接编译运行
go install ./... 安装这个目录下所有文件