针对包
每个目录一个包
main包含可执行入口
为结构定义的方法必须放在同一个包内
结构的方法可以是不同的文件
名字一般使用CamelCase,驼峰命名
首字母大写,表示公共
首字母小写,表示私有
一个结构体
package tree
import "fmt"
/**
Go语言仅支持封装, 不支持继承和多态
没有 class, 只有 struct(结构)
没有构造方法, 如果需要可以定义工厂函数
值接收者VS指针接收者
结构体修改内容用指针接收者,不修改内容用值接收者
结构体很大那么建议使用接收者,因为值传递代表着值拷贝
*/
// 定义一个结构体
type TreeNode struct {
// 整型
Value int
// TreeNode类型,但是必须是指针
Left, Right *TreeNode
}
// 给 结构定义 方法
// (node TreeNode) 称为 接收者, 表示这个方法是给 TreeNode这个结构用的
// (node TreeNode) 这个地方是值传递,不是引用传递,除非指针 (node *TreeNode)
// root 表示 TreeNode, 然后调用 root.print()
func (node TreeNode) print() {
fmt.Println(node)
}
func (node *TreeNode) setValue(val int) {
if node == nil {
fmt.Println("nil 不能设置值!")
return
}
node.Value = val
}
// 遍历
func (node *TreeNode) trease() {
if node == nil {
return
}
// 为什么此处的调用 left 或者 right 不用判断 是否为 nil?
/**
因为nil也可以作为参数传递, 也就是调用了 left 后,此时是个 nil,nil也是一个值,
只是我的值为nil而已,此时的nil也可以代表我TreeNode本身,nil在Go预压里面是有意义的,
这个时候在调用 trease() 方法时在去把 TreeNode 传递过去!
*/
node.Left.trease()
node.Right.trease()
}
// 工厂函数,
// 返回的是局部变量的地址
func createTreeNode(val int) *TreeNode {
return &TreeNode{Value: val}
}
func main() {
// 声明一个 TreeNode 的类型的变量
// 不会分配内存
var root TreeNode
// 创建一个 TreeNode, 并且赋值给 root
// TreeNode{value: 3} 表示创建的时候给 value 字段赋一个值
root = TreeNode{Value: 3}
// 给 TreeNode 里面的 left 字段赋值,并且是一个指针
root.Left = &TreeNode{}
root.Right = &TreeNode{4, nil, nil}
// make() 只用于映射、切片和程道,不返回指针。要明确的得到指针用 new() 分配
// new() 创建的同时,可以得到指针
// 表示把 root里面 right 里面的 left 赋值
root.Right.Left = new(TreeNode)
}
扩展上面的结构体
package tree
// 扩展 结构体
type MyTree struct {
// 引入其他的结构体
node *TreeNode
// 这里写入其他的结构体或者属性,达到组合的目的
}
网友评论