Невозможно преобразовать интерфейс в структуру на основе условий в Голанге - PullRequest
0 голосов
/ 22 ноября 2018

У меня есть две структуры здесь, как добавлено ниже, я пытаюсь создать одну универсальную функцию, в которой я передаю имя структуры в виде строки.Я недавно начал работать над Go.

type UserDetail struct {
    FirstName string 
    LastName  string 
    Email     string 
    User      int
    ReportsTo int
}

type Matter struct {
    ID        int 
    Name      string 
    Active    bool 
    CreatedAt time.Time
    UpdatedAt time.Time
    UserID    int
}

Ниже добавлен фрагмент функции

func Testing(model string) {
    var temp interface{}
    if model == "UserDetail" {
        fmt.Println("Enterr...")
        temp = UserDetail{}
    }
    temp.FirstName = "Dev"
    temp.Email = "dev@gmail.com"
    fmt.Println(temp) // {"", "", "", 0, 0}
}

Я вызываю функцию как Testing("UserDetail")

Я звонюфункция со структурным именем в виде строки и в определении функции на основе структурного имени я создаю требуемый экземпляр структуры путем преобразования пустого интерфейса.После создания пустого экземпляра структуры, если я пытаюсь добавить к нему какие-либо сохраненные значения и пытаюсь распечатать переменную, он выдает ошибку:

prog.go:33:6: temp.FirstName undefined (type I is interface with no methods)
prog.go:34:6: temp.Email undefined (type I is interface with no methods)

И если я не обновляюсьпеременные поля, это печать переменной со значениями по умолчанию.Моя основная мотивация - преобразовать интерфейс в структуру, основанную на условии, и использовать преобразованную переменную через функцию.

Ответы [ 4 ]

0 голосов
/ 22 ноября 2018

Если вы хотите выполнить код, специфичный для типа, я бы изменил параметр функции Testing на (model interface {}), а затем создал оператор switch, например:

switch model.(type) {
case UserDetail:
      <code>
case Matter:
      <code>
}
0 голосов
/ 22 ноября 2018

Иди никогда не работает так.Потому что го типизирован статически.Следовательно, во время компиляции он не может понять temp.FirstName = "Dev", потому что temp - это просто интерфейс {} (который может содержать любое значение).

Но из-за ряда особенностей он "кажется" динамически типизированным.Вы можете выбрать ответ по @xpare или объявить отдельную переменную для каждой структуры.

0 голосов
/ 22 ноября 2018

Вы хотите установить значения полей для структуры UserDetail, которую вы присвоили interface{} temp.Но поле принадлежало структуре UserDetail, а не temp interface{}.Вот почему, во-первых, вам нужно получить структуру UserDetail из interface{} и установить ожидаемые значения полей.Также используйте знак указателя, чтобы убедиться, что значения установлены в исходную UserDetail структуру.А затем напечатайте temp interface{}.Go напечатает исходные значения.Поэтому используйте вот так:

func Testing(model string) {
    var temp interface{}
    if model == "UserDetail" {
        fmt.Println("Enterr...")
        temp = &UserDetail{}
    }
    u := temp.(*UserDetail)
    u.FirstName = "Dev"
    u.Email = "dev@gmail.com"
    //temp = u
    fmt.Println(temp) // {"", "", "", 0, 0}
}

Редактировать

Поскольку ваше движение составляет The objective is that users would define their own structs and call a function similar to the Testing and I would get the data from the correct table in a database and then return the interface filled with data, используйте это:

package main

import (
    "fmt"
    "time"
)

type UserDetail struct {
    FirstName string
    LastName  string
    Email     string
    User      int
    ReportsTo int
}

type Matter struct {
    ID        int
    Name      string
    Active    bool
    CreatedAt time.Time
    UpdatedAt time.Time
    UserID    int
}

func Testing(model string) interface{} {
    var temp interface{}
    if model == "UserDetail" {
        fmt.Println("Enter for UserDetail...")

        temp = &UserDetail{
            FirstName: "Dev",
            Email: "dev@gmail.com",
        }
    } else if model == "Matter" {
        fmt.Println("Enter for Matter...")

        temp = &Matter{
            Name: "Joe",
            Active: true,
            CreatedAt: time.Now(),
        }
    }

    return temp
}

func main() {
    var temp interface{}
    temp = Testing("UserDetail")
    fmt.Println(temp) // {"Dev", "", "dev@gmail.com", 0, 0}

    temp = Testing("Matter")
    fmt.Println(temp) // {0, "Joe", true, current timestamp, default timestamp, 0}
}
0 голосов
/ 22 ноября 2018

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

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

Утверждение типа обеспечивает доступ к базовому конкретному значению значения интерфейса.

Пример использования:

tempConcreteValue := temp.(UserDetail)
tempConcreteValue.FirstName = "Dev"
tempConcreteValue.Email = "dev@gmail.com"

fmt.Println(tempConcreteValue) // {"", "", "", 0, 0}

Как мы можемсм. код выше, .(UserDetail) в конце temp вернет конкретное значение интерфейса temp в типе UserDetail.

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