我很难理解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
}
答案 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