【笔记】go语言--结构体,方法,包与封装
【笔记】go语言--结构体,方法,包与封装
结构体和方法
面向对象
- go语言仅支持封装,不支持继承和多态
- go语言没有class,只有struct
//结构的定义
type TreeNode struct {
Left,Right *TreeNode
Value int
}
//结构体的创建
root := TreeNode{Value: 3}
root.Left = &TreeNode{}
root.Right = &TreeNode{nil, nil,5}
root.Right.Left = new(TreeNode)
需要注意,不论地址还是结构本身,一律使用.来访问成员
//此为自定义工厂函数,接结构体的创建,go语言可实现返回局部变量
func createTreeNode(value int) *TreeNode {
return &TreeNode{Value: value}
}
root.Left.Right = createTreeNode(2)
使用自定义工厂函数,同时注意返回了局部变量的地址!
既然知道能够返回局部变量的地址,那么结构创建在堆上还是栈上了呢?
看情况,有go语言的编译器和运行环境来决定,如果这个局部变量让编译器认为没有取地址并且返回出去,认为这个局部变量不需要给外面使用,那么就会在栈上分配
但是,如果编译器认为这个局部变量通过取地址并且返回出去给别人用,那么这个局部变量就会在会在堆上分配,堆上分配完后,这个局部变量就会参与垃圾回收,等外部调用这个指针使用完后,这个指针就会被回收。
为结构体定义方法
//调用结构体,值接受者与指针接受者
//为结构体定义方法,显示定义和命名方法接受者
func (node treeNode) print() {
fmt.Print(node.value)
}
//使用指针作为方法接受者,只有使用指针才可以改变结构内容,同时nil指针也可以调用方法
func (node *treeNode) setValue(value int) {
node.value = value
}
func createNode(value int) *treeNode {
return &treeNode{value: value}
}
func main() {
var root treeNode
root = treeNode{value: 3}
root.left = &treeNode{}
root.right = &treeNode{5, nil, nil}
root.right.left = new(treeNode)
root.left.right = createNode(2)
root.right.left.setValue(4)
root.right.left.print()
}
//中序遍历
func ( node *treeNode) traverse() {
if node == nil {
return
}
node.left.traverse( )
node.print( )
node.right.traverse( )
}
值接收者vs指针接收者
- 要改变内容必须使用指针接收者
- 结构过大也考虑使用指针接收者
- —致性:如有指针接收者,最好都是指针接收者
- 值接收者是go语言特有的
- 值/指针接收者均可接收值/指针
包和封装
封装
- 名字一般使用CamelCase
- 首字母大写:public,代表全局可见,即公有方法
- 首字母小写:private,代表包内可见,即私有方法
包
- 每个目录一个包,包名可以和目录名不同名,但是建议同名
- main包中包含可执行入口
- 为结构定义的方法必须放在同一个包内
- 可以是不同的文件
问题:如果包是别人写的,我们如何调用?
如何扩充系统类型或者别人的类型
- 定义别名:最简单,别名是使用type 声明一个别名,然后给自己别名定义新的方法
- 使用组合:最常用,组合指的是用自己的type类型包装一个原来的类型
- 使用内嵌:需要省下许多代码,内嵌方式,在结构体中省略字段名,只包含一个指针类型名,则该类型的各个方法会被结构体继承,同时还可以重载原来类型的方法,也就是重新定义同名方法。类似于继承的关系
您能读到这儿,我呢是发自真心的感谢您,若要转载,还望请您带上链接