结构体

特点:

  1. 用来自定义复杂数据结构
  2. struct里面可以包含多个字段(属性)
  3. struct类型可以定义方法,注意和函数的区别
  4. struct是值类型
  5. struct类型可以嵌套
  6. 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("\n\n")
	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)
	}
}

  

 

posted @ 2018-07-23 09:56  hongpeng0209  阅读(230)  评论(0编辑  收藏  举报