0

0

Go语言结构体初始化:new() 与 {} 的选择策略与实践

碧海醫心

碧海醫心

发布时间:2025-11-26 15:38:22

|

986人浏览过

|

来源于php中文网

原创

Go语言结构体初始化:new() 与 {} 的选择策略与实践

go语言中,初始化结构体主要有两种方式:使用`new()`函数或字面量`{}`。`new()`函数返回一个指向零值结构体的指针,适用于需要逐步填充字段或仅需一个零值指针的场景。而`{}`字面量则用于创建结构体的值类型,或者通过`&t{}`语法创建指向已初始化结构体的指针,这在结构体字段值在初始化时已知的情况下更为常见和推荐。理解这两种方法的特性与适用场景,是编写高效go代码的关键。

Go语言结构体初始化方法概述

Go语言提供了灵活的结构体初始化机制,允许开发者根据具体需求选择最合适的方式。核心上,我们有两种主要途径来创建一个结构体实例:

  1. 使用 new() 函数: new(Type) 返回一个指向 Type 类型零值的指针。
  2. 使用结构体字面量 {}: Type{} 创建一个 Type 类型的零值或已初始化的值。通过 &Type{} 可以直接创建并返回一个指向已初始化结构体的指针。

理解这两种方法返回值的类型(值或指针)以及它们的初始化状态(零值或指定值)是做出正确选择的基础。

结构体字面量 {} 初始化

结构体字面量初始化是最常用且推荐的方式,因为它允许在创建实例时直接指定字段的值。

1. 初始化为值类型

当您需要一个结构体的值类型实例时,可以直接使用 Type{} 语法。您可以选择初始化所有字段、部分字段,或者不初始化任何字段(此时所有字段将被初始化为其零值)。

立即学习go语言免费学习笔记(深入)”;

package main

import "fmt"

type Person struct {
    Name string
    Age  int
    City string
}

func main() {
    // 初始化所有字段
    p1 := Person{Name: "Alice", Age: 30, City: "New York"}
    fmt.Printf("p1: %+v, Type: %T\n", p1, p1) // p1: {Name:Alice Age:30 City:New York}, Type: main.Person

    // 初始化部分字段,未指定的字段为零值
    p2 := Person{Name: "Bob", Age: 25}
    fmt.Printf("p2: %+v, Type: %T\n", p2, p2) // p2: {Name:Bob Age:25 City:}, Type: main.Person

    // 初始化为零值结构体
    p3 := Person{}
    fmt.Printf("p3: %+v, Type: %T\n", p3, p3) // p3: {Name: Age:0 City:}, Type: main.Person

    // 字段顺序初始化(不推荐,易出错)
    p4 := Person{"Charlie", 35, "London"}
    fmt.Printf("p4: %+v, Type: %T\n", p4, p4) // p4: {Name:Charlie Age:35 City:London}, Type: main.Person
}

注意事项:

Pic Copilot
Pic Copilot

AI时代的顶级电商设计师,轻松打造爆款产品图片

下载
  • 使用 字段名: 值 的形式进行初始化是最佳实践,即使字段顺序改变,代码依然健壮。
  • 未显式初始化的字段将自动设置为其类型的零值(例如,string 为 "",int 为 0,指针为 nil)。

2. 初始化为指针类型 (&T{})

当您需要一个指向结构体的指针,并且希望在创建时就初始化其字段时,可以使用 &Type{} 语法。这在Go语言中非常常见,因为它结合了创建指针和初始化字段的便利性。

package main

import "fmt"

type Product struct {
    ID    string
    Name  string
    Price float64
}

func main() {
    // 创建并初始化一个指向Product结构体的指针
    prod1 := &Product{ID: "P001", Name: "Laptop", Price: 1200.0}
    fmt.Printf("prod1: %+v, Type: %T\n", prod1, prod1) // prod1: &{ID:P001 Name:Laptop Price:1200}, Type: *main.Product

    // 创建一个指向零值Product结构体的指针
    prod2 := &Product{}
    fmt.Printf("prod2: %+v, Type: %T\n", prod2, prod2) // prod2: &{ID: Name: Price:0}, Type: *main.Product
}

注意事项:

  • &Type{} 语法不仅适用于结构体,也适用于数组、切片和映射类型,用于获取它们的地址。
  • 这种方式在需要将结构体作为函数参数传递指针,或者需要修改原始结构体实例时非常有用。

new() 函数初始化

new(Type) 函数分配内存并返回一个指向该类型零值的指针。它的主要特点是:

  • 返回指针: 始终返回一个指针。
  • 零值初始化: 分配的内存会被清零,因此所有字段都会被初始化为其类型的零值。
package main

import "fmt"

type User struct {
    ID    int
    Email string
    Active bool
}

func main() {
    // 使用 new() 初始化一个指向User结构体零值的指针
    userPtr := new(User)
    fmt.Printf("userPtr: %+v, Type: %T\n", userPtr, userPtr) // userPtr: &{ID:0 Email: Active:false}, Type: *main.User

    // 之后可以逐步填充字段
    userPtr.ID = 101
    userPtr.Email = "test@example.com"
    userPtr.Active = true
    fmt.Printf("userPtr (after population): %+v\n", userPtr) // userPtr (after population): &{ID:101 Email:test@example.com Active:true}
}

new() 与 {} 的选择策略

何时使用 new(),何时使用 {}(包括 &T{})取决于您的具体需求和编码习惯。

  1. 当结构体的完整值在初始化时已知时,优先使用 {} 或 &T{}。

    • 如果您需要一个结构体的值类型:myStruct := MyStruct{Field1: value1, Field2: value2}
    • 如果您需要一个指向已初始化结构体的指针:myStructPtr := &MyStruct{Field1: value1, Field2: value2}
    • 这种方式代码更简洁,意图更明确,因为它在创建时就完成了初始化。
  2. 当结构体字段需要逐步填充,或者您仅需要一个指向零值结构体的指针时,使用 new()。

    • 例如,您可能从不同的来源获取字段数据,或者在循环中逐步构建一个复杂的结构体。
    • myStructPtr := new(MyStruct)
    • myStructPtr.Field1 = fetchedValue1
    • myStructPtr.Field2 = fetchedValue2
    • 尽管如此,即使是逐步填充,许多Go开发者也倾向于先使用 &MyStruct{} 创建一个零值指针,然后填充,因为 &T{} 语法更具一致性。
  3. Go语言的惯用风格:

    • 在Go语言中,&T{} 是获取一个指向结构体指针的非常常见且推荐的方式,因为它允许您在同一行代码中完成内存分配、零值初始化(对于未指定的字段)和指定字段的初始化。
    • new(T) 的使用相对较少,主要在确实只需要一个零值指针,并且不需要在创建时指定任何字段值的情况下。

总结

  • Type{}: 创建一个结构体值类型。可初始化字段,未初始化字段为零值。
  • &Type{}: 创建一个指向结构体的指针,并允许在创建时初始化字段。未初始化字段为零值。这是获取已初始化结构体指针的常用且推荐方式。
  • new(Type): 创建一个指向结构体零值的指针。所有字段都为零值。适用于需要逐步填充或仅需零值指针的场景。

在大多数情况下,当您需要一个结构体实例并知道其初始值时,使用 {} 或 &{} 语法会使代码更清晰、更符合Go语言的惯例。new() 则在特定场景下提供了一种获取零值指针的直接方式。理解它们之间的细微差别,将有助于您编写出更地道、更高效的Go代码。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

195

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

187

2025.07.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

537

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

Go中Type关键字的用法
Go中Type关键字的用法

Go中Type关键字的用法有定义新的类型别名或者创建新的结构体类型。本专题为大家提供Go相关的文章、下载、课程内容,供大家免费下载体验。

233

2023.09.06

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.7万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号