retaining mapiterkey return values in *reflect.MapIter

49 views
Skip to first unread message

Dan Kortschak

unread,
Jun 30, 2020, 9:39:52 PM6/30/20
to golang-nuts
Is there a reason not to retain the returned value from `mapiterkey` on
line 1243 of reflect/value.go[1] for use on line 1249[2].

```
// Key returns the key of the iterator's current map entry.
func (it *MapIter) Key() Value {
if it.it == nil {
panic("MapIter.Key called before Next")
}
if mapiterkey(it.it) == nil { //L1243
panic("MapIter.Key called on exhausted iterator")
}

t := (*mapType)(unsafe.Pointer(it.m.typ))
ktype := t.key
return copyVal(ktype, it.m.flag.ro()|flag(ktype.Kind()), mapiterkey(it.it)) // L1249
}
```

The same question applies to `*MapIter.Value` method just below `Key`.

thanks
Dan

[1]
https://github.com/golang/go/blob/96e83664378918980bd8f60822c4bc39befcb668/src/reflect/value.go#L1243
[2]
https://github.com/golang/go/blob/96e83664378918980bd8f60822c4bc39befcb668/src/reflect/value.go#L1249


Ian Lance Taylor

unread,
Jun 30, 2020, 10:25:34 PM6/30/20
to Dan Kortschak, golang-nuts
On Tue, Jun 30, 2020 at 6:39 PM 'Dan Kortschak' via golang-nuts
<golan...@googlegroups.com> wrote:
>
> Is there a reason not to retain the returned value from `mapiterkey` on
> line 1243 of reflect/value.go[1] for use on line 1249[2].
>
> ```
> // Key returns the key of the iterator's current map entry.
> func (it *MapIter) Key() Value {
> if it.it == nil {
> panic("MapIter.Key called before Next")
> }
> if mapiterkey(it.it) == nil { //L1243
> panic("MapIter.Key called on exhausted iterator")
> }
>
> t := (*mapType)(unsafe.Pointer(it.m.typ))
> ktype := t.key
> return copyVal(ktype, it.m.flag.ro()|flag(ktype.Kind()), mapiterkey(it.it)) // L1249
> }
> ```
>
> The same question applies to `*MapIter.Value` method just below `Key`.

I don't think there is any reason to call the function twice. The
value could be retained.

I think the functionswill be inlined, so it probably won't make any
performance difference, but it might be a little clearer.

Ian

Dan Kortschak

unread,
Jun 30, 2020, 10:34:40 PM6/30/20
to Ian Lance Taylor, golang-nuts
Looking again, the second part of my question was wrong (it is a call
to `mapiterkey` and then `mapiterelem` in `Value`).

The code for Key and Value are almost identical, so the question
whether to send a change boils down whether the similarity between the
two is a benefit or a cost. I'm actually leaning towards the similarity
being a benefit and one that would be broken by retaining the value.

Dan
Reply all
Reply to author
Forward
0 new messages