-2

I am able to create a variable 'model' of type 'Sample' as follows:

type Sample struct {
    Id   int    `jsonapi:"attr,id,omitempty"`
    Name string `jsonapi:"attr,name,omitempty"`
}

var model Sample // created successfully

I am able to create it successfully as I already know the struct type (Sample).

However, when I tried to create a similar variable 'a' as follows, I get syntax error:

package main

import (
    "fmt"
    "reflect"
)

type Sample struct {
    Id   int    `jsonapi:"attr,id,omitempty"`
    Name string `jsonapi:"attr,name,omitempty"`
}

func test(m interface{}) {
    fmt.Println(reflect.TypeOf(m)) // prints 'main.Sample'

    var a reflect.TypeOf(m) // it throws - syntax error: unexpected ( at end of statement
}

func main() {

    var model Sample // I have created a model of type Sample
    model = Sample{Id: 1, Name: "MAK"}
    test(model)
}

Please advise how to create a variable of dynamic type in Go.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
MAK
  • 1,915
  • 4
  • 20
  • 44

1 Answers1

1
package main

import (
    "fmt"
    "reflect"
)

type Sample struct {
    Id   int    `jsonapi:"attr,id,omitempty"`
    Name string `jsonapi:"attr,name,omitempty"`
}

func test(m interface{}) {
    fmt.Println(reflect.TypeOf(m)) // prints 'main.Sample'

    a, ok := m.(main.Sample)
    if ok {
        fmt.Println(a.Id)
    }
}

func main() {

    var model Sample // I have created a model of type Sample
    model = Sample{Id: 1, Name: "MAK"}
    test(model)
}

and if you want a little more dynamism, you can use a type switch. Instead of the a, ok := m.(main.Sample), you do

switch a := m.(type) {
    case main.Sample:
        fmt.Println("It's a %s", reflect.TypeOf(m))
    case default:
        fmt.Println("It's an unknown type")
}
Dolanor
  • 822
  • 9
  • 19
  • I wan't to do type assertion as --> a, ok := m.(reflect.TypeOf(m)) rather than --> a, ok := m.(main.Sample) – MAK Feb 17 '20 at 13:59
  • 2
    It is not possible as Go is a statically typed language. So you can only know types that exists at compile time. `reflect` couldn’t know unknown type at compile time. Some trick the system by making any type of data a `map[string]interface{}` so you can create a hierarchical type system. Look in the `encoding/json` package to see how it’s done. – Dolanor Feb 17 '20 at 14:01
  • https://github.com/golang/go/blob/go1.13.7/src/encoding/json/decode.go#L95 – Dolanor Feb 17 '20 at 14:10