Home >Backend Development >Golang >Go type conversion fails despite having the same type

Go type conversion fails despite having the same type

WBOY
WBOYforward
2024-02-13 16:45:081071browse

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

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.

Question content

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:

    The
  1. 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.
  2. The return value is not zero.
  3. The debugger shows that the type is *pgconn.pgerror.

SOLUTION

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 https://www.php.cn/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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete