2

次のようなデータベース内のオブジェクトを表す構造体があります。

type Object struct {
    Id string
    Field1 string
    Field2 int
}

そして、フィールドが変更されるたびにデータベース内の特定のフィールドを更新する関数が必要です。次のようなものです。

func (self *Object) SetField1(value string) {
    self.Field1 = value
    database.Update(self.Id, "Field1", self.Field1) // pseudocode
}

ハードコーディングされた文字列を置き換える方法はあり"Field1"ますか?私のコードは、構造体フィールドの順序付けと命名の将来の変更に耐性がありますか?

Reflect パッケージを調べてみました。使用しているフィールドを表す StructField を取得できると便利ですが、ハードコードされた文字列を介してフィールドの名前を指定するか、構造体のフィールドのインデックス (変更される可能性があります)。

4

2 に答える 2

6

あなたが話している文脈ではありません。これはパラメーターとして渡されないため、送信する構造体のフィールドを指定する他の方法が必要です。ここでの精神的なギャップは、集合関数をプロパティではないのにプロパティであるかのように処理しようとしていることです。他の言語で見られるように、プロパティ間の主な違いは、プロパティが特定のフィールドにバインドされているのに対し、SetField1メソッドは構造体全体にバインドされていることです。そのメソッドは、2つのフィールドを設定することもできます。

一般に、フィールドごとの反射的な作業を行っていて、フィールドを使用して派手な動的な作業を行いたい場合は、構造体タグを使用する必要があります。たとえば、次のようになります。

type Object struct {
    Id string     `db:"id"`
    Field1 string `db:"field1"`
    Field2 int    `db:"field2"`
}

これらのタグには、次のようにアクセスできます。

package main

import (
    "reflect"
    "fmt"
)

func main() {
    var x struct {
        MyField int `core:"required"`
    }
    t := reflect.TypeOf(x)

    for i := 0; i < t.NumField(); i++ {
        field := t.Field(i)
        fmt.Println(field.Name, ":", field.Tag.Get("core"))
    }
}

それは実際には完全な解決策ではありませんが...それが尋ねられた方法での質問は行うことが不可能です。

于 2013-01-25T04:30:52.567 に答える
3

次のようなメソッドを追加することで、文字列を検証できます。

func (self *Object) verify(field string) string {
    if _, ok := reflect.TypeOf(*self).FieldByName(field); ok {
        return field
    }
    panic("Invalid field name")
}

そして、文字列をデータベース更新に渡すときに使用します

func (self *Object) SetField1(value string) {
    self.Field1 = value
    database.Update(self.Id, self.verify("Field1"), self.Field1) // pseudocode
}

しかし、リフレクションを使用する場合setFieldは、フィールドを文字列として受け入れ、値を として受け入れ、interface{}フィールドと値をチェックし、値を設定し、データベースを更新します。

.verify()この方法では、文字列を使用してすべてが行われるため、機能するかパニックするかのいずれかであり、メソッドの使用を覚えておく必要はありません。

次のようなもの:

func (self *Object) SetField(field string, value interface{}) {
    // verify field and value using reflection
    // set the value using reflection
    database.Update(self.Id, field, self.Field1)

}

これは、エクスポートされていないフィールドでは機能しないと思いますが。

于 2013-01-25T15:00:38.887 に答える