如何通过反射将映射值附加到切片?

How to append to slices as map values with reflection?

假设

  1. 我使用的是 go1.17 而不是 1.18,所以 go 1.18 中的答案可能对其他人有帮助,但对我没有帮助。
  2. 我搜索并尝试了很多东西,但这种情况从未解决。

问题

import (
    "fmt"
    "reflect"
)

func main() {
    l := map[string][]interface{}{"a": {}}
    appendData(l["a"])
    fmt.Println(l["a"])
}

func appendData(k interface{}) {
    lValue := reflect.ValueOf(k)
    lValue.Set(reflect.Append(lValue, reflect.ValueOf(1)))
    lValue.Set(reflect.Append(lValue, reflect.ValueOf(2)))
    lValue.Set(reflect.Append(lValue, reflect.ValueOf(3)))
}

我把场景简化成了这段代码
我只需要能够从 appendData 函数更改已传递的接口片段 ([]interface{}) 的元素。
不要把这行代码发给我l["a"] = appendData(l["a"]).([]interface{})
我知道这行得通,但出于某种原因我无法在我的代码中实现它。(我正在做一些 BFS 的事情但我不能这样做,我当时必须更改一些值)

我想要什么?

我只想看到这个输出:

[1, 2, 3]

可能吗?
是否有任何其他替代方法可以从我的代码中的其他地方更改这些数据?
感谢您的帮助。

如果只传递切片,无论 appendData() 做什么,您都不会看到 [1, 2, 3] 被打印出来。

2 件事:您无法更改地图中存储的值。如果必须更改值,则必须重新分配新值。有关详细信息,请参阅

第二:您也不能更改存储在接口中的值。详情见Removing an element from a type asserted Slice of interfaces

正确的做法:如果你想改变一些东西,总是传递一个指向它的指针,并修改指向的值。当然,在您的情况下,您不能传递指向存储在地图中的值的指针(“指向地图”),所以这是不可能的。映射索引表达式不可寻址,详情见。如果一定要用map,就必须在map中存储一个指针,你可以传递那个指针。

另一种方法是 return 新的、修改后的切片并在调用者处分配新的切片,确切地说是内置函数 append() 的作用/方式(append() returns 一个你应该分配/存储的新切片)。如果沿着这条路线走下去,您可以在地图中存储 non-pointer 个切片,因为您可以将修改后的切片重新分配给相同的地图键。