type assertion with alias type

870 views
Skip to first unread message

jfcg...@gmail.com

unread,
Jun 7, 2015, 6:54:45 AM6/7/15
to golan...@googlegroups.com
Hi,

bson package:
type M map[string]interface{}

my code (simplified):
var doc bson.M
json.Unmarshal(jsonData, &doc)
doc = doc["data"].(bson.M) // panic here

result:
panic: interface conversion: interface is map[string]interface{}, not bson.M

I understand the panic: bson.M is not the same but an alias type of map[string]interface{}.

The type assertion logic seems like it could allow this but it does not. Is there a technical or other type of reason for this ?

Thx.

Michael Schaller

unread,
Jun 7, 2015, 11:02:22 AM6/7/15
to golan...@googlegroups.com
The type identity section and the sections it links make that pretty clear:
https://golang.org/ref/spec#Type_identity

Respective quote to answer your question:
A named and an unnamed type are always different.

To my knowledge this is solely the case so that a named type can have a completely different method set. At least no other reasoning is given in the type declarations section:
https://golang.org/ref/spec#Type_declarations

adon...@google.com

unread,
Jun 8, 2015, 1:09:00 AM6/8/15
to golan...@googlegroups.com
On Sunday, 7 June 2015 11:02:22 UTC-4, Michael Schaller wrote:
A named and an unnamed type are always different.

FYI: this is true for non-interface types.  For interface types, names aren't significant; all that matters is the method set.

jfcg...@gmail.com

unread,
Jun 8, 2015, 6:49:05 AM6/8/15
to golan...@googlegroups.com
When I write
doc = bson.M( doc["data"].(map[string]interface{}) )
it works and is exactly the same operation as

doc = doc["data"].(bson.M)
would have been if it were allowed.

Would it be more practical and readable if type assertion logic allowed alias type assignment like this ? What do you think ?

7 Haziran 2015 Pazar 18:02:22 UTC+3 tarihinde Michael Schaller yazdı:

Thomas Bushnell, BSG

unread,
Jun 8, 2015, 7:14:42 AM6/8/15
to Michael Schaller, golan...@googlegroups.com
It's also useful so that you can't accidentally combine them in arithmetic. For example, you can do this:

type Fahrenheit int
type Celsius int

And  now you won't accidentally subtract one from the other and forget the necessary conversion.

Thomas

Michael Schaller

unread,
Jun 8, 2015, 7:54:31 AM6/8/15
to jfcg...@gmail.com, golang-nuts

IMHO 'doc = bson.M( doc["data"].(map[string]interface{}) )' is not okay because it lacks error handling.

The reason for this is that you use a type assertion [1], which can cause a panic at runtime, and a type conversion [2], which doesn't require error handling as an error will generate a compiler error.

My recommendation is to use the type assertion, check for an error and then do the type conversion:
d, ok := doc["data"].(map[string]interface{})
if !ok {
  // Error handling
}
doc = bson.M(d)

Why the rules for type assertions don't allow the shorter 'doc, ok := doc["data"].(bson.M)' directly I'm not sure either. Maybe to keep the type assertion rules simple and easy to understand. But maybe there is more to it...

[1] https://golang.org/ref/spec#Type_assertions

[2] https://golang.org/ref/spec#Conversions

--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/2YR-EuM2-Po/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages