2.10. 补充注意事项 7-8 结构体自定义类型字段与可变长度字段的初始化与扩容

未匹配的标注

g g study,d d up!

补充注意事项 7

结构体自定义类型字段

补充注意事项 7 结构体自定义类型字段

7. 如果结构体中包含自定义类型的字段,需要实现对应的接口方法,例如 Stringer 接口中的 String() 方法,以便在 fmt 包中使用格式化输出时能够正确地显示。

以下是一个使用自定义类型 Person 的示例,其中实现了 Stringer 接口的 String() 方法:

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("%s (%d years)", p.Name, p.Age)
}

func main() {
    p := Person{"Alice", 30}
    fmt.Println(p)
}

Person 结构体中定义了 NameAge 两个字段,并实现了 Stringer 接口的 String() 方法,该方法返回一个包含 NameAge 字段值的字符串。在 main() 函数中创建了一个 Person 类型的变量 p,并通过 fmt.Println() 函数输出该变量,由于 Person 类型实现了 Stringer 接口,因此 fmt 包会调用 String() 方法输出 p 的字符串表示形式。

输出结果为:

Alice (30 years)

由于自定义类型实现了 Stringer 接口的 String() 方法,因此在 fmt 包中可以通过 %v 等格式化标记将其作为字符串输出。

8. 如果结构体中包含可变长度的字段,例如 slicemap,需要特别注意它们的初始化和扩容。

可变长度的字段,例如 slicemap,需要在使用前进行初始化,否则访问它们时可能会出现空指针异常。同时,在添加元素时,需要特别注意是否需要扩容,否则可能会导致数据丢失或程序崩溃。

对于 slice 类型的字段,可以使用 make() 函数进行初始化,并使用 append() 函数添加元素。如果要预先分配足够的空间,可以使用 make() 函数的第二个参数指定 slice 的容量。例如:

type Person struct {
    Name string
    Age  int
    Tags []string
}

p := Person{
    Name: "Alice",
    Age:  30,
    Tags: make([]string, 0, 10), // 预先分配 10 个元素的空间
}

p.Tags = append(p.Tags, "tag1", "tag2") // 添加元素

对于 map 类型的字段,可以使用 make() 函数进行初始化,并使用键值对的方式添加元素。例如:

type Person struct {
    Name string
    Age  int
    Properties map[string]string
}

p := Person{
    Name: "Alice",
    Age:  30,
    Properties: make(map[string]string),
}

p.Properties["key1"] = "value1" // 添加元素
p.Properties["key2"] = "value2"

需要注意的是,当 slicemap 的容量不足时,会发生扩容。扩容会导致重新分配内存,并将原有的元素复制到新的内存空间中。因此,如果 slicemap 的元素数量较大,扩容操作会对程序的性能产生影响。因此,在实际编程中需要根据具体情况合理设计 slicemap 的容量。

ps:我如果 slice,想要分配不限制个数得空间,如何分配

在 Go 中,可以使用 make 函数来创建 slice,可以通过指定第二个参数为 0 来创建一个没有限制容量的 slice。例如:

s := make([]int, 0, 0)

上面的代码创建了一个空的 slice,并且容量为 0,但是可以随时添加元素而不需要重新分配内存空间。

欢迎关注公众号上海php自学中心,一起交流。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~