__都非拉得的博客

Posted on 08 May 2018

结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。每个值称为结构体的成员

创建和初始化

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

var dilbert Employee
// 结构体字面值
type Point struct{ X, Y int }
p := Point{1, 2}
// or
p := Point{X:1, Y:2}

使用

// 成员赋值
dilbert.Salary = 5000

// 对成员取地址,然后通过指针访问
position := &dilbert.Position
*position = "Senior " + *position

// 结构体可以作为函数的参数和返回值
func Scale(p Point, factor int) Point {
    return Point{p.X * factor, p.Y * factor}
}

fmt.Println(Scale(Point{1, 2}, 5)) // "{5 10}"

// 如果考虑效率的话,较大的结构体通常会用指针的方式传入和返回,
func Bonus(e *Employee, percent int) int {
    return e.Salary * percent / 100
}

// 如果要在函数内部修改结构体成员的话,用指针传入是必须的
func AwardAnnualRaise(e *Employee) {
    e.Salary = e.Salary * 105 / 100
}

结构体比较

如果结构体的全部成员都是可以比较的,那么结构体也是可以比较的,那样的话两个结构体将可以使用==或!=运算符进行比较

type Point struct{ X, Y int }

p := Point{1, 2}
q := Point{2, 1}
fmt.Println(p.X == q.X && p.Y == q.Y) // "false"
fmt.Println(p == q)                   // "false"

可比较的结构体类型和其他可比较的类型一样,可以用于map的key类型。

type address struct {
    hostname string
    port     int
}

hits := make(map[address]int)
hits[address{"golang.org", 443}]++

  1. 一个命名为S的结构体类型将不能再包含S类型的成员:因为一个聚合的值不能包含它自身。
  2. 如果结构体成员名字是以大写字母开头的,那么该成员就是导出的
  3. 如果结构体没有任何成员的话就是空结构体,写作struct{}。它的大小为0,也不包含任何信息
  4. 结构体可以作为函数的参数和返回值