2015-10-26 4 views
2

Что такое идиоматический golang способ сбросить структуру в файл csv? Я внутри func, где моя структура передается как интерфейс {}:Запись структуры в файл csv

func decode_and_csv(my_response *http.Response, my_struct interface{}) 

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

пример моих типов:

type Location []struct { 
    Name     string `json: "Name"` 
    Region     string `json: "Region"` 
    Type     string `json: "Type"` 
} 

ответ

8

Было бы намного проще, если вы использовали конкретный тип. Вероятно, вы захотите использовать пакет encoding/csv, вот пример. https://golang.org/pkg/encoding/csv/#example_Writer

Как вы можете видеть, метод Write ожидает []string так, чтобы произвести это, вы должны будете либо 1) обеспечивают вспомогательный метод или 2) отражают my_struct. Лично я предпочитаю первый метод, но это зависит от ваших потребностей. Если вы хотите перейти по маршруту два, вы можете получить все поля в структуре, используя их в качестве заголовков столбцов, а затем итерации полей, получающих значение для каждого, используйте append в этом цикле, чтобы добавить их в []string, а затем передать их Write вне стороны петли.

Для первого варианта я бы определил ToSlice или что-то на каждом типе, а затем я бы назвал его CsvAble, которому нужен метод ToSlice. Измените тип в методе my_struct CsvAble вместо использования пустого интерфейса, а затем вы можете просто позвонить ToSlice по адресу my_struct и передать возвращаемое значение в Write. Возможно, вы также вернете заголовки столбцов (это означает, что вы вернетесь к [][]string и должны выполнить итерацию внешнего измерения, проходящего каждый []string, до Write), или вам может потребоваться другой метод для удовлетворения интерфейса, такого как GetHeaders, который возвращает []string, который является заголовки столбцов. Если это так, ваш код будет выглядеть примерно так:

w := csv.NewWriter(os.Stdout) 
headers := my_struct.GetHeaders() 
values := my_struct.ToSlice() 
if err := w.Write(headers); err != nil { 
    //write failed do something 
} 
if err := w.Write(values); err != nil { 
    //write failed do something 
} 

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

Смежные вопросы