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()。
挑战
简单让我们构建一个配置管理器,演示 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:再次显示配置,查看更新后的值
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Go 在线编译器