не экспортируемые поля при расширении структуры из другого пакета

Я использую 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 заставляет вас хранить все файлы пакета в одной папке.

  1. Верно ли, что в go просто невозможно расширить функциональность пакета, если разработчик решил не экспортировать поля структуры? (Я вижу причину, по которой можно было бы это сделать, с другой стороны, я хотел бы это сделать, поскольку это «всего лишь» игрушечный пример :))

  2. Если это возможно, то как лучше всего это сделать?


person Retozi    schedule 14.02.2014    source источник


Ответы (1)


Это то же самое на всех языках, частные поля недоступны за пределами их области.

При этом, если у вас уже есть интерфейс, почему бы не использовать стандартную библиотеку JSON, в которой есть маршал функция, которая принимает интерфейс напрямую, без необходимости установки в поле.

package main

import (
    "encoding/json"
)

func main() {
    v := ....
    jsonBytes, err := json.Marshal(v)
}
person Usman Ismail    schedule 14.02.2014
comment
дело в том, что я хотел бы использовать удобные методы, которые реализует go-simplejson, такие как Get и GetPath и так далее. Я исхожу из фона Python, поэтому я привык перегружать и исправлять вещи из других пакетов. И я чувствую, что очень важно запретить доступ к неэкспортируемым полям, даже если вы делаете Go-эквивалент наследования в структуре. Если это так, я приму это, но я должен быть уверен :) - person Retozi; 15.02.2014