在包之间使用相同的结构进行类型声明

时间:2018-07-06 08:51:20

标签: go struct interface type-assertion

我很难理解Go中的某些类型断言,以及为什么以下代码无法正常工作并导致恐慌。

  

应急:接口转换:接口{}是[] db.job,而不是[] 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
}

1 个答案:

答案 0 :(得分:3)

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

  

PackageName用于合格的标识符中以访问导出的   导入源文件中软件包的标识符。它是   在文件块中声明。如果省略PackageName,则默认   到导入的package子句中指定的标识符   包。如果出现显式句点(。)而不是名称,则所有   在该软件包的软件包中声明的软件包的导出标识符   块将在导入源文件的文件块中声明,然后   必须在没有限定符的情况下访问。

错误显示:-

  

应急:接口转换:接口{}是[] db.job,而不是[] main.job

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

的接口
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}]

有关导出的标识符的更多信息,您可以检查此链接Exported functions from another package