无法根据Golang中的条件将接口转换为结构



我在这里添加了两个结构,如下所述,我正在尝试创建一个通用函数,在其中我将结构名称作为字符串传递。我最近开始研究围棋。

type UserDetail struct {
FirstName string 
LastName  string 
Email     string 
User      int
ReportsTo int
}
type Matter struct {
ID        int 
Name      string 
Active    bool 
CreatedAt time.Time
UpdatedAt time.Time
UserID    int
}

在下方添加了函数片段

func Testing(model string) {
var temp interface{}
if model == "UserDetail" {
fmt.Println("Enterr...")
temp = UserDetail{}
}
temp.FirstName = "Dev"
temp.Email = "dev@gmail.com"
fmt.Println(temp) // {"", "", "", 0, 0}
}

我将函数称为Testing("UserDetail")

我用结构名称作为字符串调用函数,在函数定义中,基于结构名称,我通过转换空接口来创建所需的结构实例。在创建空的struct实例后,如果我试图向它添加任何字段值,并尝试打印变量,它会给我一个错误,说:

prog.go:33:6: temp.FirstName undefined (type I is interface with no methods)
prog.go:34:6: temp.Email undefined (type I is interface with no methods)

如果我不更新变量字段,它将使用默认值打印变量。我的主要动机是根据条件将接口转换为结构,并在函数中使用转换后的变量。

您需要从接口中获得底层的具体值,然后才能最终修改其属性。

在golang中,有一种叫做类型断言的东西,它用于从接口变量中获取具体值。

类型断言提供对接口值的底层具体值的访问。

用法示例:

tempConcreteValue := temp.(UserDetail)
tempConcreteValue.FirstName = "Dev"
tempConcreteValue.Email = "dev@gmail.com"
fmt.Println(tempConcreteValue) // {"", "", "", 0, 0}

正如我们在上面的代码中看到的,temp末尾的.(UserDetail)将返回接口temp的具体值,类型为UserDetail

Go从来没有这样工作过。因为go是静态类型的。因此,在编译时,它无法理解temp.FirstName = "Dev"

,因为temp只是一个接口{}(可以包含任何值(。但是,许多特性使它"看起来"是(至少在某种程度上(动态类型化的。您可以通过@xpare选择答案,也可以为每个结构声明一个单独的变量。

您想要为分配给interface{} tempUserDetail结构设置字段值。但该字段属于UserDetail结构,而不属于temp interface{}结构。这就是为什么首先需要从interface{}获取UserDetail结构并设置期望的字段值。还可以使用指针符号来确保将值设置为原始UserDetail结构。然后打印temp interface{}。Go将打印原始值。所以这样使用:

func Testing(model string) {
var temp interface{}
if model == "UserDetail" {
fmt.Println("Enterr...")
temp = &UserDetail{}
}
u := temp.(*UserDetail)
u.FirstName = "Dev"
u.Email = "dev@gmail.com"
//temp = u
fmt.Println(temp) // {"", "", "", 0, 0}
}

编辑

因为你的运动是The objective is that users would define their own structs and call a function similar to the Testing and I would get the data from the correct table in a database and then return the interface filled with data,所以使用这个:

package main
import (
"fmt"
"time"
)
type UserDetail struct {
FirstName string
LastName  string
Email     string
User      int
ReportsTo int
}
type Matter struct {
ID        int
Name      string
Active    bool
CreatedAt time.Time
UpdatedAt time.Time
UserID    int
}
func Testing(model string) interface{} {
var temp interface{}
if model == "UserDetail" {
fmt.Println("Enter for UserDetail...")
temp = &UserDetail{
FirstName: "Dev",
Email: "dev@gmail.com",
}
} else if model == "Matter" {
fmt.Println("Enter for Matter...")
temp = &Matter{
Name: "Joe",
Active: true,
CreatedAt: time.Now(),
}
}
return temp
}
func main() {
var temp interface{}
temp = Testing("UserDetail")
fmt.Println(temp) // {"Dev", "", "dev@gmail.com", 0, 0}
temp = Testing("Matter")
fmt.Println(temp) // {0, "Joe", true, current timestamp, default timestamp, 0}
}

如果你想执行特定类型的代码,我会将Testing函数的参数更改为(model interface{}(,然后创建一个switch语句,如:

switch model.(type) {
case UserDetail:
<code>
case Matter:
<code>
}

最新更新