Общая атрибуция поля X, представленная в разных типах - PullRequest
0 голосов
/ 03 июля 2019

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

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

Допустим, у нас есть:

type v1 struct{
  a int
}

и

type v2 struct{
 a int
 b string
}

я хотел бы сделать что-то вроде

func main(){
 var v1 v1
 var v2 v2

 foo(v1)
 foo(v2)
}


func foo (root interface{}){
  root.a = x
}

это возможно? или есть другой способ?

редактировать: 1 - это не дубликат «Получить все поля из интерфейса», так как моя проблема не в том, чтобы выяснить, с каким типом я имею дело, а в том, чтобы манипулировать / обрабатывать различные типы одинаково. 2 - это может быть дубликатом «как написать функцию для обработки двух типов входных данных в golang», но предоставленный ответ не решает мою проблему.

1 Ответ

0 голосов
/ 04 июля 2019

Используйте анонимные поля, методы и интерфейсы.Вы можете определить новую структуру, которая содержит все общие свойства для всех других структур.Затем можно определить интерфейс для этой общей структуры, в которой перечислены все методы для обработки общих свойств.Наконец, в предыдущих структурах вам нужно всего лишь заменить все общие поля этим новым интерфейсом.На этом этапе вы можете писать универсальные функции, которые принимают интерфейс в качестве входных данных и обрабатывают внутренние общие поля с помощью открытых методов.

type SettableA interface{
    SetA(int)
    A() int
}

type sharedA struct {
    a int
}

func (s *sharedA) SetA(val int) {
    s.a = val
}

func (s *sharedA) A() int {
    return s.a
}

type v1 struct {
    SettableA 
}

type v2 struct {
    SettableA 
    b string
}

func foo(root SettableA) {
    root.SetA(5)
}

func main() {
    v1var := v1{
        SettableA: &sharedA{},
    }
    foo(v1var)
    v2var := v2{
        SettableA: &sharedA{},
        b: "test",
    }
    foo(v2var)
    fmt.Printf("V1: %v\nV2: %v\n", v1var.A(), v2var.A())
}

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

https://play.golang.org/p/BgxYrbGE426

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