Создайте экземпляр нового объекта, используя Go Reflection, и введите assert в интерфейс. - PullRequest
1 голос
/ 26 мая 2020

Я не могу объяснить, почему следующее работает.

package main

import (
    "fmt"
    "reflect"
    "strings"
)

type MyInterface interface {
    someFunc()
}

type Dock struct {
}

func (d *Dock) someFunc() {
}

type Group struct {
    Docks []Dock `better:"sometag"`
}

func foo(model interface{}) {
    v1 := reflect.Indirect(reflect.ValueOf(model))
    for i := 0; i < v1.NumField(); i++ {
        tag := v1.Type().Field(i).Tag.Get("better")
        if strings.HasPrefix(tag, "sometag") {
            inter := v1.Field(i).Interface()
            typ := reflect.TypeOf(inter).Elem()
            fmt.Println("Type:", typ.String())

            // Want to instantiate type like &Dock{} then assign it to some interface,
            // but using reflect
            n := reflect.New(typ)
            _, ok := n.Interface().(MyInterface)            
            fmt.Println("Why is it OK?", ok)

        }
    }
}

func main() {
    g := &Group{}
    foo(g)

    /*var v1, v2 interface{}
    d1 := &Dock{}
    v1 = d1
    _, ok1 := v1.(MyInterface)

    d2 := Dock{}
    v2 = d2
    _, ok2 := v2.(MyInterface)
    fmt.Println(ok1, ok2)*/
}

Он печатает

Type: main.Dock
OK? true

Если это тип Dock, то это не указатель на Dock. Почему он соответствует MyInterface?

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

Где, как пример d2 в комментарии, нет.

1 Ответ

1 голос
/ 26 мая 2020

In go do c for reflect.New

New возвращает значение, представляющее указатель на новое нулевое значение для указанного типа. То есть тип возвращаемого значения - PtrTo (typ).

n := reflect.New(typ)
fmt.Println("Type:", n.String())

Он напечатает Type: <*main.Dock Value> означает, что n является указателем на Dock. Вы пропустите часть, используя reflect.New вернуть указатель.

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