跳到主要内容

Go 内存分配机制

· 阅读需 2 分钟

问题引入

在阅读 New-API 源码的时候,发现在 struct 中定义一个 *string 类型的字段

type ClaudeMediaMessage struct {
Type string `json:"type,omitempty"`
Text *string `json:"text,omitempty"`
Model string `json:"model,omitempty"`
Source *ClaudeMessageSource `json:"source,omitempty"`
Usage *ClaudeUsage `json:"usage,omitempty"`
StopReason *string `json:"stop_reason,omitempty"`
PartialJson *string `json:"partial_json,omitempty"`
Role string `json:"role,omitempty"`
Thinking string `json:"thinking,omitempty"`
Signature string `json:"signature,omitempty"`
Delta string `json:"delta,omitempty"`
// tool_calls
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Input any `json:"input,omitempty"`
Content json.RawMessage `json:"content,omitempty"`
ToolUseId string `json:"tool_use_id,omitempty"`
}

func (c *ClaudeMediaMessage) SetText(s string) {
c.Text = &s
}

struct 中定义一个 *string 类型的字段的目的

  1. 可以区分此字段是否被设置,或者被设置为 ""

    • 原理是:*string 是一个字符串指针,默认值是 nil, 而 string 的默认值是 ""
  2. 在序列换 JSON 的时候,如果字段是 *string 类型,且值为 nil,则在序列化时会被忽略。

  3. API 设计时,可能很好的表达出可选字段。

  4. 避免频繁出现空字符串。

    • var s string , s 会被初始化为 "",变量没有逃逸,则会被分配在栈上,底层实现是 StringHeader, 大小 16 字节(指向底层字节数组的指针(8 字节,64 位系统)、字符串长度(8 字节,64 位系统))
    • var sp *string , sp 默认值是 nil, 声明时立即分配内存(通常是在栈上),大小 8 字节(由操作系统决定,64位,8字节)

文章引用