Как преобразовать значение интерфейса {} в статически типизированное значение, используя функцию в golang? - PullRequest
0 голосов
/ 12 октября 2018

В стандартной библиотеке я могу сделать преобразование JSON в типизированный объект, используя указатель.Теперь вопрос в том, как создать подобный метод, например json.Marshal, для преобразования v interface{} в типизированный объект?Нужно ли мне использовать reflect для этого?

Пожалуйста, посмотрите ниже фрагменты кода, и я ищу человека, который мог бы заполнить TODO в пакете home.Спасибо.

package main

import (
    "encoding/json"
    "fmt"

    "./home"
)

type Dog struct {
    Name         string
    FavoriteGame string
}

func (dog Dog) Greet() {
    dog.Bark()
}

func (dog Dog) Bark() {
    if len(dog.Name) == 0 {
        panic("This dog has no name!")
    }
    fmt.Printf("%s < Wo! Wo! %s!\n", dog.Name, dog.FavoriteGame)
}

type Cat struct {
    Name         string
    FavoriteMeat string
}

func (cat Cat) Greet() {
    cat.Purr()
}

func (cat Cat) Purr() {
    if len(cat.Name) == 0 {
        panic("This cat has no name!")
    }
    fmt.Printf("%s < purrrrrrr... %s...\n", cat.Name, cat.FavoriteMeat)
}

func main() {
    // JSON decoder works here
    j := []byte(`{"Name": "Jack", "FavoriteGame": "Swim"}`)
    var jack Dog
    json.Unmarshal(j, &jack)
    jack.Bark()

    // Similarly, how do I implement `home` to make the below work?
    dogHome := home.Home{Dog{Name: "Bullet", FavoriteGame: "Catch The Ball"}}
    var bullet Dog
    dogHome.GetPet(&bullet)
    bullet.Bark()

    catHome := home.Home{Cat{Name: "Ball", FavoriteMeat: "Tuna"}}
    var ball Cat
    catHome.GetPet(&ball)
    ball.Purr()
}

Другой пакет:

package home

type Pet interface {
    Greet()
}

type Home struct {
    Pet Pet
}

func (h Home) GetPet(v interface{}) {
    // TODO: What should I do here?
    v = h.Pet
}

1 Ответ

0 голосов
/ 12 октября 2018

Используйте пакет отражение :

func (h Home) GetPet(v interface{}) {
    reflect.ValueOf(v).Elem().Set(reflect.ValueOf(h.Pet))
}

Выражение reflect.ValueOf(v).Elem() - это значение отражения, на которое указывает аргумент.Метод Set устанавливает это значение.

Запустите его на игровой площадке

Лучшим подходом является использование утверждений типа непосредственно в приложении:

dogHome := Home{Dog{Name: "Bullet", FavoriteGame: "Catch The Ball"}}
bullet := dogHome.Pet.(Dog)
bullet.Bark()

catHome := Home{Cat{Name: "Ball", FavoriteMeat: "Tuna"}}
ball := catHome.Pet.(Cat)
ball.Purr()

Запустите его на детской площадке

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