为了账号安全,请及时绑定邮箱和手机立即绑定

无效操作:在对任意维度的切片建模时无法索引 T

无效操作:在对任意维度的切片建模时无法索引 T

Go
慕姐4208626 2023-01-03 16:19:42
我正在尝试使用未知大小的矩阵进行矩阵减法。这是代码:type ArrayLike interface {    []interface{} | [][]interface{} | [][][]interface{} | [][][][]interface{}}func subMatrix[T ArrayLike](A, B T, shape []int) interface{} {    dim := shape[0]    if len(shape) == 1 {        retObj := make([]interface{}, dim)        for i := 0; i < dim; i++ {            Av := A[i].(float64)            Bv := B[i].(float64)            retObj[i] = Av - Bv        }        return retObj    } else {        retObj := make([]interface{}, dim)        for i := 0; i < dim; i++ {            retObj[i] = subMatrix(Av[i], Bv[i], shape[1:])        }        return retObj    }}它抱怨无效操作:无法索引 A(受 []interface{}|[][]interface{}|[][][]interface{}|[][][][]interface{} 约束的类型 T 的变量)compilerNonIndexableOperand有谁知道如何做这项工作?
查看完整描述

1 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

您不能这样做,不能使用泛型,也不能单独使用interface{}/ 。any主要问题是您不能对具有任意维度(即任意类型)的切片进行静态建模。让我们按顺序进行:

您收到的错误消息是因为您无法使用这样的联合约束来索引类型参数。规格,索引表达式

对于类型参数类型 P:

  • [...]

  • P 的类型集中所有类型的元素类型必须相同。[...]

ArrayLike的类型集的元素类型相同。的元素类型[]interface{}interface{},其中之一[][]interface{}[]interface{}等等。

此处概述了索引错误的安慰剂解决方案A,基本上它涉及将参数类型更改为Bslice []T。然后你可以索引A[i]B[i]

然而这还不够。此时,无法将正确的参数传递给递归调用。表情的类型A[i]是现在T,而是subMatrix想要[]T

即使删除类型参数并声明 argsABasany也不起作用,因为在递归调用中您仍然希望对它们进行索引。为了索引,您必须断言any某些可索引的东西,但那会是什么在每次递归时,类型都会少一个维度,因此静态类型的断言最终会崩溃。

解决这个问题的唯一方法是(可能?)反思,但老实说,我没有看到这样做的实用工具。

您可以而且应该为每个矩阵维度编写一个通用函数:


import "golang.org/x/exp/constraints"


type Number interface {

    constraints.Integer | constraints.Float

}


func Sub2DMatrix[T Number](a, b [][]T) {

    for i := range a {

        for j := range a[i] {

            a[i][j] -= b[i][j]

        }

    }

}


查看完整回答
反对 回复 2023-01-03
  • 1 回答
  • 0 关注
  • 72 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信