我使用的一个包gosqlite有一个带有variadic个参数的方法,其类型是empty interface.

func (s *Stmt) Exec(args ...interface{}) os.Error

如果显式传递单个参数,我可以称之为罚款:

statement := blah()
error := statement.Exec("hello", 3.0, true) // works fine

然而,由于variadic参数对应于SQL语句selectin运算符中的占位符,这些占位符的数量在编译时是未知的,但在运行时会根据用户的操作动态变化.例如,如果用户输入四个值,我会使用类似于以下内容的SQL:

SELECT * FROM sky WHERE name IN (?,?,?,?)

因此,我自然会使用一段字符串调用Exec方法:

var values []string = getValuesFromUser()
statement := createStatementWithSufficientNumberOfPlaceholders(len(values))
_ := statement.Exec(values...) // compiler doesn't like this

这是不可编译的.我可以通过创建一个空接口片并通过以下方式复制引用来解决这个问题:

values2 := make([]interface{}, len(values))
for index, value := range values { values2[index] = value }
_ := statement.Exec(values2...) // compiler happy but I'm not

这个不错,但感觉有点笨重.我想知道是否有什么技巧可以将values直接传递给此函数,或者,如果没有,是否有更巧妙的方法将字符串片转换为空接口片?

非常感谢.

推荐答案

无法将[]string直接传递给...interface{}参数.这样做需要线性时间拷贝(使用n+1分配!).如果语言对你隐瞒了这一点,这将是一个巨大的隐藏成本.通常,将一个切片传递给一个可变参数只是将切片传递给函数.

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() } 

Go相关问答推荐

在Golang中,@LATEST和@UPGRADE特殊查询有什么不同?

GORM Find方法中缺少字段

如何使用Gorilla WebSockets实现Http.Hijacker&;alexedwards/scs/v2

即使HTTP服务器正在使用GO和Protobuf、SQL Server启动,请求也不返回结果

减少在围棋中映射DTO时的重复代码量

是不是有什么原因导致`Strings.EqualFold`不先进行长度比较?

将这两个函数合二为一的惯用方法

是否需要手动调用rand.Seed?

带有前导零的整数参数被 flag.IntVar 解析为八进制

如何使用 go 包设置标头键和值:shurcooL/graphql 或 hasura/go-graphql-client?

如何判断范围内的字段?

go-echo中如何防止+转义

使用 golang 生成 vim

在恒等函数中将类型 T 转换为类型 U

此代码如何生成内存对齐切片?

无法在 GORM 中排序

go 堆栈跟踪:在某些函数调用参数或返回值之后的问题(?)标记是什么意思?

HTTP 重定向不呈现新页面

Go:如何通过 GIN-Router 从 AWS S3 将文件作为二进制流发送到浏览器?

Go generics:我会在哪里使用 any 而不是 interface{}?