在列表元素中修改固定大小的数组

I'm doing a micro-optimisation of my LRU cache solution in Golang where I'm using https://golang.org/pkg/container/list/. My solution works by having a map[int]*list.Element, where each list.List list.Element is []int, with [0] being key, and [1] being value.

I'm trying to move from []int to [2]int for my optimisation, but I'm then running into the issue that modifying the fixed-size array, after ee := e.Value.([2]int) (note the [2]int type for fixed-size array), is no longer modifying the underlying values in the list.Element, unlike was the case w/ ee := e.Value.([]int) (note the []int type), which I guess makes perfect sense, since slices are based on references, whereas fixed-size arrays are based on copied values.

I've tried stuff like e.Value.([2]int)[1] = …, as well as various combinations with := &e.Value…, and casting from [2]int to []int, but it all results in complier errors.

Q: Is there no way to use the container/list with an embedded array, and perform modifications of said fixed-size array in-place?

As you already noted:

I guess makes perfect sense, since slices are based on references, whereas fixed-size arrays are based on copied values

So if you want to make this work, you'll need to use references to your fixed-size arrays by storing pointers to the arrays instead of array values.

That way, you'll be able to modify the underlying array through the list element.

See here for a simple example:

package main

import (
    "container/list"
    "fmt"
)

func main() {

    l := list.New()

    // create a fixed size array and initialize it
    var arr [2]int
    arr[0] = 1
    arr[1] = 2
    // push a pointer to the array into the list
    elem := l.PushFront(&arr)
    // modify the stored array
    elem.Value.(*[2]int)[0] = 3
    // print the element from iterating the list
    for e := l.Front(); e != nil; e = e.Next() {
        fmt.Println(e.Value)
    }
    // print the underlying array, both are modified
    fmt.Println(arr)

}

EDIT

Note that this behaviour is not something specific to this list implementation, but rather related how type assertions work in the language itself.

See here:

https://golang.org/doc/effective_go.html#interface_conversions

Quoting from that section (and adding emphasis of my own):

The syntax borrows from the clause opening a type switch, but with an explicit type rather than the type keyword: value.(typeName) and the result is a new value with the static type typeName.

When using reference types, copying the value does not affect you cause copying a pointer value ends up allowing you to change the same underlying reference.

But when the array is a value itself, it does not make sense to assign to the copy. When you try to modify the array directly (without assigning the type assertion to a variable) Go would even catch this at compile time so that you don't assign to this "temporary" copy which would obviously be a mistake. That's how you got all your syntax errors when trying to do this.

To overcome this (if you don't want to use pointers) one possibility might be for you to implement your own list, borrowing from the implementation you are using but making your Element's value an explicit [2]int instead of an interface.

That would remove the need to make the type assertion and you'll be able to modify the underlying array.