结构体
特点:
- 用来自定义复杂数据结构
- 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("\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)
}
}

浙公网安备 33010602011771号