I don't understand. When might removeFailed be true (for a Go map
as they is currently spoke)?
Chris
--
Chris "allusive" Dollin
Here you are returning a *foo.Record.
You can't actually return a struct that has private fields, if you
want code outside your package to be able to use it.
> So that the only way to remove an entry from a map[int]foo.Record
> (without invoking the nasty constructor) is to do *two* map
> accesses...lookup first, then remove, like:
> if v, ok := m[k]; ok {
> m[k] := v, false
> }
Since this is actually a map[int]*foo.Record, you can just do:
m[k] = nil,false
- jessta
--
=====================
http://jessta.id.au
> If it can't fail, you're totally right, it's only a double-lookup.
> Still, in some other languages, that would be costly...are lookups
> that cheap in Go, or is the compiler is able to optimize these in
> practice, so that the cost of the double-lookup is insignificant?
Were I writing map lookup, I'd consider remembering the
last key used and where the value was, so that an immediate
relookup could get away with an equality check. But that's
probably only wise for small keys (the last times I wrote map
code, the keys were pointers-to-objects and one forced
comparision a pretty low overhead).
package main
import ("fmt")
func main() {
var mp map[string]string
mp = make(map[string]string)
mp["teste"] = "teste"
var pmp *map[string]string
pmp = &mp
// initial map
key, has := (*pmp)["teste"]
if has {
fmt.Printf("%s in map\n",key)
} else {
fmt.Printf("%s not in map\n",key)
}
// purged map
// purge a map is just point the pointer
// to a new map.
// gc will collect the unused memory
var mp2 map[string]string
mp2 = make(map[string]string)
pmp = &mp2
key, has = (*pmp)["teste"]
if has {
fmt.Printf("%s in map\n", key)
} else {
fmt.Printf("%s not map\n",key)
}
}
--
André Moraes
http://andredevchannel.blogspot.com/
As I daid elsewhere, only if you /consistently/ use a pointer-to-map
for maps you (might) want to purge.
Since maps are reference types already, this seems ...
redundant.
Chris
--
Chris "allusive" Dollin
I don't think so. This other program has a similar result to André's example:
package main
import ("fmt")
func main() {
var mp map[string]string
// initial map
mp = make(map[string]string)
mp["teste"] = "teste"
key, has := mp["teste"]
if has {
fmt.Printf("%s in map\n",key)
} else {
fmt.Printf("%s not in map\n",key)
}
// purged map
mp = make(map[string]string)
key, has = mp["teste"]
if has {
fmt.Printf("%s in map\n", key)
} else {
fmt.Printf("%s not map\n",key)
}
}
--
- yiyus || JGL . 4l77.com
If you had passed mp to another function, which had stored
it somewhere it was used from, all the reassigning in the world
to mp would make no different to that saved map.
package main
import "fmt"
func main() {
var mp map[string]string
mp = make(map[string]string)
mp["teste"] = "teste"
// purge the map using it's own values.
for k,v := range(mp) {
mp[k] = v, false
}
v, has := mp["teste"]
if has {
fmt.Printf(v)
} else {
fmt.Printf("not in")
}
}
In this case, I remove the values within the for loop, and don't need
to create a new value since I pick only the value that is already in
the map.
The map is completely purged.
I know that usually is a bad thing to change a collection while you
are in a iteration but in this case it works without any problem
(tested on golang.org browser compiler).
> I know that usually is a bad thing to change a collection while you
> are in a iteration but in this case it works without any problem
> (tested on golang.org browser compiler).
I'd rather the spec was specific about it working rather than
relying on a small test like that. (I don't read the spec as being
explicit enough on this point, but that may be because I'm used
to specs where less is taken for granted.)
Copy the key and values to slices with the size of the map.
Iterate over the slice and remove the keys from the map.
Isn't elegant, but solves the problem for now (until somebody make a
purge built-in or says that removing while iterating is valid).
i think this is explicit enough:
"The iteration order over maps is not specified. If map entries that
have not yet been reached are deleted during iteration, the
corresponding iteration values will not be produced. If map entries
are inserted during iteration, the behavior is
implementation-dependent, but the iteration values for each entry will
be produced at most once."
if it was invalid to alter a map during iteration, then the spec would
need to say so,
but it does not. in fact, it explicitly talks about altering the map
during iteration,
which would seem to bless the idiom posted by Andre.
Since the value is removed after reading looks like it's OK to do that.
Yes, I read that.
> if it was invalid to alter a map during iteration, then the spec would
> need to say so,
> but it does not. in fact, it explicitly talks about altering the map
> during iteration,
> which would seem to bless the idiom posted by Andre.
Well, I'd like to think so too. And it's maybe just the effect of the
Java DANGER WILL ROBINSON specifications for data structures
like maps, but I'd like to see something more explicit in the way of
comfort. Something like:
The iteration order over maps is not specified. It is allowed to add
and remove elements from the map during the iteration. Deleting
an unproduced element means it will not be produced. Newly inserted
elements will be produced at the whim of the implementation, but
at most once.