将字符串片传递给可变空接口参数 [英] Pass string slice to variadic empty interface parameter

查看:107
本文介绍了将字符串片传递给可变空接口参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的软件包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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆