Как преобразовать 2d-фрагмент интерфейса в структуру

#go

# #Вперед

Вопрос:

Я хочу получить все строки из API Google sheets. Он возвращает данные с типом
[][]interface{} .

Моя структура такова

 type Record struct {
    Name string `json:"firstname"`
    Mobile    string `json:"mobile"`
}
 

Я хотел бы поместить все строки в фрагмент структуры []Record , где каждое поле представляет собой ячейку на листе Excel.

Пожалуйста, ознакомьтесь с приведенным ниже кодом для моей попытки:

 package main

import (
    "encoding/json"
    "fmt"
    "log"
)
func main() {
    srv err := InitialiseSheets()
    fmt.Println("")
    if err != nil {
        log.Fatalf("Unable to retrieve data from sheet: %v", err)
    }

    spreadsheetId := "1VoMAKHSnB6nptPnQqabMlKWraxWolYgPBxRo-thwmgk"
    readRange := "A:B"
    resp, err := srv.Spreadsheets.Values.Get(spreadsheetId, readRange).Do()

    if err != nil {
        log.Fatalf("Unable to retrieve data from sheet: %v", err)
    }

    var records []Record = make([]Record, len(resp.Values))

    byt, err := resp.MarshalJSON()
    var dat map[string]interface{}

    if err = json.Unmarshal(byt, amp;dat); err != nil {
        panic(err)
    }

    for key, value := range dat {
        switch key {
        case "values":
            switch vv := value.(type) {
            case []interface{}:
                for i, u := range vv {
                    switch r := u.(type) {
                    case interface{}:
            records[i].Name = r.([]interface{})[0].(string)
                        records[i].Mobile = r.([]interface{})[1].(string)
                        // [Daniel Webster 425255565]
                        fmt.Println("kk.([]interface{})", r.([]interface{}))
                        // [Daniel Webster]
                        fmt.Println("kk.([]interface{})[0]", r.([]interface{})[0])

                    }
                }
            }
        }
    }
}
 

Я уверен, что делать что-то подобное records[i].Mobile = r.([]interface{})[1].(string) — неподходящий способ сделать это, не знаю, как я вообще до этого додумался. Каков наилучший способ в Go сделать то, чего я пытаюсь достичь?

Если вы хотите запустить этот код, сначала настройте аутентификацию следующим образом: https://developers.google.com/sheets/api/quickstart/go и вы можете скопировать / вставить мой код.

Комментарии:

1. Как выглядят возвращаемые данные? Все, что возвращается resp.MarshalJSON()

2. @Ibu возвращает фрагмент байта. в частности godoc.org/google.golang.org/api/sheets /…

3. вы можете сделать что-то вроде fmt.Printf("%s",string(byt)) просмотра фактического содержимого, чтобы вы могли правильно использовать возвращенные данные, а не использовать интерфейс.

4. Чтобы правильно понять вашу ситуацию, можете ли вы предоставить образец электронной таблицы?

5. @Tanaike спасибо! работает хорошо, рад принять ваш ответ!

Ответ №1:

Как насчет этой модификации? В этом случае значения непосредственно переносятся из resp.Values в records .

Измененный сценарий:

 func main() {
    srv err := InitialiseSheets()
    fmt.Println("")
    if err != nil {
        log.Fatalf("Unable to retrieve data from sheet: %v", err)
    }

    spreadsheetId := "1VoMAKHSnB6nptPnQqabMlKWraxWolYgPBxRo-thwmgk"
    readRange := "A:B"
    resp, err := srv.Spreadsheets.Values.Get(spreadsheetId, readRange).Do()

    if err != nil {
        log.Fatalf("Unable to retrieve data from sheet: %v", err)
    }

    var records []Record = make([]Record, len(resp.Values))

    // Below script was modified.
    for i, row := range resp.Values {
        records[i].Name = row[0].(string)
        records[i].Mobile = row[1].(string)
    }

    // do something

}