类似于 C 中的结构体,也就是用户自定义的类型,它代表若干字段的集合。
这里简单介绍其使用方法。
简介
GoLang 中无法通过类似 C 中的 Sizeof 直接获取结构体的大小,只能通过 unsafe.Sizeof()
获取变量大小。这也就意味着,如果要获取结构体大小,需要先声明一个变量,实际上,可以使用类似 unsafe.Sizeof(Package{})
这种操作。
对于 GoLang 的结构体,在编译器编译时会采用类似 C 的字节对齐操作,不过与 C 语言不同的是,在利用 binary 操作时会自动规避掉,无需手动设置。
注意,如果一个结构体类型的名称以大写字母开头,则该结构体被导出,其它包可以访问它;同样,如果结构体中的字段名以大写字母开头,则这些字段也可以被其他包访问。
使用
如下是简单的使用。
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
p := Person{
Name: "Jack",
Age: 30,
}
fmt.Printf("Got Person %#v\n", p)
}
上述会打印 Got Person main.Person{Name:"Jack", Age:30}
。
格式化
可以指定格式化的内容。
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func (p *Person) String() string {
return fmt.Sprintf("%s-%d", p.Name, p.Age)
}
func main() {
p := &Person{
Name: "Jack",
Age: 30,
}
fmt.Printf("Got Person %s\n", p)
}
默认输出 Got Person &{Jack %!s(int=30)}
,当添加了 String()
函数实现后会输出 Got Person Jack-30
。
匿名字段
定义结构体类型时可以仅指定字段类型而不指定字段名字,那么,此时的这种字段叫做匿名字段 (Anonymous Field)。
package main
import (
"fmt"
)
type Person struct {
string
int
}
func main() {
/* p := Person{string: "Jack", int: 30} */
p := Person{"Jack", 30}
fmt.Printf("Current Person %#v\n", p)
fmt.Printf("And Person Name %#v\n", p.string)
}
虽然匿名字段没有名字,但是默认名字为类型名,那么上述的 Person
可以通过 Person.string
引用。当然,这只适用于不同类型的字段,否则将会报错。
嵌套 VS. 字段提阶
结构体的字段也可以是一个结构体,这种结构体称为嵌套结构体。
如果结构体中的匿名字段是结构体,这个匿名结构体中字段成为提阶字段 (Promoted Fields),可以从外部结构体直接访问匿名结构体类型中的字段,就像这些字段原本属于外部结构体一样。
package main
import (
"fmt"
)
type Address struct {
City, State string
}
type Person struct {
Name string
Age int
// address Address // 嵌套
Address // 字段提阶
}
func main() {
p := Person{
Name: "Jack",
Age: 30,
Address: Address{
City: "HangZhou",
State: "ZheJiang",
},
}
fmt.Printf("Got Person %#v\n", p)
/* Replace */
p.Address = Address{
City: "NanJing",
State: "JiangSu",
}
fmt.Printf("Got New Person %#v\n", p)
fmt.Printf("And it's City %s\n", p.City)
}
上面的程序中,Person
结构体有一个匿名字段 Address
,这个匿名字段也是一个结构体。此时 Address
中的字段 City
和 State
被称为提阶字段,因为它们就好像被直接声明在 Person
里一样。
在使用时可以直接通过 p.City
引用。