Go type conversion can fail despite having the same type. Type conversion is the process of converting between different data types, but in Go language, even if two types look the same, there is no guarantee that the conversion will be successful. This is because the Go language's strict type checking requires that the converted types must match exactly, including type names, structures, methods, etc. Therefore, developers must be careful and follow the type rules of the Go language when performing type conversion to avoid conversion failures.
I use jackc/pgx driver and gorm library to interact with postgresql database.
I have an instance where I have to check postgresql error codes and handle a certain error type differently. When using the pgx
driver, the gorm methods return the *pgconn.pgerror
type as error
, which contains a field with the specific error code.
In order to access the field I have to convert error
to *pgconn.pgerror
, but for some reason this fails:
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" } }
Comments:
pgx
and pgconn
packages are within the same project, so they do not return different versions of types with the same name. In other words, I only have one import in my go.mod. *pgconn.pgerror
. You've already solved your own problem, but here's some background that might be helpful, and how I found the source.
Packages with the same name can exist in the same program, as long as they have different import paths. For example, the standard library has both math/rand
and crypto/rand
, which are called r and
respectively. This is the first hint that *pgconn.PgError
and *pgconn.PgError
are different: they come from different import paths.
When modules in Go undergo major revisions, they should change their import paths. This is to maintain backward compatibility of import paths. Note that this is usually done by updating the module
declaration in the go.mod
file, rather than actually moving the code into the subdirectory. For example, see this Commit where pgx
collides from v4
to v5
. Here's the second tip: code from the pgx
project can be used under multiple import paths (due to multiple major versions).
With this background in mind, I used the git tag to view the latest v4.x.x
release. I noticed strangely that the pgconn
package does not exist in v4
. This seems to rule out the idea that github.com/jackc/pgx/v4/pgconn
conflicts with github.com/jackc/pgx/v5/pgconn
. Then I searched Google for "pgconn" and found the github.com/jackc/pgconn
repository, where I saw in the readme:
This version is used with pgx v4. In pgx v5, it is part of the //m.sbmmt.com/link/a0fb5dd4b80c7e9411ba9667315d20c3 repository.
Judging from the other information you provided, your error may be using the import path "github.com/jackc/pgx/pgconn"
. As shown in the example code for pgx
, the current import path you should use for the base module is "github.com/jackc/pgx/v5"
, and the packages within it will be like Specify it locally, for example "github .com/jackc/pgx/v5/pgconn"
.
The above is the detailed content of Go type conversion fails despite having the same type. For more information, please follow other related articles on the PHP Chinese website!