dqhnp44220 2016-03-10 21:51
浏览 36
已采纳

如何通过嵌入式接口嵌入结构值:可组合结构

This question is best described by an example

http://play.golang.org/p/bQuRr0kV-b

I am trying to make a composable struct. In this example, I want to have a Person type with embedded values from either Female or Male. If I were just dealing with structs, I would embed them like this

type Person Struct{
  Female
  Male
}

I cannot do this however, both because in the actual project, there are a lot of embedded structs and I would prefer to keep the struct clean and composable. But there is also a naming conflict — in this example, both Male and Female contain the field 'Eyes'. Moving the conflicting value to the Person struct is not a viable solution (as many of the other embedded structs do not contain that particular value).

I was hoping to pass these values via a simple interface. Sample Below: When running this code, I get &{Name: Age:0 Type:male GenderType:0x10434120} where GenderType is the pointer to Male struct(in this case). My Goal is to have a flat structure returned that would look like &{Name: Age:0 Type:male Eyes: ChestSize:0}

package main

import "fmt"

type Person struct {
    Name string
    Age  int
    Type string
    GenderType 
}

type GenderType interface {
    TypeName() string
}

type Male struct {
    Eyes     string
    ChestSize int
}

type Female struct {
    Eyes string
    BustSize int
}

func (m *Male) TypeName() string {
    return "male"
}

func (f *Female) TypeName() string {
    return "female"
}

func main() {

    d := NewHuman(new(Male))
    fmt.Printf("%+v", d)
}

func NewHuman(gt GenderType) *Person {
    return &Person{
        Type: gt.TypeName(),
        GenderType: gt,

    }
}
  • 写回答

1条回答 默认 最新

  • dongqie7806 2016-03-10 22:54
    关注

    I don't think it is possible to do this in a flat structure because it would entail changing the memory structure of the struct type during runtime, which go doesn't allow. While you can access embedded fields using GenderType, it's still allowed because you are saying that this will be a reference to an embedded struct that satisfies the interface rather than changing the structure of the struct itself.

    I think the better way to marshal into a flat json using this is to keep your embedded structure, but then make the Person struct a Marshaler

    You can add your own custom MarshalJSON() (byte[],error) method and use this to make a flat json output.

    If you need specialized unmarshaling, then you can do likewise with an (UnmarshalJSON([]byte) error) method tied to Person.

    see https://golang.org/pkg/encoding/json/#Marshaler for further reference

    Here is a playground that shows what I mean: https://play.golang.org/p/qOl9WSaI3O

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了
  • ¥100 H5网页如何调用微信扫一扫功能?
  • ¥15 讲解电路图,付费求解
  • ¥15 有偿请教计算电磁学的问题涉及到空间中时域UTD和FDTD算法结合的
  • ¥15 three.js添加后处理以后模型锯齿化严重