一、包和封装
采用驼峰命名的方式,首字母大写表示public,小写表示private,公开和私有是相对于package包来说的,每个目录下只能有一个包,main包包含可执行程序入口。为结构定义的方法必须放在同一个包内,但是可以是不同的文件。
// GOPATH/goSource/main.go
package main
// 添加GOPATH/GOROOT之后匹配包文件夹
// ./XXX 相对路径导入,不建议使用
import(
"goSource/node"
)
func main() {
// 通过前缀包名调用
root := &tree.Node {1, nil, nil}
.......
root.Traverse()
}
// 包名可以跟文件夹名称不同
// GOPATH/goSource/node/tree.go
package tree
type Node struct{
Value int
Left, Right *Node
}
....
// 同一目录下只能有一个包名
// GOPATH/goSource/node/traverse.go
package tree
func (node *Node) Traverse() {
....
}
二、扩展已有类型
package main
import (
...
)
// 定义一个指向原struct的指针
type myTree struct {
node *tree.Node
}
// 通过指针扩展原struct,实现后序遍历
func (tree *myTree) postOrder() {
if tree == nil || tree.node == nil {
return
}
// myTree{tree.node.Left}.postOrder() 会报错
left := myTree{tree.node.Left}
right := myTree{tree.node.Right}
left.postOrder()
right.postOrder()
tree.node.PrintValue()
}
func main() {
...
myRoot := &myTree{root}
myRoot.postOrder()
}
三、接口
查看接口变量
1、interface{}表示任何类型
2、type switch
3、type assertion
package main
import (
"fmt"
"goSource/interface/fake"
"goSource/interface/real"
)
type Ha interface {
Reply() string
}
func say(r Ha) string {
return r.Reply()
}
// type switch
func inspect(h Ha) {
switch a := h.(type) {
case *fake.Fake:
fmt.Printf("Type: %T, Fake Word: %v", a, a.Word)
case *real.Real:
fmt.Printf("Type: %T, Real Num: %v", a, a.Num)
default:
fmt.Println(a)
}
fmt.Println()
}
func main() {
var r Ha
fakeRetriever := fake.Fake{Word: "1"}
r = &fakeRetriever
// Hello Word
fmt.Println(say(r))
// Type: *fake.Fake, Fake Word: 1
inspect(r)
realRetriever := real.Real{}
r = &realRetriever
// OK
fmt.Println(say(r))
// Type: *real.Real, Real Num: 1
inspect(r)
// Type: *real.Real, Real Num: 2
fmt.Println(say(r))
inspect(r)
// type assertion
// not Real Type
if i, err := r.(*fake.Fake); err {
fmt.Println("Fake Word: ", i.Word)
} else {
fmt.Println("not Real Type")
}
// Real Num: 2
if i, err := r.(*real.Real); err {
fmt.Println("Real Num: ", i.Num)
} else {
fmt.Println("not Real Type")
}
}
package fake
type Fake struct {
Word string
}
func (f *Fake) Reply() string {
rs := ""
switch f.Word {
case "1":
rs = "Hello Word"
case "2":
rs = "GO!GO!GO!"
default:
rs = "Emmmmmm..."
}
return rs
}
package real
type Real struct {
Num int
}
func (r *Real) Reply() string {
r.Num += 1
return "OK"
}