Hacker News new | past | comments | ask | show | jobs | submit login

I'm new to Go and actually and don't do professional IT work but I immediately felt the need for having a type that allowed me to store any type.

My use case was/(still is) writing a spreadsheet where a user can enter different stuff in a cell and I want to store the value in an underlying data type. I now ended up storing everything as string because I couldn't figure out an efficient way to implement it.

My goal would have been to have one generic type that can store the cell types text and number which I can store in an array. This generic type could then implement an interface method like format() which calls a different format method depending on the type the cell has.

I played around with interface and reflect.TypeOf but lost too much performance compared to just storing everything in a string. Strings on the other hand now fill up my memory with stuff I don't need - at least that is my impression.

I don't have programming experiences so maybe I misunderstand the discussion or just overlooked a way to solve my issue in an efficient way. So sorry if the example I mentioned something easily doable in go.




> My goal would have been to have one generic type that can store the cell types text and number which I can store in an array.

FWIW generics wouldn't help you with that, "sum types" would. A sum type is a souped-up enum which can store associated data alongside the "enum tag", so you can have e.g.

    enum Foo {
        Bar(String),
        Baz(u8, u32),
        Qux,
    }
and at runtime you ask which "value" is in your enum:

    match foo {
        Bar(s) => // got a Bar with as string inside
        Baz(n, _) => // got a Baz, took the first number
        Qux => // Got a Qux, it stores no data
    }
(and in most languages the compiler will yell at you if you forget one of the variants).

So for your use case you'd have e.g.

    enum Value {
        Boolean(bool),
        Integer(u32),
        String(String),
        // etc…
    }
> I played around with interface and reflect.TypeOf but lost too much performance compared to just storing everything in a string.

Maybe try a struct with an explicit tag rather than reflection? e.g.

    type ValueType int
    const (
        TYPE1 ValueType = iota
        TYPE2
        TYPE3
        // … one for each concrete type you want to wrap

    )
    struct Value {
        type ValueType
        value interface {}
    }
and then you can

    switch value.type {
    case TYPE1:
        value.value.(Type1)
    case TYPE2:
        value.value.(Type2)
    // etc...
I'd expect reflect.TypeOf to be very expensive, this is a check + a cast.


Thanks for that information. I had thought enums can only be used as named types. Good to know they can hold data as well. I had though of that struct as well (ok, not in that professional way with types as constants and iota:-)) but found it a bit annoying that I have to store a type myself although the type itself should already have the type information somewhere itself - consequently that information is stored reduntantly. But I'll definitely try that. Thanks.


> I had thought enums can only be used as named types. Good to know they can hold data as well.

That depends on the language, and enums being sum types also depends on the language.

* Rust and Swift enums are sum types (they can hold data and every variant can hold different stuff), there is also a ton of (mostly functional) languages with sum types not called enum: Haskell, F#, OCaml, … there are also languages which replicate them via other structures (sealed classes in Kotlin, case classes in Scala).

* java enums (a bare "enum" is the C one) can hold data but every variant must hold data of the same type so you'd need up/down casts

* C++, C# and C enums can't hold data

Go does not have enums.


C++17 has support for sum types via std::variant.


Minor nitpick: case classes in Scala are product types, not sum types. I think you meant "sealed traits".


The combination of both really.


FWIW, "enums" are in most languages you'll run into somewhat distinct from "enum types".




Registration is open for Startup School 2019. Classes start July 22nd.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: