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

问题描述 投票:0回答:1

我试图在 Go 中为四叉树实现一个 Node 类,我想在该类上有一个“插入”方法,它接受任何具有 x 和 y 坐标的切片,本质上是 2 个浮点数。

所以我使该方法看起来像这样:

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

其中

Locatable
是以下界面:

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

但是我很快意识到切片在 Go 中不是协变的,所以据我所知,我唯一的选择是使用泛型,然后在我需要访问唯一的结构字段时键入断言,或者只是显式地将我的结构切片中的所有内容复制到接口切片,并且然后将其传递到我的

insert
方法中。

这些是唯一的 2 个选项还是有更好的方法来处理“通用切片”?

go generics interface slice covariance
1个回答
-1
投票

我有一个方法通过反射循环

interface{} slice
然后尝试输入断言

不够好,希望能给你启发

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})
}
© www.soinside.com 2019 - 2024. All rights reserved.