将字符串片传递给可变空接口参数 [英] Pass string slice to variadic empty interface parameter
问题描述
我使用的软件包gosqlite有一个带有 variadic 参数的方法,其类型为空接口。
func(s * Stmt)Exec(args ... interface {})os.Error
如果显式传递个别参数,我可以称它为罚款:
statement:= blah()
error:= statement.Exec(hello,3.0,true)//正常工作
然而,由于variadic参数对应于我的SQL语句的
操作符中的
中的占位符,请选择
,这些占位符的数量在编译时并不知道,但是在运行时会根据用户的行为动态变化。例如。如果用户输入四个值,我最终得到的SQL类似于:
SELECT * FROM sky WHERE name IN(?所以很自然我想调用 Exec 使用一段字符串的方法: var values [] string = getValuesFromUser()
语句:= createStatementWithSufficientNumberOfPlaceholders(len(values))
_:= statement.Exec(values ...)//编译器不喜欢这个
这不能编译。我可以通过创建一个空的接口片并复制引用来解决这个问题:
values2:= make([] interface {},len(values))
for index,value:= range values {values2 [index] = value}
_:= statement.Exec(values2 ...)//编译器很开心但我'不是
这个工作正常,但感觉有点笨重。我想知道是否有一些技巧能够将 values
直接传递给该函数,否则,将字符串切片转换为空白接口的方式会更好?
非常感谢。
解决方案没有办法通过 [] string
直接传递给 ... interface {}
参数。这样做需要线性时间复制(使用n + 1分配!)。如果这种语言隐藏你的话,这将是一个重大的隐藏成本。通常,将切片传递给可变参数只是将切片传递给函数。
至于其他方式,您可以通过编写函数需要一个 []字符串
并返回相应的 [] interface {}
。当然,您必须为每个 [] T
- > [] interface {}
转换再次编写它你想要做的,但它的功能相当短,而所有的变化就是签名。您可以使用反射(它具有固有运行时成本)来使该函数成为通用 ,例如:
valuesVal:= reflect.ValueOf(values)
...
for i:=范围值2 {values2 [i] = valuesVal.Index(i).Interface()}
A package I am using, gosqlite, has a method with a variadic parameter where its type is the empty interface.
func (s *Stmt) Exec(args ...interface{}) os.Error
I can call this fine if explicitly pass individual parameters:
statement := blah()
error := statement.Exec("hello", 3.0, true) // works fine
However, as the variadic parameter corresponds to placeholders within the in
operator of my SQL statement's select
, the number of these placeholders is not known at compile time but dynamically changes at run time depending upon what the user is doing. E.g. I end up with SQL akin to the following if the user enters four values:
SELECT * FROM sky WHERE name IN (?,?,?,?)
So naturally I would like to call the Exec
method with a slice of strings:
var values []string = getValuesFromUser()
statement := createStatementWithSufficientNumberOfPlaceholders(len(values))
_ := statement.Exec(values...) // compiler doesn't like this
This does not compile. I can get around this problem by creating an empty interface slice and copying the references over:
values2 := make([]interface{}, len(values))
for index, value := range values { values2[index] = value }
_ := statement.Exec(values2...) // compiler happy but I'm not
And this works fine but it feels a bit clunky. I was wondering if there was some trick to be able to pass values
directly to this function or, failing that, a neater way of converting the string slice to an empty interface one?
Many thanks.
解决方案 There is no way to pass a []string
directly to a ...interface{}
parameter. Doing this requires a linear time copy (with n + 1 allocations!). If the language hid this from you, it would be a significant hidden cost. Normally, passing a slice to a variadic argument just passes the slice into the function.
As for other ways of doing this, you could make it cleaner by writing a function that takes a []string
and returns the corresponding []interface{}
. Of course, you'll have to write it again for each []T
-> []interface{}
conversion you want to do, but its a rather short function, and all that changes is the signature. You could use reflection, which comes with an inherent runtime cost, to make the function "generic", such as in:
valuesVal := reflect.ValueOf(values)
...
for i := range values2 { values2[i] = valuesVal.Index(i).Interface() }
这篇关于将字符串片传递给可变空接口参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!