【问题标题】:Returned interface{} type assertion返回的 interface{} 类型断言
【发布时间】:2019-09-02 21:06:15
【问题描述】:

我需要查询数据库的函数。

我使用 github.com/gocraft/dbr,所以我创建了辅助函数:

//SelectData - selects data from database
func SelectData(table, fields, where string, data interface{}) interface{} {

    var ptr reflect.Value

    ptr = reflect.New(reflect.TypeOf(data)) // create new pointer

    obj := ptr.Interface()

    sess := Session

    query := sess.Select(fields).
        From(table)

    if len(where) > 0 {
        query.Where(where)
    }

    _, err := query.Load(obj)

    if err != nil {
        panic(err)
    }

    return obj

}

然后我尝试使用它:

//CheckUser - checks is user registered in db
func CheckUser(userid string) User {
    var user User
    var i interface{}

    i = db.SelectData("users", "*", "", user)

    fmt.Printf("=%#v \n", i)

    user = i.(User)
    return user
}

但我得到运行时错误:

interface conversion: interface {} is *models.User, not models.User
D:/Go/src/runtime/panic.go:513 (0x42ccb6)
        gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
D:/Go/src/runtime/iface.go:248 (0x4091ac)
        panicdottypeE: panic(&TypeAssertionError{iface, have, want, ""})
C:/Users/vasalt/go/src/wcenter/models/model_user.go:29 (0x9dda3a)
        CheckUser: user = i.(User)
C:/Users/vasalt/go/src/wcenter/controllers/ctrl_main.go:59 (0x9e03b6)
        SetPageData: fmt.Printf("=result = %#v\n", models.CheckUser("1234"))

并调试输出:

=&models.User{UID:sql.NullString{String:"1", Valid:true}, UserID:sql.NullString{String:"1234", Valid:true}, UserGroup:sql.NullString{String:"1", Valid:true}}

所以它成功地从数据库中检索数据,但它返回&models.User 而不仅仅是models.User,我无法弄清楚如何将interface{}*models.User 转换为models.User

【问题讨论】:

  • nope models\model_user.go:29:7: cannot use i.(*User) (type *User) as type User in assignment
  • var user 用户应该是var user *User

标签: go reflection interface


【解决方案1】:

我认为这应该可行。您可以将其类型转换为 *User 并根据您的用例返回 User 值或 *User。

user = i.(*User)
return *user

【讨论】:

  • 谢谢,我只是更改了返回值return i.(*User),一切正常
【解决方案2】:
 ptr = reflect.New(reflect.TypeOf(data)) // 创建新指针

 obj := ptr.Interface()

reflect.New 返回一个 reflect.value,表示一个指向新数据类型实体的指针。ptr.Interface() 返回一个实际值 ptr,其类型为 *data。 所以当你调用i = db.SelectData("users", "*", "", user)时,它会返回*User。你不能使用类型断言i.(User)除了i.(*User)

【讨论】:

    猜你喜欢
    • 2011-10-26
    • 1970-01-01
    • 2020-08-06
    • 2017-07-31
    • 2023-01-08
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    相关资源
    最近更新 更多