go поддерживает мульти-типы? - PullRequest
0 голосов
/ 29 марта 2020
type MyNumber interface {
    float32, float64, uint, int // this is not supported
}

func PrintNumber(n MyNumber) {
    switch n.(type) {
    case float32, float64, uint, int:
        fmt.Printf("%v\n", n)
    default:
        panic("PrintNumber only supports types float32, float64, uint, int")
    }
}

В go вы можете определить пустой интерфейс, который в основном допускает любой тип

var v interface{}
v = "string"
v = 0.1

Есть ли способ сократить разрешенные типы до указанного c списка типов ?

Что-то вроде

type MyNumber float32, float64, uint, int

или

type MyNumber interface {
    float32, float64, uint, int
}

Это сделано для того, чтобы компилятор мог проверить, будет ли тип поддерживаться функцией.

Ответы [ 2 ]

2 голосов
/ 29 марта 2020

Есть ли способ сократить разрешенные типы до указанного c списка типов [пустого интерфейса]?

Во время компиляции, нет.

Однако вы можете использовать ограничение во время выполнения. Этого следует избегать, когда есть другие альтернативы, так как он не обеспечивает такой большой безопасности.

Это делается в стандартной библиотеке в ряде мест, таких как маршалер json, который требует указатель в качестве цели.

0 голосов
/ 29 марта 2020

Вы не можете принудительно настроить набор конкретных типов во время компиляции так, как вам бы хотелось.

Что вы можете сделать, это использовать интерфейсы. Перечислите методы в интерфейсе, которые вы ожидаете от реализаций. Тогда не имеет значения, какой конкретно тип среды выполнения. Вы взаимодействуете со значением только через интерфейс, который гарантируется во время компиляции, что оно реализуется переданным значением.

Например, если вы ожидаете, что значение предоставит значение int32, используйте этот интерфейс:

type HasInt32 interface {
    Int32() int32
}

func f(i HasInt32) {
    fmt.Println("int32 value:", i.Int32())
}

Не имеет значения, имеет ли переданное значение int32 или float64 в качестве базового типа, или это любой другой сложный тип. Вам нужен int32, и это то, что вы получаете. Разработчики несут ответственность за то, как получить это значение.

Например:

type MyInt32 int32

func (m MyInt32) Int32() int32 { return int32(m) }

type MyStruct struct {
    i int64
}

func (m MyStruct) Int32() int32 { return int32(m.i) }

Тестирование:

var m MyInt32 = 1
f(m)

var s MyStruct = MyStruct{i: 2}
f(s)

Какие выходы (попробуйте на Go Детская площадка ):

int32 value: 1
int32 value: 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...