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] // adminsqlStr = 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] // adminsqlStr = 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")newSql := ""for i, _ := range strs {newSql += strs[i]if i != len(strs)-1 {switch args[i].(type) {case string:newSql += args[i].(string)case int:newSql += string(args[i].(int))}}}return newSql
}