গোতে কোনও স্ট্রাক্টের ক্ষেত্রগুলি দিয়ে ইটারেট করুন


107

মূলত, এর ক্ষেত্রগুলির মানগুলির মধ্য দিয়ে পুনরাবৃত্তি করার একমাত্র উপায় (যা আমি জানি) structএটি এর মতো:

type Example struct {
    a_number uint32
    a_string string
}

//...

r := &Example{(2 << 31) - 1, "...."}:
for _, d:= range []interface{}{ r.a_number, r.a_string, } {
  //do something with the d
}

আমি ভাবছিলাম, যদি আরও উন্নততর ও বহুমুখী উপায় অর্জনের উপায় থাকে তবে []interface{}{ r.a_number, r.a_string, }আমার প্রতিটি পরামিতি পৃথকভাবে বা বিকল্পভাবে তালিকাবদ্ধ করার দরকার নেই, কোনও কাঠামোর মধ্য দিয়ে লুপ করার আরও ভাল উপায় আছে কি?

আমি reflectপ্যাকেজটি সন্ধান করার চেষ্টা করেছি , তবে আমি একটি প্রাচীরকে আঘাত করেছি, কারণ আমি একবারে পুনরুদ্ধার করার পরে নিশ্চিত কি না reflect.ValueOf(*r).Field(0)

ধন্যবাদ!


5
প্রতিবিম্ব সম্পর্কিত একটি আকর্ষণীয় নিবন্ধটি এখানে: blog.golang.org/laws-of-reflection নিবন্ধের উদাহরণের একটি অনুসরণ করে: play.golang.org/p/_bKAQ3dQlu নোট করুন যে আপনি অ-রপ্তানি ক্ষেত্রগুলি দেখতে পারবেন না
প্রতিবিম্ব

উত্তর:


126

আপনি reflect.Valueক্ষেত্রটি পুনরুদ্ধার করার পরে আপনি Field(i)কল করে একটি ইন্টারফেস মান পেতে পারেন Interface()। ইন্টারফেস মান বলেছে তারপর ক্ষেত্রের মান প্রতিনিধিত্ব করে।

ক্ষেত্রের মানকে কংক্রিটের ধরণ হিসাবে রূপান্তর করতে কোনও ফাংশন নেই, যেমন আপনি জানেন যে কোনও জেনেরিক নেই। সুতরাং, সেই ক্ষেত্রের ধরণ (যা ক্ষেত্রের উপর নির্ভর করে অবশ্যই পরিবর্তন হয়) এর GetValue() T সাথে স্বাক্ষর নিয়ে কোনও ফাংশন নেই T

আপনি যেতে যেতে সবচেয়ে কাছাকাছি হ'ল GetValue() interface{}এবং এটি হ'ল reflect.Value.Interface() অফার।

প্রতিচ্ছবি ( খেলুন ) ব্যবহার করে স্ট্রাক্টে প্রতিটি রফতানি হওয়া ক্ষেত্রের মানগুলি কীভাবে পাবেন তা নিম্নলিখিত কোডটি ব্যাখ্যা করে :

import (
    "fmt"
    "reflect"
)

func main() {
    x := struct{Foo string; Bar int }{"foo", 2}

    v := reflect.ValueOf(x)

    values := make([]interface{}, v.NumField())

    for i := 0; i < v.NumField(); i++ {
        values[i] = v.Field(i).Interface()
    }

    fmt.Println(values)
}

24
হ্যাঁ কারণ যান জেনেরিক প্রয়োজন হয় না। কাশি, কাশি :-) ক্ষেত্রের ধরণ পাওয়ার উপায় আছে কি?
ইউ আভালোস

1
reflect.Value.Type()হ্যাঁ, মাধ্যমে তবে নোট করুন যে প্রকারগুলি প্রথম শ্রেণির নাগরিক নয়, তাই আপনি কেবল ব্যবহার করে সেই ধরণের নতুন মানগুলি ইনস্ট্যান্ট করতে পারেন reflect
নেমো

6
v.Field(i).Interface()প্যানিকগুলি যদি আপনি অ রপ্তানি করা ব্যক্তিগত ক্ষেত্রগুলিতে অ্যাক্সেস করার চেষ্টা করেন। শুধু সাবধান হন :)
টারিয়ান

10
v.Field(i).CanInterface() অপরিশোধিত ক্ষেত্রগুলির ক্ষেত্রে একটি ব্যবহার করা আতঙ্ক এড়াতে পারে।
পেড্রাম এসমাইলি

1
আমি ক্ষেত্রের নাম কীভাবে পেতে পারি?
সত্যেশ

33

যদি আপনি কোনও কাঠামোর ক্ষেত্র এবং মানগুলির মাধ্যমে আইট্রেট করতে চান তবে আপনি নীচের গো কোডটি একটি রেফারেন্স হিসাবে ব্যবহার করতে পারেন।

package main

import (
    "fmt"
    "reflect"
)

type Student struct {
    Fname  string
    Lname  string
    City   string
    Mobile int64
}

func main() {
    s := Student{"Chetan", "Kumar", "Bangalore", 7777777777}
    v := reflect.ValueOf(s)
    typeOfS := v.Type()

    for i := 0; i< v.NumField(); i++ {
        fmt.Printf("Field: %s\tValue: %v\n", typeOfS.Field(i).Name, v.Field(i).Interface())
    }
}

চালনা করুন খেলার মাঠ

দ্রষ্টব্য: যদি আপনার স্ট্রাক্টের ক্ষেত্রগুলি রফতানি না করা হয় তবে v.Field(i).Interface()আতঙ্ক দিনpanic: reflect.Value.Interface: cannot return value obtained from unexported field or method.


0

চেতন কুমার সমাধান গ্রহণ এবং যদি আপনাকে ক প্রয়োগ করতে হয় applymap[string]int

package main

import (
    "fmt"
    "reflect"
)

type BaseStats struct {
    Hp           int
    HpMax        int
    Mp           int
    MpMax        int
    Strength     int
    Speed        int
    Intelligence int
}

type Stats struct {
    Base map[string]int
    Modifiers []string
}

func StatsCreate(stats BaseStats) Stats {
    s := Stats{
        Base: make(map[string]int),
    }

    //Iterate through the fields of a struct
    v := reflect.ValueOf(stats)
    typeOfS := v.Type()

    for i := 0; i< v.NumField(); i++ {
        val := v.Field(i).Interface().(int)
        s.Base[typeOfS.Field(i).Name] = val
    }
    return s
}

func (s Stats) GetBaseStat(id string) int {
    return s.Base[id]
}


func main() {
    m := StatsCreate(BaseStats{300, 300, 300, 300, 10, 10, 10})

    fmt.Println(m.GetBaseStat("Hp"))
}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.