1.遇到的问题
问题来源于,我sql模版拼接遇到的问题。
首先,这样是没有问题的。
var qhx interface{} = "qhx"
s := qhx.(string)
fmt.Println(s)
但是当我在这段代码里用:1.类型断言
var sqlStr = "select * from `tx_user` where username = '%s'"
jointSqlStr1(sqlStr, "admin")
func jointSqlStr1(sqlStr string,args ...interface{}) string {
for _,arg := range args {
sqlStr = fmt.Sprintf(arg.(string)) // 类型断言
}
return sqlStr
}
他就会报interface{} not string这个问题
后面我试了试,就算用 2. switch - type,也会类型匹配不到。
解放方案:
先通过 3.fmt.Spinft()函数转换为字符串,会多了 [ ]这个东西,再切除就可以了。
func jointSqlStr(sqlStr string, args ...interface{}) string {
for _, arg := range args {
str := fmt.Sprintf("%s", arg) // [admin]
str = str[1 : len(str)-1] // admin
sqlStr = fmt.Sprintf(sqlStr, str)
}
return sqlStr
}
后来发现: 以上都是正确的方法。
2.我的问题
我的问题在函数嵌套。怎么讲呢?
// 执行select all
func ExecuteSelectAll(stc interface{}, sql string, params ...interface{}) {
sql = jointSqlStr(sql, params) // 我拿到params,直接传入joinSqlStr里面
err := Db.Select(stc, sql)
if err != nil {
util.Log.Error("Sql Select Error:" + err.Error())
return
}
}
func jointSqlStr(sqlStr string, args ...interface{}) string {
for _, arg := range args {
str := fmt.Sprintf("%s", arg) // [admin]
str = str[1 : len(str)-1] // admin
sqlStr = fmt.Sprintf(sqlStr, str)
}
return sqlStr
}
导致拿到的类型结构是这样似的。显然这是不对的。
正确的写法,应该这样:
func ExecuteSelectAll(stc interface{}, sql string, params ...interface{}) {
sql = jointSqlStr(sql, params...)
// ....
}
但是,如下图: 经过Sprintf()拼接之后,如果有空余的%s没被填充,最后出现下面这种状况。
var sqlStr = "select * from tx_user WHERE username= '%s' and password = '%s'"
fmt.Sprintf(sqlStr,"admin")
因此,代码要这样改。
func jointSqlStr(sqlStr string, args ...interface{}) string {
// 以%s分割
strs := strings.Split(sqlStr, "%s")
if len(strs) == 0 {
return sqlStr
}
newSql := ""
for i, _ := range strs {
newSql += strs[i]
if i != len(strs)-1 {
switch args[i].(type) {
case string:
newSql += args[i].(string)
break
case int:
newSql += fmt.Sprintf("%v", args[i].(int))
break
case uint:
newSql += fmt.Sprintf("%v", args[i].(uint))
break
}
}
}
return newSql
}