我正在用嵌入式 struct 测试go json封送.然而,当我嵌入时间时,我看到了这一点.时间,为什么它总是覆盖其他嵌入式 struct ,即使它们也提供自己的自定义封送处理?下面的代码总是打印"0001-01-01T00:00:00Z"

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

type A struct {
}

func (a A) Print() {
    fmt.Println("A")
}

type B struct {
    B int
}

func (a A) MarshalJSON() ([]byte, error) {
    return []byte(`"a"`), nil
}

func (b B) MarshalJSON() ([]byte, error) {
    return []byte(`"b"`), nil
}

func (a B) Print() {
    fmt.Println("A")
}

type C struct {
    A
    B
    time.Time
    C int `json:"C"`
}

func main() {
    fmt.Println("Hello, 世界")
    c := C{}
    decode, err := json.Marshal(c)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(string(decode))
}

推荐答案

如果嵌入了多个具有相同名称的字段或方法的类型,那么这些字段或方法将不再可以直接访问.

Selectors:

x.f

  1. 对于类型为T*T的值x,其中T不是指针或

这意味着,考虑到以下类型:

type S1 struct { F string }

type S2 struct { F string }

type S3 struct {
    S1
    S2
}

表达s3.F是非法的:

var s3 S3
_ = s3.F // ambiguous selector s3.F

这是因为有more than one 101 at the shallowest depth个.你可以穿playground号试试.

同样的规则也适用于方法.由此可知,C类型不满足json.Marshaler接口because,它在同一深度嵌入了实现MarshalJSON()方法的more that one类型.你可以在playground上看到这一点.


然而,问题仍然是,为什么不管怎样都使用嵌入式time.Time的定制封送.这是因为time.Time不仅实现了json.Marshaler接口,还实现了encoding.TextMarshaler接口(docsplayground).而json.Marshaldocumentation则是这样说的:

Marshal递归地遍历值v.如果遇到一个值

一旦AB实现了encoding.TextMarshaler接口,就可以确定上述行为是否成立,那么time.TimeMarshalText方法将不再使用.

Go相关问答推荐

Golang Cososdb-gremlin连接

语法-for循环中的initit陈述是否允许分配?

map 中的多个函数类型,Golang

Go Regexp:匹配完整的单词或子字符串,或者根本不匹配

mockgen不创建模拟

Go:拆分一个由逗号分隔的键/值对字符串,并在给定的键/价值对中嵌入可能的逗号

将字符串格式的x509证书生成主题名称

在 Windows 11 上运行 go mod tidy 时的 gitlab 权限问题

如何将已知类型转换为指向switch 中类型参数的指针?

如何将验证器标记添加到嵌套字段

如何使用 sync.WaitGroup 来执行所有的 goroutine?

自定义 Fyne 自适应网格布局

在 .go 文件中运行一个函数和在 Go 模板中调用它有什么区别?

如何使用带有方法的字符串枚举作为通用参数?

GqlGen - 在字段解析器中访问查询输入参数

如何排除溢出矩阵的坐标

为什么 Go 中的 maps.Keys() 将 map 类型指定为 M?

Gorilla/Mux 和 Websocket 竞赛条件,这安全吗?

Golang 查询扫描未将查询正确扫描到 struct 中

有没有一种方法可以确保传递的值具有使用泛型的某些字段?