Go 言語でのリフレクションの基本を説明する記事

リリース: 2023-07-25 17:01:58
転載
1228 人が閲覧しました

リフレクションとは

リフレクションとは、えーっと、リバース、つまり物事をひっくり返すという意味です。

たとえば、次のような非常に単純なコードです。

#
var a int = 3
fmt.Println(a)
ログイン後にコピー
#もちろん、

#a#変数が ## であることはわかっています。 #int と入力しますが、逆に考えると、プログラムは a が次であることをどのようにして認識するのでしょうか。 int 型はどうでしょうか? ? ? 現時点では、リフレクションを使用する必要があります。

#サンプルコード

#

v := reflect.TypeOf(a)
fmt.Println(v)
ログイン後にコピー

#2 つのコードが 1 つの実行結果に結合されます

コードの 2 行目は、変数 aint に正常に復元しました。 ###タイプ。 ###############何? ? ?あなたは私にとって何の役に立つのですか? ? ? ,うーん。 。 。正直、あまり使いませんが、使い方を知っておく必要があります。

Reflection (reflect パッケージ)

Go では、任意の変数、 ## と同様に、両方とも

具象タイプ

具象値 を持ちます。 #var a int = 3, 特定の型 int#, 特定の値 3# です####。

したがって、変数 の特定の型 reflect.Type# に属します。 ##、変数 特定の値は、reflect.Value に属します。

Go は

  • ##reflect.TypeOf # を取得します##特定のタイプ##。 ##reflect.ValueOf

  • ##特定の値を取得#TypeOf##TypeOf

メソッドは、変数

##特定のタイプ

#。 あらゆるタイプのデータを受け取り、リフレクションを通じて変数のタイプを出力できる関数を定義する必要があります。

示例代码

函数

func reflectType(x interface{}) {
    v := reflect.TypeOf(x)
    fmt.Printf("你传入的变量类型是:%v\n",v)
}
ログイン後にコピー

main

func main() {
    var a int = 666
    var b float64 = 3.14
    var c string = "hello world"
    var d [3]int = [3]int{1,2,6}
    var e []int = []int{1,2,6,88}
    var f map[string]interface{} = map[string]interface{}{
        "Name":"张三",
        "Age":18,
}
    reflectType(a)
    reflectType(b)
    reflectType(c)
    reflectType(d)
    reflectType(e)
    reflectType(f)
}
ログイン後にコピー

执行结果

Go 言語でのリフレクションの基本を説明する記事

通过reflect.TypeOf方法,完美解决上述需求。

TypeOf 的Name和Kind

这个是啥意思呢??这个在结构体中比较好体现。

简答来说就是TypeOf返回的太笼统了,还有更加细化的类型,通过这俩属性获取。

示例代码

函数
func reflectType(x interface{}) {
v := reflect.TypeOf(x)
fmt.Printf("你传入的变量类型是:%v | Name:%v | Kind:%v\n", v, v.Name(), v.Kind())
}
ログイン後にコピー
结构体
type Student struct {
    Name string
    Age int
}
ログイン後にコピー
main
func main() {
    var a int
    var b *int
    var c []int
    var d map[string]interface{}
    var e Student
    reflectType(a)
    reflectType(b)
    reflectType(c)
    reflectType(d)
    reflectType(e)
}
ログイン後にコピー

执行结果

Go 言語でのリフレクションの基本を説明する記事

总结

经过对比,会发现几个特殊问题。

如果变量是指针类型Name为空,Kindptr

変数が 参照型 (スライスとマップ) 型の場合、Name は空で、##Kind のみです。

変数が 構造体 の場合、Name は構造体名、Kindstruct

#ValueOf

TypeOf は変数の ## のみを取得できます逆に #特定の型 # を指定しても、特定の値 # は取得できません。これは少し不親切です。

所以ValueOf就来解决这个问题了,但是ValueOf牛叉的是,它里面还包括了变量类型

注:ValueOfTypeOfKind属性返回内容是一摸一样的。

需求:定义一个函数,可以接收任意类型,通过反射得出变量类型和变量值。

函数

func reflectType(x interface{}) {
    v := reflect.ValueOf(x)
    k := v.Kind()
    switch k {
    case reflect.Int:
        fmt.Printf("我是Int类型,我的值是%v\n",v.Int())
    case reflect.Slice:
        fmt.Printf("我是切片类型,我的值是%v\n",v.Slice(1,2))
    case reflect.Map:
        fmt.Printf("我是切片类型,我的值是%v\n",v.MapKeys())
    //case :可以继续case下去
  }
}
ログイン後にコピー

main

func main() {
  var a int = 1
  var c []int = []int{1, 5, 7, 19}
  var d map[string]interface{} = map[string]interface{}{
    "Name": "你好",
    "Age":  18,
  }
  var e Student
  reflectType(a)


  reflectType(c)
  reflectType(d)
  reflectType(e)
}
ログイン後にコピー

执行结果

Go 言語でのリフレクションの基本を説明する記事

通过反射设置值

反射还有一个用途,就是动态的修改变量值,可能你暂时体会不到,但是语法还是要学的。

通过反射设置值,需要用到Elem方法,并且传入的必须是指针

示例代码

函数

func reflectSetValue(x interface{}) {
  v := reflect.ValueOf(x)
  //kind也必须是Elem调用
  var k = v.Elem().Kind()
  switch k {
  case reflect.Int:
    //反射修改必须通过Elem
    v.Elem().SetInt(200)
  }
}
ログイン後にコピー

main

func main() {
  var a int = 10
  fmt.Printf("a的值:%v\n", a)
  //反射修改值传入的必须是地址
  reflectSetValue(&a)
  fmt.Printf("a的值:%v\n", a)
}
ログイン後にコピー

执行结果

Go 言語でのリフレクションの基本を説明する記事

概要

GoTypeOf の基本的なリフレクションを学習しました。 TypeOf,ValueOf, の名前と種類リフレクション経由で値を設定します

ここで、KindType にあります。 ValueOf の両方が使用可能です。通常は TypeOfValueOfより良い結果を得るために一緒に使用してください。

反省はわかりにくいかもしれないので、もっと頑張らなければなりません!に固執します! !

以上がGo 言語でのリフレクションの基本を説明する記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:Go语言进阶学习
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート