英文:
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.Scanner
和driver.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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论