Cannot assign to array element in a map?

4,881 views
Skip to first unread message

Jingcheng Zhang

unread,
May 6, 2013, 1:20:42 AM5/6/13
to golang-nuts
Hello gophers,

The codes cannot compile:

func main() {
     m := make(map[int][2]int, 10)
     m[0] = [2]int{1, 2}
     m[0][1] = 3
     println(m[0][1])
}

Result is:

>go run main.go
# command-line-arguments
.\main.go:6: cannot assign to m[0][1]

Why?

--
Best regards,
Jingcheng Zhang
Beijing, P.R.China

Dan Kortschak

unread,
May 6, 2013, 1:31:56 AM5/6/13
to Jingcheng Zhang, golang-nuts
Querying a map give a copy of the stored item, so there is no point
assigning to it. This works:

http://play.golang.org/p/zch2RapP1E

or this:

http://play.golang.org/p/94BaoNuiAr

Kyle Lemons

unread,
May 6, 2013, 1:32:10 AM5/6/13
to Jingcheng Zhang, golang-nuts
Map values are essentially immutable because they are not addressable; therefore you cannot edit only part of one.  You'd have to copy out the array, modify it, and assign it back.

From the spec:

http://tip.golang.org/ref/spec#Assignments
"Each left-hand side operand must be addressable"

http://tip.golang.org/ref/spec#Address_operators
"[An addressable value] is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array"




--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Steven Blenkinsop

unread,
May 6, 2013, 1:32:32 AM5/6/13
to Jingcheng Zhang, golang-nuts
On Monday, May 6, 2013, Jingcheng Zhang wrote:
Hello gophers,

The codes cannot compile:

func main() {
     m := make(map[int][2]int, 10)
     m[0] = [2]int{1, 2}
     m[0][1] = 3
     println(m[0][1])
}

Result is:

>go run main.go
# command-line-arguments
.\main.go:6: cannot assign to m[0][1]

Why?

The elements inside a map are not addressable. This is because, if you store the address of an element in a map, that address might be invalidated at a later time if the element gets removed from the map or the map restructures itself internally. You cannot assign to unaddressable values. The one exception is assigning directly to map indexing expressions, so you can put stuff in a map. However, it doesn't let you assign to unaddressable expressions derived from map indexing expressions, hence the error. Plausibly the compiler could break these assignments into three steps: (1) copy the element out of the map, (2) update the copy, (3) overwrite the element in the map with the copy. However, Go tries not to be too magical, and hiding this three step process by making it look like a simple assignment would work against that.

Jingcheng Zhang

unread,
May 6, 2013, 1:42:55 AM5/6/13
to Steven Blenkinsop, golang-nuts
Thank everyone. 

The feature looks a little strange, as I thought m[0] is addressable, which is in fact not.

Jesse McNelis

unread,
May 6, 2013, 2:09:02 AM5/6/13
to Jingcheng Zhang, Steven Blenkinsop, golang-nuts
On Mon, May 6, 2013 at 3:42 PM, Jingcheng Zhang <dio...@gmail.com> wrote:
Thank everyone. 

The feature looks a little strange, as I thought m[0] is addressable, which is in fact not.

If the syntax was m.get(0) it would probably be obvious that it wasn't addressable.
 

David DENG

unread,
May 6, 2013, 11:34:15 AM5/6/13
to golan...@googlegroups.com, Steven Blenkinsop
Consider elements of an array (not a slice) as the fields of a struct.

David

John Nagle

unread,
May 9, 2013, 11:05:11 PM5/9/13
to golan...@googlegroups.com
On 5/6/2013 7:08 AM,
gordon...@gmail.com wrote:
> If you are willing to use a slice instead of an array, then this also
> works, because slice is a reference type.

"Any problem in computer science can be solved with another level
of indirection." -- David Wheeler.

John Nagle

sofo...@gmail.com

unread,
Aug 18, 2013, 12:50:52 PM8/18/13
to golan...@googlegroups.com, Jingcheng Zhang, gordon...@gmail.com
I agree. 
Actually, if you read Go Effective, you will found that, slice is reference type, while arrays are values:
"Arrays are values. Assigning one array to another copies all the elements."

I think this is not because map is not addressable(m[0] is array). And map index expression can be left-hand side operand


在 2013年5月6日星期一UTC+8下午10时08分16秒,gordon...@gmail.com写道:
If you are willing to use a slice instead of an array, then this also works, because slice is a reference type:
Reply all
Reply to author
Forward
0 new messages