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

huangapple go评论91阅读模式
英文:

How does Go resolve seemingly same types?

问题

我有一个包含两列的PostgreSQL数据库:id(UUID)和company_url(varchar),具有以下值:

2fc35af4-5f5c-445e-86c5-01d93513b8be | https://test.com
2bf31b75-d1f3-4a9c-a530-73b714816e9e | https://test2.com

以下是使用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)
    }
}

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

type UUID [16]byte

在上面的代码中,id使用uuid.UUID进行了类型声明。我尝试在上面的代码中替换类型声明(使用not ok注释掉的部分),但返回的不是正确的值,而是一个由16个零组成的数组。而uuid.UUID返回正确的id。

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

英文:

I have a PostgreSQL database with 2 columns: id (UUID), company_url (varchar) with following values:

2fc35af4-5f5c-445e-86c5-01d93513b8be | https://test.com
2bf31b75-d1f3-4a9c-a530-73b714816e9e | https://test2.com

Here's the code to access the table using Go (error handling and credentials omited for simplicity):

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)
	}
}

There also exists a Go package for UUIDs. In its' source code the UUID is defined simply as

type UUID [16]byte

In the code above the id is typed using uuid.UUID, I tried to replace the type declaration in my code above (commented out with not ok) but instead of the correct value it returns an array of 16 zeroes. uuid.UUID returns correct id.

So my question is why such behaviour if uuid.UUID and [16]byte are of the same types? There are no binaries in uuid package nor init() function, nor is Scan() making any implicit changes.

答案1

得分: 5

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

英文:

Strictly speaking, they are not the same types. They have the same underlying type though. UUID is different in that it implements the interfaces sql.Scanner and driver.Valuer, so it can be used with the databases transparently.

huangapple
  • 本文由 发表于 2022年11月16日 23:29:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/74463141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定