特点:
- 用来自定义复杂数据结构
- struct里面可以包含多个字段(属性)
- struct类型可以定义方法,注意和函数的区别
- struct是值类型
- struct类型可以嵌套
- go没有class,只有struct
定义
struct声明:
type 标识符 struct{
field1 type
field2 type
}
example:
type Student struct{
Name string
Age int
Score int
}
struct中字段访问
package main import ( "fmt" ) type Student struct { Name string Age int Score int } func main() { var stu Student stu.Name = "alex" stu.Age = 20 stu.Score = 100 var stu1 = Student{ Name: "sb", Age: 18, } fmt.Println(stu1) fmt.Printf("name=%s age=%d score=%d", stu.Name, stu.Age, stu.Score) }
struct定义的三种形式
- var stu Student
- var stu *Student = new(Student)
- var stu *Student = &Student{}
链表定义
type Student struct{
Name string
Next *Student
}
每个节点包含下一节点的地址,这样把所有的节点串起来了,通常把链表中的第一节点叫做链表头
尾部插入
package main import ( "fmt" "math/rand" ) type Student struct { Name string Age int Score float32 next *Student } func trans(p *Student) { for p != nil { fmt.Println(*p) p = p.next } } func insertTail(p *Student) { var tail = p for i := 0; i < 10; i++ { stu := Student{ Name: fmt.Sprintf("stu%d", i), Age: rand.Intn(100), Score: rand.Float32() * 100, } tail.next = &stu tail = &stu } } func main() { var head *Student = new(Student) head.Name = "alex" head.Age = 18 head.Score = 100 insertTail(head) trans(head) }
头部插入
package main import ( "fmt" "math/rand" ) type Student struct { Name string Age int Score float32 next *Student } func trans(p *Student) { for p != nil { fmt.Println(*p) p = p.next } } func main() { var head *Student = new(Student) head.Name = "alex" head.Age = 18 head.Score = 100 for i := 0; i < 10; i++ { stu := Student{ Name: fmt.Sprintf("stu%d", i), Age: rand.Intn(100), Score: rand.Float32() * 100, } stu.next = head head = &stu } trans(head) }
链表插入删除
package main import ( "fmt" "math/rand" ) type Student struct { Name string Age int Score float32 next *Student } func trans(p *Student) { for p != nil { fmt.Println(*p) p = p.next } } func addNode(p *Student, newNode *Student) { for p != nil { if p.Name == "stu9" { newNode.next = p.next p.next = newNode break } p = p.next } } func delNode(p *Student) { prev := p for p != nil { if p.Name == "stu6" { prev.next = p.next break } prev = p p = p.next } } func main() { var head *Student = new(Student) head.Name = "alex" head.Age = 18 head.Score = 100 var newstu *Student = new(Student) newstu.Name = "stu1000" newstu.Age = 18 newstu.Score = 100 for i := 0; i < 10; i++ { stu := Student{ Name: fmt.Sprintf("stu%d", i), Age: rand.Intn(100), Score: rand.Float32() * 100, } stu.next = head head = &stu } // trans(head) // delNode(head) addNode(head, newstu) trans(head) }
遍历二叉树
package main import "fmt" //定义二叉树结构体 type treeNode struct { Value int Left, Right *treeNode } func (node *treeNode) print() { fmt.Println(node.Value) } //遍历二叉树 func (node *treeNode) traverse() { if node == nil { return } node.Left.traverse() node.print() node.Right.traverse() } //新建二叉树 func createTreeNode(value int) *treeNode { return &treeNode{Value: value} } func main() { tree := createTreeNode(3) tree.Left = createTreeNode(0) tree.Right = createTreeNode(5) tree.Left.Right = createTreeNode(2) tree.Right.Left = createTreeNode(0) tree.traverse() }
TAG
package main import ( "encoding/json" "fmt" ) type Student struct { Name string `json:"name"` Age int Score int } func main() { stu := Student{ Name: "alex", Age: 18, Score: 80, } data, err := json.Marshal(stu) if err != nil { fmt.Println("json encode failed,err:", err) return } fmt.Println(string(data)) }
匿名字段
结构体中包含匿名字段
package main import ( "fmt" "time" ) type Car struct { name string age int } type Train struct { Car int start time.Time } func main() { var t Train t.name = "alex" //t.Car.name = "alex" t.age = 18 t.int = 200 fmt.Println(t) }
方法
func (receiver type) methodName (参数列表) (返回值列表){
}
package main import ( "fmt" ) type Student struct { Name string Age int } func (p *Student) init(name string, age int) { p.Name = name p.Age = age } func (p Student) get() Student { return p } func main() { var stu Student stu.init("stu", 10) stu1 := stu.get() fmt.Println(stu1) }
声明
- 定义一个结构体struct
- 定义方法
调用
- 声明一个结构体实例
- 实例.methodName
继承(能继承结构体的属性和方法)
package main import ( "fmt" ) type car struct { weight int name string } func (p *car) Run() { fmt.Println("running") } type bike struct { car //匿名结构体,继承 wheel int } type train struct { c car //有名结构体,组合 } func main() { var b bike var t train b.weight = 100 b.name = "bike" b.wheel = 2 t.c.weight = 10000 fmt.Println(b) fmt.Println(t) b.Run() }
如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现继承
如果一个struct嵌套了另一个有名结构体,这个模式叫组合
接口
接口实现:
1、golang中的接口,不需要显示的实现,只要一个变量,含有接口类型中的所有方法,那么这个变量就实现了这个接口
2、如果一个变量还有多个interface的方法,那么这个变量就实现了多个接口
package main import ( "fmt" ) type Test interface { Print() Sleep() } type Student struct { name string age int } func (p Student) Print() { fmt.Println("name", p.name) fmt.Println("age", p.age) } func (p Student) Sleep() { fmt.Println("sleeping") } func main() { var t Test var stu = Student{ name: "stu1", age: 20, } t = stu t.Print() t.Sleep() }
实现接口规定的所有方法
package main import ( "fmt" ) //car 接口 两个方法GetName、Run type car interface { GetName() string Run() } //定义一个结构体 type BMW struct { Name string } //实现GetName方法 func (p BMW) GetName() string { return p.Name } //实现Run方法 func (p BMW) Run() { fmt.Printf("%s is running", p.Name) } func main() { var c car bmw := BMW{ Name: "bmw", } c = bmw c.GetName() c.Run() }
接口实现排序
package main import ( "fmt" "math/rand" "sort" ) type Student struct { Name string Age int } type Book struct { Name string Author string } type StudentArray []Student func (p StudentArray) Len() int { return len(p) } func (p StudentArray) Less(i, j int) bool { return p[i].Name < p[j].Name } func (p StudentArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func main() { var stus StudentArray for i := 0; i < 10; i++ { stu := Student{ Name: fmt.Sprintf("stu%d", rand.Intn(100)), Age: rand.Intn(100), } stus = append(stus, stu) } for _, v := range stus { fmt.Println(v) } fmt.Println(" ") sort.Sort(stus) for _, v := range stus { fmt.Println(v) } }
实现负载均衡接口
├── balance
│ ├── balance.go
│ ├── instance.go
│ ├── random.go
│ └── roundrobin.go
└── main
└── main.go
balance.go
package balance type Balancer interface{ DoBalance([]*Instance) (*Instance,error) }
instance.go
package balance type Instance struct { host string port int } func NewInstance(host string, port int) *Instance { return &Instance{ host: host, port: port, } }
random.go
package balance import ( "errors" "math/rand" ) type RandBalance struct { } func (p *RandBalance) DoBalance(insts []*Instance) (inst *Instance, err error) { if len(insts) == 0 { err = errors.New("No instance") return } lens := len(insts) index := rand.Intn(lens) inst = insts[index] return }
main.go
package main import ( "fmt" "go_dev/day6/负载均衡接口/balance" "math/rand" "time" ) func main() { var insts []*balance.Instance for i := 0; i < 10; i++ { host := fmt.Sprintf("192.168.%d.%d", rand.Intn(255), rand.Intn(255)) one := balance.NewInstance(host, 8888) insts = append(insts, one) } balancer := &balance.RandBalance{} for { inst, _ := balancer.DoBalance(insts) fmt.Println(inst) time.Sleep(time.Second) } }