Интерфейс преобразования полей на эквивалентных структурах - PullRequest
0 голосов
/ 28 мая 2019

Существует ли простой способ преобразования структуры, в которой некоторые поля являются «общими» (interface{}), в другой тип, имеющий те же имена полей, но «строго типизированный» (int, string и т. Д. )

Позвольте сказать, что, учитывая определения:

package main

import (
    "fmt"
)

type GenericData struct {
    Hard int
    Soft interface{}
}

type Data struct {
    Hard int
    Soft int
}

type GenericDataGenerator func() GenericData

func generateGenericData() interface{} {
    return GenericData{1, 2}
}

func returnsGenericDataGenerator() interface{} {
    return generateGenericData
}

Требует ли преобразование из GenericData в Data явного приведения всех полей interface{}? Есть ли более простой способ сделать это?

func main() {
    gd := generateGenericData()
    fmt.Println(gd)
    fmt.Println(gd.(GenericData))

    // Doesn't work, but is straightforward
    // fmt.Println(gd.(Data))

    // Works, but is not straight forward
    fmt.Println(Data{gd.(GenericData).Hard, gd.(GenericData).Soft.(int)})


    genDataGenerator := returnsGenericDataGenerator()

    // Doesn't work, but is straightforward
    //genDataGenerator.(GenericDataGenerator)()

    // Works, but is not straight forward
    resp := genDataGenerator.(func() interface{})()
    fmt.Println(resp.(GenericData))
}

Код может быть выполнен в: https://play.golang.org/p/_UVBi5It1FY

1 Ответ

2 голосов
/ 28 мая 2019

Существует ли простой способ преобразования структуры, в которой некоторые поля являются «общими» (interface {}), в другой тип, имеющий те же имена полей, но «строго типизированный» (int, string и т. Д.)?

номер

И это становится очевидным, когда вы понимаете, что interface{} - это не какой-то «универсальный» или «произвольный» тип, а отдельный тип «строго тип», такой как string или int32. Пустой интерфейс interface{} является полностью нормальным типом, как uint16 или map[float32]bool. Это тип интерфейса (в отличие от других примеров, которые представляют собой числовой тип и тип карты), а его набор методов является пустым набором. Он такой же строгий или строго типизированный, как и любой другой тип.

Тот факт, что вы можете присвоить любое значение переменной типа interface{}, не означает, что interface{} так или иначе означает «любой тип». Вы можете присвоить значения 3, -1234 и 435948 (чтобы назвать несколько) для int32. Это разрешено, поскольку допустимый диапазон значений int32 содержит эти значения (3, -1234, 435948). Вы можете присвоить значение типа func(int) string переменной типа interface{}, поскольку допустимый диапазон значений interface{} содержит func(int)string. Это пустая истина, а не «общая».

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