Pass string slice to variadic empty interface parameter
我使用的包gosqlite具有一个方法,该方法具有一个可变参数,其类型为空接口。
1 | func (s *Stmt) Exec(args ...interface{}) os.Error |
如果显式传递单个参数,我可以调用此fine:
1 2 | statement := blah() error := statement.Exec("hello", 3.0, true) // works fine |
号
但是,由于variadic参数对应于我的SQL语句的
1 | SELECT * FROM sky WHERE name IN (?,?,?,?) |
因此,我当然想用一段字符串调用
1 2 3 | var values []string = getValuesFromUser() statement := createStatementWithSufficientNumberOfPlaceholders(len(values)) _ := statement.Exec(values...) // compiler doesn't like this |
。
这不编译。我可以通过创建一个空接口切片并复制引用来解决这个问题:
1 2 3 | values2 := make([]interface{}, len(values)) for index, value := range values { values2[index] = value } _ := statement.Exec(values2...) // compiler happy but I'm not |
这个很好用,但感觉有点笨重。我想知道是否有一些技巧可以将
非常感谢。
无法将
至于其他方法,您可以通过编写一个函数使它更清晰,该函数接受一个
1 2 3 | valuesVal := reflect.ValueOf(values) ... for i := range values2 { values2[i] = valuesVal.Index(i).Interface() } |
我没有答案。我不认为有这样一个,因为即使是内置的和可变的copy和append都有相同(或兼容的具体)的元素类型"blockhead",但我有两个明显的建议:
- 不从
getValuesFromUser() 返回[]string (即通行证仍为未加修改的[]interface{}) , - 在另一个类型上,使用func将
[]string 转换为[]interface{} 来结束对statement.Exec() 的调用。
小精灵
同样,第三,明显的音符扩展了
另外,我自己也没有做任何基准测试,但我不认为这种转换是非常昂贵的,因为界面感觉像是一种引用类型,编译器可能在幕后做了一些肮脏的诡计……不过,也许不是,我也会很高兴知道一个实际的解决方案。