有没有一种方法可以追加两个go interface{}引用?

3

我正在尝试创建一个方法,该方法将已缓存的数据与从数据库中提取的非缓存数据进行追加。理想情况下,执行类似以下操作的单个方法是最理想的。那么有没有一种方法可以追加两个都是切片的interface{}引用?

package main

import "fmt"

type foo struct {
    Name string
}

func main() {
    a := []*foo{
        &foo{"bar"},
        &foo{"boom"},
    }

    b := []*foo{
        &foo{"blam"},
        &foo{"pow"},
    }

    fmt.Println(add(a, b))
}

func add(a, b interface{}) interface{} {
    return append([]interface{}{a}, ([]interface{}{b})...)
}

Results https://play.golang.org/p/9cWxPg6daq

[[0x1040a128 0x1040a130] [0x1040a140 0x1040a148]]

期望的结果

[0x1040a128 0x1040a130 0x1040a140 0x1040a148]

更新:基准测试

https://play.golang.org/p/9a8aZckQAF

C:\Users\chris\Go\src\bitbucket.org\chrisolsen\test>go test -bench=.
PASS
BenchmarkWithReflection-4         300000              4580 ns/op
BenchmarkNoReflection-4           300000              4194 ns/op
ok      bitbucket.org/chrisolsen/test   2.911s
2个回答

3
只需使用reflect
func add(a, b interface{}) interface{} {
    return reflect.AppendSlice(reflect.ValueOf(a), reflect.ValueOf(b)).Interface()
}

游乐场: https://play.golang.org/p/FjS73G2_G5.

请注意,如果ab不是兼容的切片,则会出现紧急情况。


1
虽然这样做可以实现,但是反射很可能会很慢。 - Nick Palmer
1
反射很可能会更慢,但在排除它之前,我进行了基准测试。虽然速度较慢,但与HTTP请求延迟相比,反射时间成本只是微不足道的,并且由于只有在需要缓存新数据时才需要反射,因此不会一直被调用。 - chris

1
一般来说,在Go中,没有办法将一个类型的数组转换为另一个类型的数组。您必须按照特定类型的方式进行转换,或者运行for循环以转换每个元素。这是由于切片的实现方式所致。请参见此答案: Type converting slices of interfaces in go 使用特定类型方法获得所需结果的方法如下: https://play.golang.org/p/RqKWvQqE_g 目前,Go还没有“泛型”机制,这使得通过通用注释实现这一点成为可能,尽管有些人已经编写了像Java中的泛型那样的代码生成器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接