簡體   English   中英

如何從嵌入式結構的方法中反映包含struct的字段?

[英]How to reflect fields of containing struct from a method of the embedded struct?

這個程序的輸出是map [] ,但我想要map [Id:true name:true]

我正在嘗試干掉我的一些SQL CRUD代碼,並認為嵌入一個處理讀寫數據庫的持久性結構會很好。 在下面的示例中,持久性結構將是Inner,我的模型將是Outer。 謝謝!

http://play.golang.org/p/fsPqJ-6aLI
package main

import (
    "fmt"
    "reflect"
)

type Inner struct {
}

type Outer struct {
    Inner
    Id   int
    name string
}

func (i *Inner) Fields() map[string]bool {
    typ := reflect.TypeOf(*i)
    attrs := make(map[string]bool)

    if typ.Kind() != reflect.Struct {
        fmt.Printf("%v type can't have attributes inspected\n", typ.Kind())
        return attrs
    }

    // loop through the struct's fields and set the map
    for i := 0; i < typ.NumField(); i++ {
        p := typ.Field(i)
        if !p.Anonymous {
            v := reflect.ValueOf(p.Type)
            v = v.Elem()
            attrs[p.Name] = v.CanSet()

        }
    }

    return attrs
}

func main() {
    val := Outer{}
    fmt.Println(val.Fields()) // prints map[], but I want map[Id:true name:true]
}

你不能。 你專門在Inner上調用一個方法,它不知道它嵌入的位置。 嵌入不是繼承,它是簡單的自動委托。

您可能希望在公共持久性接口中查看這些包裝的方向,或者甚至是可以處理持久化數據類型的通用函數。


現在,如果你真的想嘗試這個,你可以通過指針地址訪問外部結構,但是你需要知道你想要訪問的外部類型,這意味着你無法通過反射獲得它。

outer := (*Outer)(unsafe.Pointer(i))
typ := reflect.TypeOf(*outer)

看起來你可以這樣做: 如果你創建一個接口並將有問題的對象作為arg傳遞給函數,則reflect會獲得對象的正確外部類型:

package main

import (
    "fmt"
    "reflect"
)

type InType interface {
    Fields(obj InType) map[string]bool
}

type Inner struct {
}

type Outer struct {
    Inner
    Id   int
    name string
}

func (i *Inner) Fields(obj InType) map[string]bool {
    typ := reflect.TypeOf(obj).Elem()
    attrs := make(map[string]bool)

    if typ.Kind() != reflect.Struct {
        fmt.Printf("%v type can't have attributes inspected\n", typ.Kind())
        return attrs
    }

    // loop through the struct's fields and set the map
    for i := 0; i < typ.NumField(); i++ {
        p := typ.Field(i)
        if !p.Anonymous {
            v := reflect.ValueOf(p.Type)
            v = v.Elem()
            attrs[p.Name] = v.CanSet()

        }
    }

    return attrs
}

func main() {
    val := Outer{}
    fmt.Println(val.Fields(&val)) // prints map[Id:true name:true]
}

https://play.golang.org/p/0i3gNrMeSXa

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM