-1

I have tried out the following code:

package main

import (
    "fmt"
    "sync"
)

type T string

func main() {
    var a sync.Map // map[interface{}]interface{}
    var c T
    // a.Store("a", T("A"))
    a.Store("a", "A")
    b, _ := a.Load("a")
    c = b.(T)
    fmt.Println(c)
}

This gets an error of panic: interface conversion: interface {} is string, not main.T. However, it works if I use the commented line.

Aren't T and string of same underlying types? What's behind this?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
JasmineOT
  • 1,978
  • 2
  • 20
  • 30
  • 4
    Yes, they have the same underlying type and that's why *conversion* (`T(v)`) works, however *type assertion* (`v.(T)`) is another thing. – mkopriva Nov 20 '19 at 19:56
  • 5
    Adding to above, the assertion is strict. https://stackoverflow.com/questions/41501596/custom-type-passed-to-function-as-a-parameter – Brian Wagner Nov 20 '19 at 19:58
  • If you are new to Go you do not need a sync.Map. – Volker Nov 20 '19 at 20:54

1 Answers1

1

This stores a string in the map:

a.Store("a", "A")

This loads the value from the map, but returns an interface that is pointing to the value inserted above, which is a string:

b, _ := a.Load("a")

This will check if b is a T:

c = b.(T)

But b is a string, so the assertion fails.

If you do:

a.Store("a",T("A"))

then the assertion should work, because the type of the value in the map is now a T.

Burak Serdar
  • 46,455
  • 3
  • 40
  • 59