儘管型別相同,Go 型別轉換仍可能失敗。類型轉換是在不同資料型別之間進行轉換的過程,但在Go語言中,即使兩個型別看起來相同,也不能保證轉換一定會成功。這是因為Go語言對類型的嚴格檢查,要求轉換的類型必須完全匹配,包括類型名稱、結構和方法等。因此,開發者在進行類型轉換時,一定要謹慎並遵循Go語言的類型規則,以避免轉換失敗的情況。
我使用 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" } }
註解:
pgx
和 pgconn
套件位於同一項目內,因此它們不會傳回具有相同名稱的類型的不同版本。換句話說,我的 go.mod 中只有一個導入。 *pgconn.pgerror
。 您已經解決了自己的問題,但這裡有一些可能有用的背景,以及我如何找到來源。
同一個程式中可以存在同名的包,只要它們有不同的導入路徑即可。例如,標準函式庫既有math/rand
,也有crypto/rand
,分別稱為r和
。這是 *pgconn.PgError
和 *pgconn.PgError
不同的第一個提示:它們來自不同的導入路徑。
當 Go 中的模組進行主要修訂時,它們應該更改其導入小路。這是為了保持導入路徑的向後相容性。請注意,這通常是透過更新 go.mod
檔案中的 module
宣告來完成的,而不是實際將程式碼移到子目錄中。例如,請參閱此 提交,其中 pgx
從 v4
碰撞到 v5
。這是第二個提示:來自 pgx
專案的程式碼可以在多個導入路徑下使用(由於多個主要版本)。
考慮到這一背景,我使用 git 標籤來查看最新的 v4.x.x
發布。我注意到奇怪的是,pgconn
套件在 v4
中不存在。這似乎排除了 github.com/jackc/pgx/v4/pgconn
與 github.com/jackc/pgx/v5/pgconn
衝突的想法。然後我在 Google 上搜尋「pgconn」並找到了 github.com/jackc/pgconn
儲存庫,我在自述文件中看到:
該版本與 pgx v4 一起使用。在 pgx v5 中,它是 https://www.php.cn/link/a0fb5dd4b80c7e9411ba9667315d20c3 儲存庫的一部分。
從您提供的其他資訊來看,您的錯誤可能是使用了導入路徑 "github.com/jackc/pgx/pgconn"
。如pgx
的範例程式碼所示,您應該用於基本模組的目前導入路徑是"github.com/jackc/pgx/v5"
,並且其中的套件將被類似地指定,例如"github .com/jackc/pgx/v5/pgconn"
。
以上是儘管類型相同,Go 類型轉換仍失敗的詳細內容。更多資訊請關注PHP中文網其他相關文章!