Решение для утверждения типа без обобщений с Golang? - PullRequest
0 голосов
/ 02 мая 2018

Я использую gorm, и он допускает много типов данных, таких как int, uint, int8, uint8 ....

Тогда у меня есть плагин в шаблоне, как это:

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)
    }

Преобразует все целочисленные типы в форматированную строку. Так что мне делать? Вывести список всех поддерживаемых gorm типов int и привести его к int64?

Я много дней искал решение, преобразующее interface{} в его истинный тип без использования утверждения типа, но не сработало.

Ответы [ 3 ]

0 голосов
/ 02 мая 2018

Судя по вашим комментариям, вам нужно преобразовать любой числовой тип в строку. Это легко сделать с помощью fmt.Sprint:

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

Но это не имеет ничего общего с ГОРМ.

С другой стороны, если ваша проблема в том, что GORM возвращает непредсказуемый тип, просто измените оператор select, чтобы он всегда возвращал строку. Например, для MySQL что-то вроде:

SELECT CAST(someNumberColumn AS VARCHAR) AS stringColumn

или

SELECT CAST(someNumberColumn AS INT) AS intColumn
0 голосов
/ 02 мая 2018

Я не думаю, что это проблема с го или горм. Я немного сбит с толку тем, что вы сохраняете свои временные метки Unix в разных форматах. Кстати, метка времени Unix 32-битная, поэтому нет смысла конвертировать (и сохранять в первую очередь) любые 8-битные значения.

Решением было бы использование единого типа данных (int64) для всех временных меток в ваших структурах. После этого ваша функция форматирования может принимать int64 вместо interface{}, без необходимости каких-либо утверждений типа.

0 голосов
/ 02 мая 2018

Я не использовал gorm, но думаю, что что-то подобное может решить вашу проблему:

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
}

Вместо того, чтобы перечислять все потенциальные типы, он просто преобразует interface{} в string, используя fmt.Sprint(), а затем преобразует string в int64, используя strconv.ParseInt().

...