Как преобразовать структуру в другую структуру с меньшим количеством полей - PullRequest
4 голосов
/ 19 сентября 2019

Я пытаюсь скопировать структуру типа Big в тип Small без явного создания новой структуры типа Small с теми же полями.

Я пытался найти другие похожие проблемы, такие как this и это и все преобразования между различными типами структур происходят, только если структуры имеют одинаковые поля.

Вот пример того, что я пытался сделать:

// Big has all the fields that Small has including some new ones.
type Big struct {
    A int
    B string
    C float
    D byte
}

type Small struct {
    A int
    B string
}

// This is the current solution which I hope to not use.
func ConvertFromBigToSmall(big Big) Small {
    return Small{
        A: big.A,
        B: big.B,
    }
}

Я ожидал, что смогу сделать что-то подобное, но это не сработает:

big := Big{}
small := Small(big)

Есть ли способ преобразования между Big в Small (и, возможно, даже порок?-верса) без использования функции Convert?

Ответы [ 4 ]

5 голосов
/ 19 сентября 2019

Для этого нет встроенной поддержки.Если вам это действительно нужно, вы можете написать общую функцию, которая использует отражение для копирования полей.

Или вы можете изменить дизайн.Если Big - это Small плюс некоторые другие дополнительные поля, почему бы не использовать повторно Small в Big?

type Small struct {
    A int
    B string
}

type Big struct {
    S Small
    C float
    D byte
}

Тогда, если у вас есть структура Big, у вас также естьSmall: Big.S.Если у вас есть Small, и вам нужен Big: Big{S: small}.

Если вы беспокоитесь о том, чтобы потерять удобство более коротких имен полей или других маршаллированных результатов, тогда используйте встраивание вместо именованного поля:

type Big struct {
    Small // Embedding
    C float
    D byte
}

Тогда они также действительны: Big.A, Big.B.Но если вам нужно значение Small, вы можете обратиться к встроенному полю, используя в качестве имени поля неквалифицированное имя типа, например, Big.Small (см. Тип встроенной структуры Golang ).Аналогично, для создания Big из Small: Big{Small: small}.

2 голосов
/ 19 сентября 2019

Есть ли способ преобразования между Big в Small (и, возможно, даже наоборот) без использования функции Convert?

Единственный вариант -сделайте это вручную, как вы сделали.Заверните ли вы это в функцию или нет, это вопрос вкуса / обстоятельств.

0 голосов
/ 19 сентября 2019

вы можете сделать что-то вроде этого:

package main

import (
    "fmt"
)

type Big struct {
    Small
    C float32
    D byte
}

type Small struct {
    A int
    B string
}

func main() {
    big := new(Big)
    big.A = 1
    big.B = "test"
    big.C = 2.3
    fmt.Printf("big struct: %+v", big)
    fmt.Println()
    small := big.Small
    fmt.Printf("small struct: %+v", small)
    fmt.Println()
}

вывод:

big struct: &{Small:{A:1 B:test} C:2.3 D:0}
small struct: {A:1 B:test}

детская ссылка: https://play.golang.org/p/-jP8Wb--att

0 голосов
/ 19 сентября 2019

Боюсь, прямого пути для этого не существует.То, что вы сделали, - правильный путь.

Вы можете попытаться записать первый объект в JSON, а затем попытаться проанализировать его обратно ко второму объекту.Хотя я бы не пошел по этому пути.

Еще один способ, который является конкретным, заключается в том, что Большой объект унаследует Маленький объект.тогда вы можете опускать руки.Опять же, я бы не стал этого делать, но если бы вы должны ...

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