Как я могу вызвать dbmap.Insert (interface {}) из другой функции? - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть куча очень похожих структур (в данном примере A и B), экземпляры которых я хочу обработать в некоторой функции (в примере f()), а затем вставить их в мою базу данных. Я подумал, что могу как-то справиться с пустым интерфейсом, но, похоже, это не решение, так как я получаю сообщение об ошибке:

i: &{{6 2019-04-03 15:11:37.822100431 +0200 CEST m=+0.001291882} 7} *main.A
2019/04/03 15:11:37 Insert i no table found for type: 
exit status 1

Я попытался создать минимальный, но исполняемый пример:

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/mattn/go-sqlite3"
    gorp "gopkg.in/gorp.v2"
    "log"
    "time"
)

type Meta struct {
    Id        int
    CreatedAt time.Time
}

type A struct {
    Meta
    Value int
}

type B struct {
    Meta
    Value string
}

var dbmap *gorp.DbMap

func f(i interface{}) {
    fmt.Printf("i: %v %T\n", i, i)

    err := dbmap.Insert(&i)
    checkErr(err, "Insert i")
}

func main() {
    Init()

    a := A{Meta: Meta{CreatedAt: time.Now()}, Value: 7}
    b := B{Meta: Meta{CreatedAt: time.Now()}, Value: "seven"}

    err := dbmap.Insert(&a)    // works
    checkErr(err, "Insert a")

    err = dbmap.Insert(&b)     // works
    checkErr(err, "Insert b")

    f(&a) // fails
}

func Init() {
    db, err := sql.Open("sqlite3", "/tmp/post_db.bin")
    checkErr(err, "sql.Open failed")
    dbmap = &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
    dbmap.AddTableWithName(A{}, "As").SetKeys(true, "Id")
    dbmap.AddTableWithName(B{}, "Bs").SetKeys(true, "Id")
    err = dbmap.CreateTablesIfNotExists()
    checkErr(err, "Couldn't create tables")
}

func checkErr(err error, msg string) {
    if err != nil {
        log.Fatalln(msg, err)
    }
}

Какой правильный способ сделать это? В C ++ я бы просто использовал шаблоны;)

1 Ответ

1 голос
/ 04 апреля 2019

Если вы называете вас func как f(&a).Вы должны вызывать внутри func f просто dbmap.Insert(i), потому что ваше значение уже является указателем.Так что ваш func будет выглядеть как

func f(i interface{}) {
    fmt.Printf("i: %v %T\n", i, i)

    err := dbmap.Insert(i)
    checkErr(err, "Insert i")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...