Menu
CoddyTech

new() 函数

本课属于 Coddy GO 学习旅程的“面向对象编程”单元。第 22 课,共 107 课。

Go 提供了一个名为 new() 的内置函数,它会为某种类型分配内存,并返回指向该内存的指针。分配的内存会初始化为该类型的零值。

p := new(int)      // 为 int 分配内存
fmt.Println(*p)    // 0(零值)
fmt.Println(p)     // 0xc000018030(内存地址)

new() 函数接收一个类型作为参数,并返回一个指向该类型新分配的零值的指针。当你需要一个指针,但没有现成的变量可供引用时,这尤其有用。

使用结构体时,new() 会创建一个指向结构体的指针,并将所有字段设为零值。

type Person struct {
    Name string
    Age  int
}

p := new(Person)
fmt.Println(p.Name)  // ""(空字符串)
fmt.Println(p.Age)   // 0

你可能想知道何时使用 new(),何时使用地址运算符 &。下面这两种方式是等效的:

// 使用 new()
p1 := new(Person)

// 对字面量使用取地址运算符
p2 := &Person{}

&Person{} 这种语法在实际中更常见,因为它可以让你同时初始化字段。当你特别需要一个零值实例,并且希望明确体现内存分配语义时,可以使用 new()。

challenge icon

挑战

简单

让我们构建一个配置管理器,演示 new() 如何分配内存并将结构体初始化为零值。你会看到,这种方法与对结构体字面量使用取地址运算符有何不同。

你需要将代码分放在两个文件中:

  • config.go:定义一个 ServerConfig 结构体,其中包含 Host(string)、Port(int)、MaxConnections(int)和 DebugMode(bool)字段。创建两个函数:
    • NewServerConfig:使用 new() 分配一个 ServerConfig,并直接返回指针(所有字段均为零值)
    • ConfigureServer:接收一个 *ServerConfig 指针,以及主机名字符串和端口整数,然后通过指针设置配置中的相应字段
    还要为 *ServerConfig 添加一个 Display 方法,返回显示所有配置值的格式化字符串。
  • main.go:从输入中读取主机名和端口。首先,使用 NewServerConfig() 创建配置并显示出来,以展示零值。然后使用 ConfigureServer 设置主机名和端口,再次显示配置,以展示更新后的值。

输入如下:

  • 第 1 行:主机名(字符串)
  • 第 2 行:端口号(整数)

你的 Display 方法应返回以下精确格式的字符串:

Host: [Host]
Port: [Port]
MaxConnections: [MaxConnections]
DebugMode: [DebugMode]

将显示结果打印两次,一次在配置之前(显示零值),一次在配置之后(显示更新后的主机名和端口)。

例如,输入 localhost 和 8080 时,输出应为:

Host: 
Port: 0
MaxConnections: 0
DebugMode: false
Host: localhost
Port: 8080
MaxConnections: 0
DebugMode: false

注意,第一次显示的所有字段都是零值(空字符串、0、0、false),因为 new() 会将所有内容初始化为零值。调用 ConfigureServer 后,只有主机名和端口会改变,其他字段仍保持零值。

亲手试试

package main

import (
	"fmt"
)

func main() {
	// 读取输入
	var host string
	var port int
	fmt.Scanln(&host)
	fmt.Scanln(&port)

	// TODO:使用 NewServerConfig() 创建配置并显示它
	// 这会显示零值

	// TODO:使用 ConfigureServer 设置主机和端口

	// TODO:再次显示配置,查看更新后的值
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Go 在线编译器