结构体
结构体(struct)是用户自定义的类型,代表若干字段的集合。有时将多个数据看做一个整体要比单独使用这些数据更有意义,在这种情况下就适合使用结构体。
比如将一个员工的 firstName, lastName 和 age 打包在一起成为一个结构体就是很有意义的。
具名结构体
type Employee struct {
firstName, lastName string
age int
}
上面的 Employee 是一个具名结构体(named structure),因为它创建了一个具有名字的结构体类型: Employee 。
匿名结构体
我们也可以定义一个没有类型名称的结构体,这种结构体叫做匿名结构体(anonymous structures)。
var employee struct {
firstName, lastName string
age int
}
上面的代码片段声明了一个匿名结构体变量 employee。
package main
import (
"fmt"
)
func main() {
var emp1 struct {
firstName, lastName string
age int
}
emp1.firstName = "Andreah"
emp1.lastName = "Nikola"
emp1.age = 31
emp2 := struct {
firstName, lastName string
age int
}{
firstName: "Andreah",
lastName: "Nikola",
age: 31,
}
fmt.Println("Employee 1", emp1)
fmt.Println("Employee 2", emp2)
}
匿名字段
定义结构体类型时可以仅指定字段类型而不指定字段名字。这种字段叫做匿名字段(anonymous field)。
package main
import (
"fmt"
)
type Person struct {
string
int
}
func main() {
p := Person{"Naveen", 50}
fmt.Println(p)
}
在上面的程序中,Person 是一个具有两个匿名字段的结构体类型,类型分别为 string
和 int
。
虽然匿名字段没有名字,但是匿名字段的默认名字为类型名。比如上面的 Person 类型,尽管它的字段是匿名的,但是默认它们拥有它们的类型的名字。因此 Person 结构体有两个名为 string 和 int 的字段。
package main
import (
"fmt"
)
type Person struct {
string
int
}
func main() {
var p1 Person
p1.string = "naveen"
p1.int = 50
fmt.Println(p1)
}
在上面的程序中,我们通过使用匿名字段的类型名("string"
和 "int"
)来访问 Person 结构体的字段。
导出结构体和字段
如果一个结构体类型的名称以大写字母开头,则该结构体被导出,其他包可以访问它。同样地,如果结构体中的字段名以大写字母开头,则这些字段也可以被其他包访问。
type Spec struct { //exported struct
Maker string //exported field
model string //unexported field
Price int //exported field
}
比较结构体
结构体是值类型,如果其字段是可比较的,则该结构体就是可以比较的。如果两个结构体变量的所有非空字段都相等,则认为这两个结构体变量相等。
package main
import (
"fmt"
)
type name struct {
firstName string
lastName string
}
func main() {
name1 := name{"Steve", "Jobs"}
name2 := name{"Steve", "Jobs"}
if name1 == name2 {
fmt.Println("name1 and name2 are equal")
} else {
fmt.Println("name1 and name2 are not equal")
}
name3 := name{firstName: "Steve", lastName: "Jobs"}
name4 := name{}
name4.firstName = "Steve"
if name3 == name4 {
fmt.Println("name3 and name4 are equal")
} else {
fmt.Println("name3 and name4 are not equal")
}
}
在上面的程序中,name 结构体类型包含两个 string 字段。因为 string 是可比较的,因此两个 name 类型的变量也是可以比较的。所以,name1 和 name2 是相等的,而 name3 和 name4 是不相等的。
如果结构体包含不可比较的类型的字段,那么这两个结构体是不可比较的。
package main
import (
"fmt"
)
type image struct {
data map[int]int
}
func main() {
image1 := image{data: map[int]int{
0: 155,
}}
image2 := image{data: map[int]int{
0: 155,
}}
if image1 == image2 {
fmt.Println("image1 and image2 are equal")
}
}
在上面的程序中,image 结构体类型包含了一个字段 data,该字段是 map 类型。map 是不可比较的类型,因此 image1 和 image2 是不可比较的。