Задать вопрос

Приведение типов в GO, можно сделать красивее?

Нужна функция которая:
- на входе принимает, что угодно
- на выходе, если это возможно должно возвращаться число типа int64
Получился такой код:
func interToInt64(inp interface{}) (int64, error) {
	switch inp.(type) {
	case int:
		return int64(inp.(int)), nil
	case int8:
		return int64(inp.(int8)), nil
	case int16:
		return int64(inp.(int16)), nil
	case int32:
		return int64(inp.(int32)), nil
	case int64:
		return inp.(int64), nil
	case uint:
		return int64(inp.(uint)), nil
	case uint8:
		return int64(inp.(uint8)), nil
	case uint16:
		return int64(inp.(uint16)), nil
	case uint32:
		return int64(inp.(uint32)), nil
	case uint64:
		return int64(inp.(uint64)), nil
	case string:
		return strconv.ParseInt(inp.(string), 10, 64)
	default:
		return 0, fmt.Errorf("unsupported type %T", inp)
	}
}

Можно ли решить эту задачу по-аккуратнее? Напрягает, что приходится явно перечислять все возможные подтипы интов.
  • Вопрос задан
  • 837 просмотров
Подписаться 3 Средний Комментировать
Решения вопроса 1
Можно сделать так, будет меньше кода. В остальном, ничего не уменьшить, ибо го довольно низкоуровневый язык.
func interToInt64(inp interface{}) (int64, error) {
	switch v := inp.(type) {
	case int:
		return int64(v), nil
	case int8:
		return int64(v), nil
	case int16:
		return int64(v), nil
	case int32:
		return int64(v), nil
	case int64:
		return v, nil
	case uint:
		return int64(v), nil
	case uint8:
		return int64(v), nil
	case uint16:
		return int64(v), nil
	case uint32:
		return int64(v), nil
	case uint64:
		return int64(v), nil
	case string:
		return strconv.ParseInt(v, 10, 64)
	default:
		return 0, fmt.Errorf("unsupported type %T", inp)
	}
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
zoonman
@zoonman
⋆⋆⋆⋆⋆
Идея такой функции не самая здравая. Конверсия некоторых чисел будет вызывать непредсказуемое поведение.
Что-то в духе uint64(2^32+1) может здорово пошатать ваш int64.
Я советую вам не играть с огнем и рассмотреть альтернативные варианты работы с данными.
Ответ написан
Комментировать
devalone
@devalone
̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
Ещё вариант:

package main

import (
	"fmt"
	"strconv"
)

func main() {
	fmt.Println(interToInt64(1))
	fmt.Println(interToInt64(int64(10)))
	fmt.Println(interToInt64(int8(10)))
	fmt.Println(interToInt64(15.5))
	fmt.Println(interToInt64("15.5"))
	fmt.Println(interToInt64("15"))
	fmt.Println(interToInt64(uint(10)))
	fmt.Println(interToInt64(uint64(999)))
	fmt.Println(interToInt64(uint64(18446744073709551615)))
}

func interToInt64(inp interface{}) (int64, error) {
	strVal := fmt.Sprint(inp)
	if res, err := strconv.ParseInt(strVal, 10, 64); err == nil {
		return res, nil
	}
	return 0, fmt.Errorf("unsupported type %T with value %v", inp, inp)
}


https://play.golang.org/p/Q0_5UIoU3KP
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы