1)go中的struct与C中的struct非常相似,并且go没有class
2)使用type <Name> struct {}定义结构,名称遵循可见性规则
3)支持指向自身的指针类型成员
4)支持匿名结构,可用作成员或定义成员变量
5)匿名结构也可以用于map的值
6)可以使用字母值对结构体进行初始化
7)允许直接通过指针类读写结构成员
8)相同类型的成员可以进行直接拷贝赋值
9)支持==与!=比较运算符,但不支持>或<
10)支持匿名字段,本质上是定义了以某个类型名为名称的字段
11)嵌入结构作为匿名字段看起来像继承,但不是继承
12)可以使用匿名字段指针
13)go语言仅支持封装,不支持继承和多态
14)go没有class,只有struct
实例,创建一棵树的数据结构
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
func main() {
var root treeNode
//初始为空
fmt.Println(root)
//几种不同的创建树的方法
root = treeNode{value: 3}
root.left = &treeNode{}
root.right = &treeNode{5, nil, nil}
root.right.left = new(treeNode)
nodes := []treeNode{
{value: 3},
{},
{6, nil, &root},
}
//打印查看创建的结构
fmt.Println(nodes)
}
输出:
API server listening at: 127.0.0.1:36962
{0 <nil> <nil>}
[{3 <nil> <nil>} {0 <nil> <nil>} {6 <nil> 0xc0420503e0}]
2.工厂函数
//go语言结构中没有构造函数,但是可以创建一个工厂函数来负责创建结构
func createNode(value int) *treeNode {
//go语言中返回一个局部变量的地址是可以给外部使用的
return &treeNode{value: value}
}
root.left = createNode(100)
实例:
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
func (node treeNode) print() {
fmt.Println(node.value)
}
//go语言结构中没有构造函数,但是可以创建一个工厂函数来负责创建结构
func createNode(value int) *treeNode {
//go语言中返回一个局部变量的地址是可以给外部使用的
return &treeNode{value: value}
}
func (node treeNode) setVale(value int) {
node.value = value
node.print()
}
func (node *treeNode) setValePtr(value int) {
node.value = value
node.print()
}
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.print() //这里有个接收者,root相当于参数,值传递
root.right.print()
root.right.left.print()
root.left.right.print()
fmt.Println()
//检验接收者值传递,传入一个值在局部打印,之后在主函数打印观察是否被修改
fmt.Println("#####################")
root.right.left.print()
root.right.left.setVale(100)
root.right.left.print()
//地址传入测试,这样发现内容会被修改
fmt.Println("#####################")
root.right.left.print()
root.right.left.setValePtr(100)
root.right.left.print()
}
输出:
5
0
2
#####################
0
100
0
#####################
0
100
100
上述发现,只有指针传入的时候内容才会被修改,其他值专递情况不会修改内容,这里可以总结为:
1)只有使用指针才可以改变结构内容
3)nil指针也可以调用方法
实例:遍历一棵树
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
func (node treeNode) print() {
fmt.Printf("%d ", node.value)
}
//go语言结构中没有构造函数,但是可以创建一个工厂函数来负责创建结构
func createNode(value int) *treeNode {
//go语言中返回一个局部变量的地址是可以给外部使用的
return &treeNode{value: value}
}
//中序遍历
func (node *treeNode) traverse() {
if node == nil {
return
}
node.left.traverse()
node.print()
node.right.traverse()
}
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.traverse()
}
输出:
API server listening at: 127.0.0.1:33038
0 2 3 0 5
接收者总结,指针接收者和值接收者应该如何使用
1)要改变内容必须使用指针接收者
2)结构过大也考虑使用指针接收者
3)一致性,如果有指针接收者最好使用指针接收者