我想在导出结构中使用的嵌套导出结构中添加一个方法。
我有一个ldap.Search().Entries返回的[]*ldap.Entry
类型
ldap.Entry
类型由Attributes []*EntryAttribute
组成。我的目标是在ldap.EntryAttribute
中添加一个额外的方法,例如MarshalJSON
我可以直接在ldap
包中添加一个额外的代码,它将按预期工作。但这是一种肮脏的方式:
// EntryAttribute holds a single attribute
type newEntryAttribute struct {
// Name is the name of the attribute
Name string
// Values contain the string values of the attribute
Values []string
// ByteValues contain the raw values of the attribute
ByteValues [][]byte
}
// Print outputs a human-readable description
func (e EntryAttribute) MarshalJSON() ([]byte, error) {
b := newEntryAttribute(e)
b.ByteValues = nil
return json.Marshal(b)
}
我该如何以更优雅的方式做到这一点?
答案 0 :(得分:1)
最接近的方法是根据您自己的类型创建方法,该方法将嵌入EntryAttribute类型。像这样:
package mine
import "github.com/go-ldap/ldap""
type EntryAttribute {
ldap.EntryAttribute
}
func (e EntryAttribute) MarshalJSON() ([]byte, error) {
// ...
}
但是,在程序中的任何地方,您必须使用您的类型,而不是原始类型。
答案 1 :(得分:-1)
到目前为止,我已经找到以下解决方案。它不优雅,但不需要修改程序包。
type myEntry struct {
*ldap.Entry
Attributes []*myEntryAttribute
}
type myEntryAttribute struct {
*ldap.EntryAttribute
}
func (a *myEntryAttribute) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Name string
Values []string
}{Name: a.Name, Values: a.Values})
}
func ldapEntry2myEntry(t interface{}) interface{} {
switch e := t.(type) {
case []*ldap.Entry:
var res []interface{}
for _, v := range e {
res = append(res, ldapEntry2myEntry(v))
}
return res
case *ldap.Entry:
var att []*myEntryAttribute
for _, a := range e.Attributes {
att = append(att, &myEntryAttribute{a})
}
return &myEntry{e, att}
}
return nil
}
... ... ...
data, err := json.Marshal(ldapEntry2myEntry(sr.Entries))
if err != nil {
log.Fatal("error")
}
fmt.Printf("%s\n", data)
// or only one element
data, err := json.Marshal(ldapEntry2myEntry(sr.Entries[0]))
if err != nil {
log.Fatal("error")
}
fmt.Printf("%s\n", data)