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.
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.