Как изменить значение пустого интерфейса, который передается как ссылка на структуру в golang? - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть много структур, которые передаются как указатель на функцию AutoFilled. каждая структура отличается от другой. но некоторые поля такие же, как "creator", "createon", "edition" .., есть ли способ изменить общее поле в функции автозаполнения?

package main

import (
    "fmt"
    "time"
)

type User struct {
    ID string
    Creator string
    CreateOn time.Time
    Edition int
    Name string
    Password string
}

type Book struct {
    ID string
    Creator string
    CreateOn time.Time
    Edition int
    Name string
    ISBN string

}

func AutoFilled(v interface{}) {
    // Add Creator
    // Add CreateOn
    // Add Edition (Version) [new is zero, edit increase 1]
}

func main() {
    user := User{}
    book := Book{}

    AutoFilled(&user)
    AutoFilled(&book)

    fmt.Println(user)
    fmt.Println(book)

    fmt.Println("Thanks, playground")
}

Ответы [ 2 ]

2 голосов
/ 10 февраля 2020

@ AJR дал очень хороший вариант. вот альтернативный подход.

Для каждой структуры (Book и User) создайте метод с именем New<StructName. Взяв Book в качестве примера

func NewBook() *Book {
    return &Book {
        //you can fill in default values here for common construct
    }
} 

Вы можете дополнительно расширить этот шаблон, создав структуру Common и передав ее в NewBook при ее создании, т.е.

func NewBook(c Common) *Book {
    return &Book {
        Common: c
        //other fields here if needed
    }
}

Теперь в вашем основном коде вы сделаете это

func main() {
    c := NewCommon() //this method can create common object with default values or can take in values and create common object with those
    book := NewBook(c)
    //now you don't need autofill method

    fmt.Println("Thanks, playground")
}
2 голосов
/ 10 февраля 2020

Похоже, вам просто нужна структура Common, встроенная (иногда называемая mixin) в другие структуры.

type Common struct {
    ID string
    Creator string
    CreateOn time.Time
    Edition int
}
type User struct {
    Common
    Name string
    Password string
}

type Book struct {
    Common
    Name string
    ISBN string
}

Также я бы сделал функцию AutoFilled методом на Common. (При использовании интерфейса вы теряете безопасность типов.)

func (c *Common)Autofill() {
    // set fields on Common struct
}

func main() {
        user := &User{}
        user.Autofill()

...