英文:
How to use Scan interface to lowercase a string read from the database
问题
我想要将从数据库中读取的字符串转换为小写。我知道这可以在SQL中完成,但这是我使用Go的第一天,这更多是一个概念验证(以及对Go的理解),而不是实际需求。
类型EmailAddress在使用Scan接口从数据库中读取时应始终为小写,但这会导致panic: interface conversion: interface is []uint8, not string。
package main
import (
"database/sql"
"github.com/kisielk/sqlstruct"
_ "github.com/lib/pq"
"log"
"strings"
)
type EmailAddress string
func (g *EmailAddress) Scan(src interface{}) error {
*g = EmailAddress(strings.ToLower(src.(string)))
return nil
}
type User struct {
Id int
MobilePhone string `sql:"mobile_phone"`
Email EmailAddress
}
func main() {
db, _ := sql.Open("postgres", "host=localhost dbname=test sslmode=disable")
defer db.Close()
rows, _ := db.Query("SELECT id, mobile_phone, COALESCE(email,'') as email FROM users limit 5")
for rows.Next() {
var t User
_ = sqlstruct.Scan(&t, rows)
log.Printf("%+v\n", t)
}
}
以上是你提供的代码的翻译。
英文:
I want to lower case a string as I read it in from the database. I know this can be done in SQL, but this is my first day with go and this is more of a proof of concept (and understanding of go) rather than an actual requirement.
type EmailAddress should always be lowercase when read from the db using the Scan interface, this breaks with panic: interface conversion: interface is []uint8, not string
package main
import (
"database/sql"
"github.com/kisielk/sqlstruct"
_ "github.com/lib/pq"
"log"
"strings"
)
type EmailAddress string
func (g *EmailAddress) Scan(src interface{}) error {
*g = EmailAddress(strings.ToLower(src.(string)))
return nil
}
type User struct {
Id int
MobilePhone string `sql:"mobile_phone"`
Email EmailAddress
}
func main() {
db, _ := sql.Open("postgres", "host=localhost dbname=test sslmode=disable")
defer db.Close()
rows, _ := db.Query("SELECT id, mobile_phone, COALESCE(email,'') as email FROM users limit 5")
for rows.Next() {
var t User
_ = sqlstruct.Scan(&t, rows)
log.Printf("%+v\n", t)
}
}
答案1
得分: 11
你看到[]uint8
错误是因为EmailAddress被提供为一个字节切片,而不是一个字符串。记住,byte只是uint8的别名。这里有一个简单的示例展示了你看到的错误:http://play.golang.org/p/iN5y3PaFAL
所以,最简单的修复方法是改变scan函数:
func (g *EmailAddress) Scan(src interface{}) error {
b, ok := src.([]byte)
if !ok {
return fmt.Errorf("expected []byte, got %T", src)
}
*g = EmailAddress(strings.ToLower(string(b)))
return nil
}
英文:
You're seeing the []uint8
error because the EmailAddress is being provided as a byte slice, rather than a string. Remember, byte is just an alias for uint8. Here's a simple example which shows the error you're seeing: http://play.golang.org/p/iN5y3PaFAL
So, the easiest fix would be to change the scan function:
func (g *EmailAddress) Scan(src interface{}) error {
b, ok := src.([]byte)
if !ok {
return fmt.Errorf("expected []byte, got %T", src)
}
*g = EmailAddress(strings.ToLower(string(b))
return nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论