Я использую go-simplejson в небольшом игрушечном проекте (фактически мой первый проект go). В этом проекте мне нужно расширить пакет simplejson:
simplejson представляет небольшую структуру (с некоторыми полезными методами) с функцией-конструктором:
type Json struct {
data interface{}
}
// NewJson returns a pointer to a new `Json` object
// after unmarshaling `body` bytes
func NewJson(body []byte) (*Json, error) {
j := new(Json)
err := j.UnmarshalJSON(body)
if err != nil {
return nil, err
}
return j, nil
}
В моем проекте я хочу синхронизировать некоторые данные xml с CouchDB. Для этого я хотел бы создать новый конструктор, в котором я передаю декодированный xml (интерфейс типа {}) непосредственно объекту Json, а затем маршалирую его в JSON.
Это тривиально:
func NewJsonFromData(data interface{}) *Json {
return &Json{data}
}
теперь, поскольку это своего рода «хак», я хочу избежать разветвления go-simplejson и реализовать его в go-simplejson, потому что я бы «загрязнял» общий пакет. Я хотел бы сделать это в моем собственном маленьком игрушечном пакете. И вот тут начинается беда:
поле данных не экспортируется и не отображается за пределами пакета... поэтому объявление этой функции в моем другом пакете выглядит так:
func NewJsonFromData(data interface{}) *simplejson.Json {
return &simplejson.Json{data}
}
не работает, выдает следующую ошибку компиляции:
implicit assignment of unexported field 'data' in simplejson.Json literal
также делаю
type Json struct {
simplejson.Json
}
в моем собственном пакете не работает, я не могу установить поле данных в конструкторе моей собственной структуры Json, которая составляет simplejson.Json, так как он не экспортируется (очевидно, он будет работать, если поле будет называться «Данные».
создание файла в моей собственной папке пакета с
package simplejson
не принимается, так как go заставляет вас хранить все файлы пакета в одной папке.
Верно ли, что в go просто невозможно расширить функциональность пакета, если разработчик решил не экспортировать поля структуры? (Я вижу причину, по которой можно было бы это сделать, с другой стороны, я хотел бы это сделать, поскольку это «всего лишь» игрушечный пример :))
Если это возможно, то как лучше всего это сделать?