1. I think "type Uuid string" is a better idea, because they're
(presumably) immutable, and the []byte to string conversion does an
allocation which you want to avoid in performance critical code.
2. As far as JSON goes, what's so bad about map[string]whatever
instead of map[Uuid]whatever? Yes, you lose the type annotation and it
requires a little more conversion in some places, but it seems like a
fine compromise for now.
3. JSON should probably handle maps with key types that have an
underlying string type.
Andrew
It does already. The problem is that JSON requires that
key values be Unicode strings, which in Go means that
they must be valid UTF-8 encoded strings. The UUIDs
are raw 8-bit data and almost never coincide with valid
UTF-8, so they cannot be encoded as JSON strings.
If the map keys were the hex format of the UUID then this
would be just fine. My suggestion would be to try this and
measure the performance hit before trying something more
complex.
Russ
On Tue, Aug 30, 2011 at 1:54 AM, Russ Cox <r...@golang.org> wrote:
>> 3. JSON should probably handle maps with key types that have an
>> underlying string type.
> It does already. The problem is that JSON requires that
> key values be Unicode strings, which in Go means that
> they must be valid UTF-8 encoded strings. The UUIDs
> are raw 8-bit data and almost never coincide with valid
> UTF-8, so they cannot be encoded as JSON strings.
How about checking if the key implements the Marshaler interface?
It might be a bit of an esoteric use case, but I can see that other
people might want to transform their strings when
marshalling/unmarshalling to be compatible with some other system.
> If the map keys were the hex format of the UUID then this
> would be just fine. My suggestion would be to try this and
> measure the performance hit before trying something more
> complex.
I'll post the complete package with some benchmarks later today, but
the formatting overhead is quite significant.
Regards
Albert
There's a slight mismatch here. The normal Marshaler interface
returns arbitrary JSON. Object keys are JSON strings. So we
could call Marshal and then error out if it returns something
other than a string. I guess that would be okay.
Russ
Thanks, I'll try to prepare a patch soon.
In the mean time, we've worked around it by implementing the Marshaler
interface on our map type.
At that point we go through the effort of creating a map with proper
string keys and we then return the result of Marshal on that
"well-formed" map.
This is a lot of work, but it doesn't happen in a performance-critical
part of the code.
At the same time, it doesn't slow down the normal use of UUIDs in
maps. I'm going to try UUIDs as strings anyway to get rid of the
UuidKey wart though.
Regards
Albert