Go Academy · 课时

new() 与指针的使用时机

使用 new 分配内存与常见指针模式

第 4 / 4 课13 个步骤

new() 与指针的使用时机 是 CoddyKit 上的免费 Go Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。

内置函数 new()

new(T) 会分配一个已置零的 T,并返回 *T。对于结构体,它等价于 &T{}:

package main
import "fmt"

func main() {
    p := new(int)
    fmt.Println(*p)     // 0
    *p = 42
    fmt.Println(*p)     // 42

    type Point struct{ X, Y int }
    pt := new(Point)
    fmt.Println(*pt)    // {0 0}
}

new 与 &T{}

对于结构体,&T{} 更符合 Go 的惯用写法,并且支持初始化字段。现代 Go 中很少使用 new:

package main
import "fmt"

type Config struct{ Port int; Host string }

func main() {
    a := new(Config)          // zeroed
    b := &Config{Port: 8080}  // initialized
    fmt.Println(a, b)
}

何时返回指针

在以下情况下,应从构造函数返回指针:

  • 结构体具有状态,调用方必须共享同一个实例
  • 结构体具有指针接收者方法(满足接口时需要)
  • 结构体较大,复制它的代价很高

何时返回值

在以下情况下,应返回值:

  • 类型较小(只有几个字段)
  • 它是不可变的配置
  • 您希望明确表示调用方获得的是独立副本

示例:尽管 time.Time 有许多方法,它仍按值返回。

切片和映射中的指针

在集合中存储指针,可以让多个使用者共享修改:

package main
import "fmt"

type User struct{ Name string; Score int }

func main() {
    users := []*User{{"Alice", 0}, {"Bob", 0}}
    users[0].Score = 100
    fmt.Println(users[0]) // &{Alice 100}
}

使用指向基本类型的指针表示可选性

*int 或 *string 字段可以为 nil,表示“未设置”。这对于使用 omitempty 的 JSON 或可选的数据库列很有用:

package main
import "fmt"

type Profile struct {
    Name string
    Age  *int // nil means not provided
}

func main() {
    p := Profile{Name: "Alice"}
    fmt.Println(p.Age == nil) // true
    age := 30
    p.Age = &age
    fmt.Println(*p.Age) // 30
}

避免指针泛滥

过度使用指针会增加 GC 压力并降低缓存局部性。不要仅仅为了性能就将值类型改为指针,应先进行基准测试。

make 与 new

make 会初始化切片、映射和通道(它们需要内部设置)。new 会为任意类型分配零值,并返回一个指针。它们的用途不同:

package main
import "fmt"

func main() {
    s := make([]int, 5)           // usable slice
    m := make(map[string]int)     // usable map
    p := new(int)                 // *int pointing to 0
    fmt.Println(s, m, *p)
}

不可变指针模式

返回 *T,但将其记录为不可变;使用者不应修改它。这种模式常见于在多个协程之间共享的配置对象。

指针安全概要

遵循以下规则,确保指针使用安全:

  • 解引用前始终检查 nil
  • 不要将指向栈变量的指针存储得超过该变量的生命周期(Go 的逃逸分析会处理这一点)
  • 除非绝对必要,否则不要转换 unsafe.Pointer
  • 让编译器管理栈与堆

快速检查

new(int) 返回什么?

回顾:new 与指针

要点:

  • new(T) 返回已置零的 *T——很少使用;优先使用 &T{}
  • 值较小或不可变时返回值;有状态或较大时返回指针
  • *T 字段支持将 nil 表示为缺失
  • 不要过度使用指针——GC 是有代价的

练习提示

创建一个 Settings 结构体,其中包含一个用于 MaxConnections 的 *int 字段。编写一个接收 *Settings 的函数,仅在该字段为 nil 时设置默认值。

免费开始

用 AI 导师学习 Go — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
51
课程
203

常见问题解答

「new() 与指针的使用时机」课时是免费的吗?

是的 — 「new() 与指针的使用时机」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。

「new() 与指针的使用时机」这节课中我会学到什么?

使用 new 分配内存与常见指针模式 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Go Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「new() 与指针的使用时机」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Go Academy 课中编写并运行代码吗?

能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 什么是指针
  2. 指针与函数
  3. 方法中的指针接收者
  4. new() 与指针的使用时机
← 返回 Go Academy