Golang 之 struct

xys1228 · · 1664 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

声明一个struct

声明一个 struct 的语法如下:

type struct_name struct {
    body
}

例如:

type Person struct {
    name string
    age uint8
}

关于 struct 字段的可见性

如果一个 struct 的字段以大写字母开头, 则表示这个字段是导出的, 即可以在其他包中访问这个字段, 例如:

type Person struct {
    Name string
    age uint8
}

上面的例子中, 因为 Person 的 Name 字段是大写字母开头, 因此可以在其他包访问它, 而 age 是小写字母开头, 因此仅仅能在包内访问.

struct 字面量

我们可以使用 struct 字面量来实例化一个 struct, 例如:

xys := Person {
    "xys",
    18,
}
fmt.Printf("%v\n", xys)

上面的例子中, 我们在使用 struct 字面量时, 没有指定字段的对应关系, 因此字面量中值的顺序需要和定义 struct 时的字段顺序一致, 并且不能省略任何字段. 如果顺序不对的话, 则会产生编译错误

xys := Person {
    18,
    "xys",
}
fmt.Printf("%v\n", xys)

上面的代码会产生编译错误, 提示类型不匹配:

src/github.com/yongshun/test.go:14: cannot use 18 (type int) as type string in field value
src/github.com/yongshun/test.go:15: cannot use "xys" (type string) as type uint8 in field value

除了上面的字面量实例化 struct 以外, 我们还可以使用另一种类型的字面量:

xys := Person{
    age: 18,
    name: "xys",
}

fmt.Printf("%v\n", xys)

第二种字面量初始化的方式和第一种的区别就是: 第二种需要指定字段的名字和其对应的值. 不过第二种字面量初始化方式有一个优点, 即它可以按照任意顺序排列字段, 而且可以仅仅初始化一部分的字段, 例如:

xys := Person{
    name: "xys",
}

当某些字段没有被初始化时, 它的值就被初始化为默认值(这里 age 字段的默认值就是0).
注意, 这两种初始化方式不能混合使用.

struct 的比较

如果在 struct 中所有的字段都可以比较(comparable), 则这个 struct 就可以比较

p1 := Person{
    age: 18,
    name: "xys",
}

p2 := Person{
    age: 18,
    name: "xys",
}

fmt.Printf("%t\n", p1 == p2) // true

如果一个 struct 是可比较的, 则这个 struct 可以作为一个 map 的 Key, 例如:

p1 := Person{
    age: 18,
    name: "xys",
}

p2 := Person{
    age: 18,
    name: "xys",
}

fmt.Printf("%t\n", p1 == p2)

persons := make(map[Person]string)

persons[p1] = "xys"
persons[p2] = "by"

fmt.Println(persons[p1])

注意, 如果以 struct 为 key, 当两个 struct 相等, 那么对 map 来说, 这两个 struct 是同一个 key.
例如上面的例子, p1 == p2, 因此 persons[p1] == persons[p2]

struct 嵌入 与 匿名字段

Go 允许我们声明一个仅仅有类型, 但是没有名字的字段, 这样的字段叫做匿名字段.
例如:

type Person struct {
    name string
    age uint8
}

type Student struct {
    Person
    id uint32
}

上面的例子中, Student 中嵌入了另一个 struct, 即 Person, 因此 构成了一个匿名字段.
当一个 struct A 嵌入到另一个 struct B 中, 那么 struct B 就可以直接方法 struct A 中的字段.例如:

type Person struct {
    name string
    age uint8
}

type Student struct {
    Person
    id uint32
}

func main() {
    var s Student

    s.name = "xys"
    s.age = 18
    s.id = 1

    fmt.Println(s)
}

上面的例子中, 我们使用 s.name 来访问了 Person 中的字段, 它等同于 "s.Person.name".
当然, 我们也可以使用字面量来初始化 Student, 例如:

s := Student {
    Person: Person {
        name: "xys",
        age: 18,
    },
    id: 1,
}

根据上面的例子, 我们知道, 匿名字段其实也是有名字的, 不过它的名字是类型名, 并且在 点号表达式(dot expressions) 中, 匿名字段的类型名可以省略.
但是需要注意的是, 在字面量实例化 struct 时, 不能省略匿名字段的类型名, 即如下代码是错误的:

s := Student {
    name: "xys",
    age: 18,
    id: 1,
}

有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:xys1228

查看原文:Golang 之 struct

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1664 次点击  
加入收藏 微博
上一篇:Golang 之 函数
下一篇:Golang 之 defer
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传