luo2pei4 2020-10-29 21:28 采纳率: 0%
浏览 192

Go语言中结构体嵌入接口值的原理

这个问题是在看go的Context源码的时候发现的。简单来讲就是,结构体A嵌入接口I,再将结构体A嵌入结构体B,实例化结构体B并返回实例的指针,可以直接转换成接口I类型。于是自己做了一个小测试,具体代码如下。请问这是什么原理,如果有相关内存模型说明就更好了。

package main

import "fmt"

var ctx TestInt

// TestInt is an interface
type TestInt interface {
    func1()
    func2()
    func3()
}

func (*emptyCtx) func1() {
    fmt.Println("func1")
}

func (*emptyCtx) func2() {
    fmt.Println("func2")
}

func (*emptyCtx) func3() {
    fmt.Println("func3")
}

type emptyCtx int

var (
    background = new(emptyCtx)
)

// Background is a function
func Background() TestInt {
    return background
}

// Struct1 is a struct
type Struct1 struct {
    TestInt
    str1 string
}

// Struct2 is a struct
type Struct2 struct {
    Struct1
    str2 string
}

func newStruct1(parent TestInt) Struct1 {
    return Struct1{
        TestInt: parent,
        str1:    "test1",
    }
}

// NewStruct2 is a function
func NewStruct2(parent TestInt) TestInt {

    return &Struct2{
        Struct1: newStruct1(parent),
        str2:    "test2",
    }
}

func main() {

    ctx := Background()
    ctx = NewStruct2(ctx)

    ctx.func1()
    ctx.func2()
    ctx.func3()
}

  • 写回答

2条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-07-24 22:49
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    这个问题涉及到了嵌入结构体的方式和接口的转换。具体来说,结构体A嵌入接口I,然后结构体A再被结构体B嵌入。通过这样的方式,实例化结构体B并返回实例的指针时,可以直接转换成接口I类型。 在代码中,定义了一个接口TestInt,包含了三个方法func1、func2和func3。然后定义了一个结构体emptyCtx,实现了TestInt接口的所有方法。 接着定义了两个结构体Struct1和Struct2,其中Struct1包含了TestInt接口和一个字符串字段str1,而Struct2包含了Struct1和一个字符串字段str2。 在函数newStruct1中,返回了一个新实例化的Struct1结构体,其中的TestInt接口是传入的parent参数。 在函数NewStruct2中,返回了一个新实例化的Struct2结构体的指针,其中的Struct1是通过调用newStruct1函数得到的,而TestInt接口是传入的parent参数。 在main函数中,首先通过调用Background函数获取一个TestInt接口实例ctx。然后调用NewStruct2函数,将ctx作为参数传入,得到一个新的TestInt接口实例。最后通过调用ctx的func1、func2和func3方法,可以看到输出对应的字符串。 这个原理是通过结构体嵌入和接口转换的方式,实现了接口的组合和实例的类型转换。具体的内存模型说明可以参考Go语言的规范和源码,涉及到了结构体、接口、指针等相关的内存布局和转换。 如果需要进一步了解这方面的知识,可以参考Go语言官方文档中有关结构体、接口和类型转换的相关章节,以及深入学习Go语言的内存模型和数据结构的相关知识。
    评论

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵