我有一个struct Person,它有一个AccessMode类型的uint字段。在Postgres数据库中,AccessMode的数据类型是char(8)。我为AccessMode编写了一个自定义扫描函数,它实现了扫描仪接口。在扫描函数中,它被接收为ASCII字符串的uint8片表示形式。
当AccessMode的数据类型在数据库中更改为varchar(8)时,它将作为扫描函数中的string接收。以下是代码
type Access uint
type Person struct {
AccessMode Access
}
func (a *Access) Scan(val interface{}) error {
if bb, ok := val.([]byte); ok {
return a.UnmarshalText(bb)
}
return errors.New("scan failed: data is not a byte slice")
}为什么在varchar和uint切片的情况下被接收为字符串,而在扫描函数中使用char数据类型呢?
发布于 2020-05-12 06:39:18
这取决于您使用的驱动程序,为了避免这样的问题,您需要查阅驱动程序的文档。例如,github.com/lib/pq驱动程序提供了关于其文档中的数据类型的部分。
您将在上面注意到,lib/pq声称将char类型的值返回为string,这是正确的,但是它可能看起来并非如此。我的意思是在postgres中有char类型,然后是"char"类型,而在上面的lib/pq指的是后者。
如果可能的话,您应该避免使用char和varchar,而应该使用text。
焦炭是什么时候的炭?
当您将一个列声明为具有char或char(n)类型时,该列的实际类型将是bpchar (空白填充的、固定长度的字符类型),它不会由lib/pq处理(尽管可能应该是这样)。
当您将列声明为具有"char"类型时,该列的实际类型将是"char" (用于内部使用的单字节字符类型),这将由lib/pq处理,并作为string返回。
要在这种特殊情况下保护自己,可以使用类型开关。
func (a *Access) Scan(src interface{}) error {
switch val := src.([]byte) {
case []byte:
return a.UnmarshalText(val)
case string:
return a.UnmarshalText([]byte(val))
}
return errors.New("scan failed: data is not a byte slice")
}https://stackoverflow.com/questions/61744776
复制相似问题