Go 如何解析看似相同的类型?

S_p*_*Xru -1 sql postgresql uuid types go

我有一个 PostgreSQL 数据库,有 2 列:id (UUID)、company_url (varchar),具有以下值:

2fc35af4-5f5c-445e-86c5-01d93513b8be | https://test.com
2bf31b75-d1f3-4a9c-a530-73b714816e9e | https://test2.com
Run Code Online (Sandbox Code Playgroud)

以下是使用 Go 访问表的代码(为简单起见,省略了错误处理和凭据):

package main

import (
    "fmt"
    "database/sql"
    "github.com/google/uuid"
    _ "github.com/lib/pq"
)

func main() {
    connStr := "host= password= port= dbname= user="
    db, _ := sql.Open("postgres", connStr)
    rows, _ := db.Query("SELECT * FROM companies;")

    for rows.Next() {
        // var id [16]byte // not ok
        var id uuid.UUID // ok
        var companyURL string

        rows.Scan(&id, &companyURL)
        fmt.Println(id, companyURL)
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个用于UUID的 Go 包。在其源代码中,UUID 简单地定义为

type UUID [16]byte
Run Code Online (Sandbox Code Playgroud)

在上面的代码中, id是使用 键入的uuid.UUID,我尝试替换上面代码中的类型声明(用 注释掉not ok),但它返回的不是正确的值,而是一个包含 16 个零的数组。uuid.UUID返回正确的 id。

uuid.UUID所以我的问题是,如果和[16]byte是同一类型,为什么会出现这种行为?uuid 包和函数中没有二进制文件init(),也没有Scan()进行任何隐式更改。

ber*_*eal 5

严格来说,它们不是同一类型。但它们具有相同的基础类型UUID不同之处在于它实现了接口sql.Scannerdriver.Valuer,因此它可以透明地与数据库一起使用。