0

I'm trying to do something like this:

Struct to save setting:

type Setting struct{
    Name            string
    DataType        types.Type
}

Setting definition:

var SETTING_DebugLogging Setting = Setting{
    Name: "DebugLogging",
    DataType: bool,    <-- This is wrong
}

and then, get the value from a Map using reflection and the value on DataType:

// Get a value setting, or his default
func (s Setting) Get() interface{}{
    val, ok := settings[s].(s.DataType)    <-- This is wrong
    if !ok{
        return s.DefaultValue.(s.DataType)   <-- This is wrong
    }

    return val
}

I wan't to do this way, to ensure "Get" is always returning the value expected for that setting. If it's an invalid one, returns the default value, so I don't have to check again in code.

Just doing var := setting.Get().(setting.DataType) would be enough, no checks needed.

I've also tried to use reflection.kind to save the type of the setting. And that works for storing it, but I can't use it to parse latter:

This is ok with reflect.Kind:

// Game to launch
var SETTING_GameToLaunch Setting = Setting{
    Name: "GameToLaunch",
    DataType: reflect.Bool,
    DefaultValue: 2,
}

But this doesn't work latter:

func (s Setting) Get() interface{}{
    val, ok := settings[s].(s.DataType)

So. Any ideas on how I can do that? Store a type, and use latter with reflection?

  • I would strongly advise against this design if you can possibly avoid it. This is more like Java code than Go code and will lead to further frustration as implementation continues. – Adrian Feb 03 '20 at 17:03

1 Answers1

2

You could use / store reflect.Type. In Get(), you may check if the value is of that type, e.g. reflect.TypeOf(settings[s]) == s.DataType.

But it would be simpler to just use a struct, and enumerate settings as fields. That will be type safe, and you don't have to use type assertions when using / getting setting values.

icza
  • 389,944
  • 63
  • 907
  • 827
  • reflect.Type doesn't work either. I can't store that. Comparission works, but I can't save a reflect.type value. And yes. That's the way I did for other settings in my app, but In this ones, I need to have diferent permissions. (Read/Write). I simplified the struct, but there are more things there, so this is the best approach I've found. The problem is that I don't know how to store/assign a type – Facundo Curti Feb 02 '20 at 16:42
  • @FacundoCurti _"I don't know how to store/assign a type"_ Which part is you don't know? You may create `reflect.Type` using `reflect.TypeOf()`, e.g. `reflect.TypeOf(false)` to have the type descriptor for `bool`. – icza Feb 02 '20 at 16:45
  • Ohh. Lol. That's how. Thx a lot :D I guess there is no way to create a Type, without using reflect.TypeOf()? Something like var := Type(string). I've got enforced to use even casting in some cases: DataType: reflect.TypeOf(uint32(0)) – Facundo Curti Feb 02 '20 at 16:52
  • @FacundoCurti Yes, you need a value, you can't write`reflect.TypeOf(bool)`. Also as you wrote, if you need a type other than the default type of an untyped constant, you need explicit type conversion, such as `reflect.TypeOf(uint32(0))`. Also see: [Golang TypeOf without an instance and passing result to a func](https://stackoverflow.com/questions/48939416/golang-typeof-without-an-instance-and-passing-result-to-a-func/48944430#48944430) – icza Feb 02 '20 at 17:34