Go语言类型转换失败,尽管类型相同

niwlg2el  于 2023-02-17  发布在  Go
关注(0)|答案(2)|浏览(336)

我正在使用jackc/pgx驱动程序以及GORM库来与PostgreSQL数据库接口。
我有一个示例,我必须检查PostgreSQL错误代码并以不同的方式处理特定的错误类型。当使用pgx驱动程序时,GORM方法返回*pgconn.PgError类型作为error,其中包含一个带有特定错误代码的字段。
为了访问该字段,我必须将error强制转换为*pgconn.PgError,但由于某种原因,这失败了:

res := tx.Take(&f, "id = ?", id)
if res.Error != nil {
    if pqErr, ok := res.Error.(*pgconn.PgError); ok {
        // does not reach here
    } else {
        fmt.Printf("Error type: %T\n", res.Error)
        // Output: "Error type: *pgconn.PgError"
    }
}

注:

  1. pgxpgconn包在同一个项目中,所以它们不会返回同名类型的不同版本,换句话说,我在go.mod中只有一个import。
    1.返回值不为空。
    1.调试器显示该类型为*pgconn.PgError
i34xakig

i34xakig1#

你已经解决了你自己的问题,但这里有一些可能有用的背景,以及我是如何找到来源的。
相同名称的包可以存在于同一个程序中,只要它们具有不同的导入路径。例如,标准库具有math/randcrypto/rand,每个都称为rand。这是*pgconn.PgError*pgconn.PgError如何不同的第一个提示:它们来自不同的进口途径。
当Go语言中的模块生成major revisions时,它们应该修改它们的导入路径,这是为了保持导入路径的向后兼容性。注意,这通常是通过更新go.mod文件中的module声明来实现的,而不是将代码移动到子目录中。例如,请看这个提交,其中pgxv4迁移到v5。这是第二个提示:来自pgx项目的代码在多个导入路径下可用(由于多个主要版本)。
有了这样的背景,我使用git标签查看了最新的v4.x.xrelease版本的存储库,我注意到奇怪的是,v4中并不存在pgconn包,这似乎排除了github.com/jackc/pgx/v4/pgconngithub.com/jackc/pgx/v5/pgconn冲突的可能性,然后我在Google上搜索“pgconn”,找到了github.com/jackc/pgconn存储库,我在自述文件中看到:
此版本与pgx v4一起使用。在pgx v5中,它是https://github.com/jackc/pgx存储库的一部分。
根据您提供的其他信息,您的错误可能是使用了导入路径"github.com/jackc/pgx/pgconn",如pgx的示例代码所示,基本模块当前应使用的导入路径是"github.com/jackc/pgx/v5",其中的包也将以类似的方式指定,例如"github.com/jackc/pgx/v5/pgconn"

ecfdbz9o

ecfdbz9o2#

正如@HymnsForDisco在注解中正确指出的那样,github.com/jackc/pgconngithub.com/jackc/pgx/pgconn都存在,结果返回的错误来自前者,而我在代码中导入的是后者。
为了确认,我添加了以下行:

fmt.Println("Error path: ", reflect.TypeOf(res.Error).Elem().PkgPath())
// Output: "Error path:  github.com/jackc/pgconn"

将导入更改为“github.com/jackc/pgconn“解决了问题。

相关问题