go入门练习006:struct

struct基本概念

定义:字段顺序非常重要!两个字段完全一样,但顺序不同的struct视为不同。

type Employee struct {
	ID        int
	Name      string
	Address   string
	DoB       time.Time
	Position  string
	Salary    int
	ManagerID int
}

使用:

var dilbert Employee
dilbert.Salary -= 5000 
//指针访问
var employeeOfTheMonth *Employee = &dilbert
employeeOfTheMonth.Position += " (proactive team player)"
(*employeeOfTheMonth).Position += " (proactive team player)"
//dilbert的字段也是变量,也支持指针访问
position := &dilbert.Position
*position = "Senior " + *position 

go函数传参基本上都是值传递,struct也是。

func Scale(p Point, factor int) Point {
  return Point{p.X * factor, p.Y * factor}
}

所以,为了效率,通常使用指针:

func Bonus(e *Employee, percent int) int {
    return e.Salary * percent / 100
}

struct不能嵌套定义,如结构体S,不能包含S字段。但可以包含*S字段,这样就可以实现链表和树等数据结构了。

package main

import "fmt"

type tree struct {
	value       int
	left, right *tree
}

// Sort sorts values in place.
func Sort(values []int) {
	var root *tree
	for _, v := range values {
		root = add(root, v)
	}
	appendValues(values[:0], root)
}

// appendValues appends the elements of t to values in order
// and returns the resulting slice.
func appendValues(values []int, t *tree) []int {
	if t != nil {
		values = appendValues(values, t.left)
		values = append(values, t.value)
		values = appendValues(values, t.right)
	}
	return values
}

func add(t *tree, value int) *tree {
	if t == nil {
		// 相当于 return &tree{value: value}.
		t = new(tree)
		t.value = value
		return t
	}
	if value < t.value {
		t.left = add(t.left, value)
	} else {
		t.right = add(t.right, value)
	}
	return t
}

func main() {
	values := []int{1, 5, 0, 6, 7, 1, 6, 7, 3, 7, 0}
	Sort(values)
	fmt.Println(values)
}

struct字面量

struct字面量有两种形式:

type Point struct{ X, Y int }
//方式1,按位置
p := Point{1, 2}
//方式2,按字段名
p := Point{X:1,Y:2}
//显然方式2更灵活,可以省略部分字段,省略的字段默认零值
p := Point{Y:2}

由于struct经常用指针,go提供了一个简便的方式来创建和初始化struct并获取它的指针:

pp := &Point{1, 2}
//等价于
pp := new(Point)
*pp = Point{1, 2}

struct嵌套和匿名字段

struct嵌套采用组合的思想,简化struct的定义,如两个struct:

type Circle struct {
      X, Y, Radius int
}
type Wheel struct {
      X, Y, Radius, Spokes int
}

轮子Wheel前三个字段都是圆Circle的字段,因此可以嵌套定义:

type Point struct {
      X, Y int
}
type Circle struct {
      Center Point//圆心
      Radius int
}
type Wheel struct {
      Circle Circle//圆
      Spokes int
}

var w Wheel
w.Circle.Center.X = 8
w.Circle.Center.Y = 8
w.Circle.Radius = 5
w.Spokes = 20

上面访问Wheel字段的方式非常繁琐,使用匿名字段可以简化:

type Circle struct {
      Point//匿名字段圆心
      Radius int
}
type Wheel struct {
      Circle//匿名字段圆
      Spokes int
}

var w Wheel
w.X = 8 // equivalent to w.Circle.Point.X = 8
w.Y = 8 // equivalent to w.Circle.Point.Y = 8
w.Radius = 5 // equivalent to w.Circle.Radius = 5
w.Spokes = 20

匿名字段的问题是不支持字面量:

w = Wheel{8, 8, 5, 20} // compile error: unknown fields
w = Wheel{X: 8, Y: 8, Radius: 5, Spokes: 20} // compile error: unknown fields

字面量初始化必须这样:

w = Wheel{Circle{Point{8, 8}, 5}, 20}
//或
w = Wheel{
      Circle: Circle{
            Point: Point{X: 8, Y: 8},
      Radius: 5,
      },
      Spokes: 20, // NOTE: trailing comma necessary here (and at Radius)
}

posted on 2020-10-23 11:38  caffebabe  阅读(107)  评论(0编辑  收藏  举报