如何在Go中处理通用切片?[重复]

wfauudbj  于 2023-04-18  发布在  Go
关注(0)|答案(1)|浏览(133)

此问题已在此处有答案

Type converting slices of interfaces(9个回答)
Cannot convert []string to []interface {}(7个回答)
Cannot use args (type []string) as type []interface {} [duplicate](1个答案)
slice of struct != slice of interface it implements?(6个答案)
How can I access a struct field with generics (type T has no field or method)?(1个答案)
4天前关闭。
我试图在Go语言中实现一个Node类来实现一个四叉树,我想在这个类上实现一个“insert”方法,它接受任何具有x和y坐标的东西的切片,本质上是2个浮点数。
所以我让这个方法看起来像这样:

func (node *QNode) insert(datapoints []Locatable)

其中Locatable是以下接口:

type Locatable interface {
    getPosition() (x, y float32)
}

然而我很快意识到,切片在Go中不是协变的,所以我唯一的选择是使用泛型,然后在我需要访问唯一的结构体字段时键入assert,或者只是显式地将所有内容从我的结构体切片复制到接口切片,然后将其传递到我的insert方法中。
这是仅有的两个选项,还是有更好的方法来处理“通用切片”?

bvn4nwqk

bvn4nwqk1#

我有一个方法通过reflect循环interface{} slice然后尝试输入assert
虽然不够好,但希望能激励你

package main

import (
    "fmt"
    "reflect"
)

type QNode struct {
    x_arr []float32
    y_arr []float32
}

func (node *QNode) insertSingle(datapoint Locatable) {
    x, y := datapoint.getPosition()
    node.x_arr = append(node.x_arr, x)
    node.y_arr = append(node.x_arr, y)
}

// Can Insert 1 or more
func (node *QNode) inserts(datapoints interface{}) {

    type_checker := reflect.TypeOf(datapoints)
    switch type_checker.Kind() {
    case reflect.Slice:
        datapoints_reflect_val := reflect.ValueOf(datapoints)
        for i := 0; i < datapoints_reflect_val.Len(); i++ {
            if val, ok := datapoints_reflect_val.Index(i).Interface().(Locatable); ok {
                node.insertSingle(val)
            }
        }
    default:
        if val, ok := datapoints.(Locatable); ok {
            node.insertSingle(val)
        }
    }

}

type Locatable interface {
    getPosition() (x, y float32)
}

type A struct {
    x_a float32
    y_a float32
}
type B struct {
    x_b float32
    y_b float32
}

func (a A) getPosition() (x, y float32) {
    return a.x_a, a.y_a
}
func (b B) getPosition() (x, y float32) {
    return b.x_b, b.y_b
}
func main() {
    node := QNode{
        x_arr: make([]float32, 0),
        y_arr: make([]float32, 0),
    }
    //Mutiple Insert
    As := make([]A, 0)
    for i := 0; i < 20; i++ {
        As = append(As, A{float32(i) * 2, 2.3})
    }
    node.inserts(As)
    Bs := make([]B, 0)
    for i := 0; i < 20; i++ {
        Bs = append(Bs, B{float32(i) * 2, 2.3})
    }
    node.inserts(Bs)
    //Mix Mutiple Insert
    ABs := make([]interface{}, 0)
    for i := 0; i < 10; i++ {
        ABs = append(ABs, B{float32(i) * 2, 2.3})
    }
    for i := 0; i < 10; i++ {
        ABs = append(ABs, A{float32(i) * 2, 2.3})
    }
    node.inserts(ABs)
    fmt.Println(node)
    //Single Insert
    node.inserts(A{7.9, 8.3})
    node.inserts(B{5.9, 2.3})
}

相关问题