我试图在 Go 中为四叉树实现一个 Node 类,我想在该类上有一个“插入”方法,它接受任何具有 x 和 y 坐标的切片,本质上是 2 个浮点数。
所以我使该方法看起来像这样:
func (node *QNode) insert(datapoints []Locatable)
其中
Locatable
是以下界面:
type Locatable interface {
getPosition() (x, y float32)
}
但是我很快意识到切片在 Go 中不是协变的,所以据我所知,我唯一的选择是使用泛型,然后在我需要访问唯一的结构字段时键入断言,或者只是显式地将我的结构切片中的所有内容复制到接口切片,并且然后将其传递到我的
insert
方法中。
这些是唯一的 2 个选项还是有更好的方法来处理“通用切片”?
我有一个方法通过反射循环
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})
}