TomSawyer
TomSawyer

Reputation: 3820

Solution for type assertion without generics with Golang?

I'm using gorm, and it allows many data types like int, uint, int8, uint8 ....

Then I have a plugin in template like this:

f["UNIX2STR"] = func(t interface{}, f string) string {
        switch t.(type) {
        case int:
            return time.Unix(int64(t.(int)), 0).Format(f)
        case uint:
            return time.Unix(int64(t.(uint)), 0).Format(f)
        case uint8:
            return time.Unix(int64(t.(uint8)), 0).Format(f)
        case *int:
            return time.Unix(int64(*t.(*int)), 0).Format(f)
        case *uint:
            return time.Unix(int64(*t.(*uint)), 0).Format(f)
        case *uint8:
            return time.Unix(int64(*t.(*uint8)), 0).Format(f)
        .....
        default:
            return ""
        }
        // return time.Unix(int64(t), 0).Format(f)
    }

It converts all integer types to formatted string. So what am I suppose to do? List all gorm supported int types and cast it to int64?

I have searched many days for solution convert interface{} to its true type without using type assertion but didn't work.

Upvotes: 0

Views: 1100

Answers (3)

mbuechmann
mbuechmann

Reputation: 5780

I do not think that this is a problem with go or gorm. I am a bit baffled that you save your unix timestamps in many different formats. BTW, A unix timestamp is 32 bit, so there is no point in converting (and saving in the first place) any 8 bit ints.

A solution would be to use a unified data type (int64) for all timestamps in your structs. After that your formatting func can accept int64 instead ofinterface{}, without the need of any type assertions.

Upvotes: 0

Jonathan Hall
Jonathan Hall

Reputation: 79794

Based on your comments, it sounds like you're concerned with converting any numeric type to a string. This is easily done with fmt.Sprint:

stringValue := fmt.Sprint(i) // i is any type

But this has nothing to do with GORM.

On the other hand, if your problem is that GORM is returning an unpredictable type, just change your select statement to always return a string. For example, for MySQL, something like:

SELECT CAST(someNumberColumn AS VARCHAR) AS stringColumn

or

SELECT CAST(someNumberColumn AS INT) AS intColumn

Upvotes: 1

Tom Wright
Tom Wright

Reputation: 2861

I've not used gorm, but I think that something like this could solve your problem:

func formatUnix(t interface{}, f string) (string, error) {
    timestampStr := fmt.Sprint(t)
    timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
    if err != nil {
        return "", err
    }
    return time.Unix(timestamp, 0).Format(f), nil
}

Rather than listing all potential types, it simply converts the interface{} to a string using fmt.Sprint() and then convert the string to int64 using strconv.ParseInt().

Upvotes: 1

Related Questions