type Point struct{ X,Y int }
p := Point{1,2}
所以,这种格式一般用在定义结构体类型的包中或者一些有明显的成员变量顺序约定的小结构体中,比如
image.Point{x,y}
或者color.RGBA{red,green,blue,alpha}
。我们用得更多的是第二种格式,通过指定部分或者全部成员变量的名称和值来初始化结构体变量:
anim := gif.GIF{LoopCount: nframes}
如果在这种初始化方式中某个成员变量没有指定,那么它的值就是该成员变量类型的零值。因为指定了成员变量的名字,所以它们的顺序是无所谓的。这两种初始化方式不可以混合使用,另外也无法使用第一种初始化方式来绕过不可导岀变量无法在其他包中使用的规则。
package p
type T struct{ a,b int } // a 和 b 都是不可导出的
package q
import "p"
var _ = p.T{a: 1,b: 2} //编译错误,无法引用 a、b
var _ = p.T{l,2} //编译错误,无法引用 a、b
结构体类型的值可以作为参数传递给函数或者作为函数的返回值。例如,下面的函数将 Point 缩放了一个比率:
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
}
pp := &Point{1,2}
这个等价于:
pp := new(Point)
*pp = Point{1,2}
结构体比较
如果结构体的所有成员变量都可以比较,那么这个结构体就是可比较的。两个结构体的比较可以使用 == 或者 !=。其中 == 操作符按照顺序比较两个结构体变量的成员变量,所以下面的两个输出语句是等价的:
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"
type address struct {
hostname string
port int
}
hits := make(map[address]int)
hits[address{"golang.org",443}]++