Monkey patching instance in Go

huangapple go评论85阅读模式
英文:

Monkey patching instance in Go

问题

我有一个包含一些字段的结构体,并且我将该结构体进行编组并返回给客户端的 JSON。我不能改变 JSON 或结构体,但在某些特殊情况下,我需要添加一个额外的标志。在 Go 中是否可以进行实例的猴子补丁,并且如何实现呢?
我可以通过继承来解决这个问题,但我很想知道在 Go 中是否可以动态地向结构体实例添加属性。

英文:

I have structure with some fields inside and I Marshall that structure and return json to client. I cannot change json nor structure but in some corner cases I have to add one more additional flag. Is possible instance monkey patching in Go and how to achieve that ?
I can solve this through inheritance but I would love to see if dynamically adding property to instance of structure is possible in Go.

答案1

得分: 4

不,你不能在Go语言中像那样进行猴子补丁。结构体在编译时被定义,你不能在运行时添加字段。

我可以通过继承来解决这个问题(...)

不,你不能这样做,因为Go语言中没有继承。你可以通过组合来解决:

type FooWithFlag struct {
    Foo
    Flag bool
}
英文:

No, you can't monkeypatch things like that in Go. Structs are defined at compile time, you can't add fields at runtime.

>I can solve this through inheritance (…)

No you can't because there is no inheritance in Go. You can solve it through composition:

type FooWithFlag struct {
    Foo
    Flag bool
}

答案2

得分: 2

你可以始终定义一个自定义的Marshaler / Unmarshaler接口,并在你的类型中处理它:

type X struct {
    b bool
}

func (x *X) MarshalJSON() ([]byte, error) {
    out := map[string]interface{}{
        "b": x.b,
    }
    if x.b {
        out["other-custom-field"] = "42"
    }
    return json.Marshal(out)
}

func (x *X) UnmarshalJSON(b []byte) (err error) {
    var m map[string]interface{}
    if err = json.Unmarshal(b, &m); err != nil {
        return
    }
    x.b, _ = m["b"].(bool)
    if x.b {
        if v, ok := m["other-custom-field"].(string); ok {
            log.Printf("got a super secret value: %s", v)
        }
    }
    return
}

playground

英文:

You can always define a custom Marshaler / Unmarshaler interface and handle it in your type:

type X struct {
	b bool
}

func (x *X) MarshalJSON() ([]byte, error) {
	out := map[string]interface{}{
		"b": x.b,
	}
	if x.b {
		out["other-custom-field"] = "42"
	}
	return json.Marshal(out)
}

func (x *X) UnmarshalJSON(b []byte) (err error) {
	var m map[string]interface{}
	if err = json.Unmarshal(b, &m); err != nil {
		return
	}
	x.b, _ = m["b"].(bool)
	if x.b {
		if v, ok := m["other-custom-field"].(string); ok {
			log.Printf("got a super secret value: %s", v)
		}
	}
	return
}

<kbd>playground</kbd>

答案3

得分: 0

你也可以在标志上使用json:",omitempty"选项。

一个例子:

http://play.golang.org/p/ebmZLR8DLj

英文:

you could also use the json:&quot;,omitempty&quot; option on your flag

an example:

http://play.golang.org/p/ebmZLR8DLj

huangapple
  • 本文由 发表于 2015年7月3日 16:12:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/31201822.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定