在包之间使用相同结构的类型断言

Type Assertion using identical structs between packages

我很难理解 Go 中的某些类型断言以及为什么下面的代码不起作用并导致恐慌。

panic: interface conversion: interface {} is []db.job, not []main.job

主要:

/*stackTypeAssert.go
> panic: interface conversion: interface {} is []db.job, not []main.job
*/

package main

import (
    "fmt"
    "stackTypeAssert/db"
)

type job struct {
    ID     int
    Status string
}

type jobs interface{}

func main() {
    jobTable := db.GetJobs()
    fmt.Println(jobTable) // This works: [{1 pending} {2 pending}]

    //Type Assertion
    var temp []job
    //panic: interface conversion: interface {} is []db.job, not []main.job
    temp = jobTable.([]job)
    fmt.Println(temp)
}

包数据库:

/*Package db ...
panic: interface conversion: interface {} is []db.job, not []main.job
*/
package db

//GetJobs ...
func GetJobs() interface{} {
    //Job ...
    type job struct {
        ID     int
        Status string
    }
    task := &job{}
    var jobTable []job
    for i := 1; i < 3; i++ {
        *task = job{i, "pending"}
        jobTable = append(jobTable, *task)
    }
    return jobTable
}

Import declarations 的 go lang 规范中描述为:-

The PackageName is used in qualified identifiers to access exported identifiers of the package within the importing source file. It is declared in the file block. If the PackageName is omitted, it defaults to the identifier specified in the package clause of the imported package. If an explicit period (.) appears instead of a name, all the package's exported identifiers declared in that package's package block will be declared in the importing source file's file block and must be accessed without a qualifier.

如错误所述:-

panic: interface conversion: interface {} is []db.job, not []main.job

您应该使用 db 包的结构,将其导入 main 中以创建临时变量,因为返回值是包装结构 db.jobs 而不是 main.jobs[= 的接口23=]

package main

import (
    "fmt"
    "stackTypeAssert/db"
)

type job struct {
    ID     int
    Status string
}

type jobs interface{}

func main() {
    jobTable := db.GetJobs()
    fmt.Println(jobTable) // This works: [{1 pending} {2 pending}]

    // create a temp variable of []db.Job type
    var temp []db.Job
    // get the value of interface returned from `GetJobs` function in db package and then use type assertion to get the underlying slice of `db.Job` struct.
    temp = jobTable.(interface{}).([]db.Job)
    fmt.Println(temp)
}

db 包文件中定义 GetJobs() 函数外部的结构,并通过将结构转换为 uppercase.

使其可导出
package db
// make it exportable by converting the name of struct to uppercase
type Job struct {
    ID     int
    Status string
}

//GetJobs ...
func GetJobs() interface{} {
    task := &Job{}
    var jobTable []Job
    for i := 1; i < 3; i++ {
        *task = Job{i, "pending"}
        jobTable = append(jobTable, *task)
    }
    return jobTable
}

输出

[{1 pending} {2 pending}]
[{1 pending} {2 pending}]

有关导出标识符的更多信息,您可以查看此link