Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Go reflect和接口类型assert实例化新的obj_Go_Go Reflect - Fatal编程技术网

使用Go reflect和接口类型assert实例化新的obj

使用Go reflect和接口类型assert实例化新的obj,go,go-reflect,Go,Go Reflect,我无法解释为什么下面的方法有效 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(mo

我无法解释为什么下面的方法有效

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)*/
}
如果它是Dock类型,那么它不是指向Dock的指针。为什么它符合
MyInterface

如注释中的d2示例所示。

go
for
reflect.New

New返回一个值,该值表示指向 指定的类型。也就是说,返回值的类型是PtrTo(typ)

它将打印
Type:
表示
n
Dock
的指针。您使用
reflect错过了部分。New
返回指针。

go doc reflect.New:“New返回一个值,表示指向指定类型的新零值的指针。也就是说,返回值的类型是PtrTo(typ)。”,逐字逐句地阅读文档。
Type: main.Dock
OK? true
n := reflect.New(typ)
fmt.Println("Type:", n.String())