Heim  >  Artikel  >  Backend-Entwicklung  >  Hat Go-Sprache Reflexion?

Hat Go-Sprache Reflexion?

青灯夜游
青灯夜游Original
2022-11-25 16:56:143519Durchsuche

Go-Sprache hat Reflexion. Die Go-Sprache bietet einen Mechanismus zum Aktualisieren und Überprüfen des Werts von Variablen, Aufrufmethoden von Variablen und intrinsische Operationen, die von Variablen zur Laufzeit unterstützt werden. Die spezifischen Typen dieser Variablen sind jedoch zur Kompilierungszeit nicht bekannt. Reflection in der Go-Sprache wird durch das Reflect-Paket unterstützt, das zwei wichtige Typen definiert: Typ und Wert. Jeder Schnittstellenwert in Reflection kann so verstanden werden, dass er aus zwei Teilen besteht: Reflect.Type und Reflect.Value.

Hat Go-Sprache Reflexion?

Die Betriebsumgebung dieses Tutorials: Windows 7-System, GO Version 1.18, Dell G3-Computer.

Die Go-Sprache bietet einen Mechanismus zum Aktualisieren und Überprüfen des Werts von Variablen, Aufrufmethoden von Variablen und intrinsische Operationen, die von Variablen zur Laufzeit unterstützt werden. Die spezifischen Typen dieser Variablen sind jedoch zur Kompilierungszeit nicht bekannt. Reflection ermöglicht es uns auch, den Typ selbst als erstklassigen Werttyp zu behandeln.

Reflexion in der Go-Sprache

Reflexion bezieht sich auf die Möglichkeit, während der Ausführung des Programms auf das Programm selbst zuzugreifen und es zu ändern. Beim Kompilieren des Programms werden die Variablen in Speicheradressen und Variablennamen umgewandelt wird vom Compiler nicht in den ausführbaren Teil geschrieben, das Programm kann beim Ausführen des Programms keine eigenen Informationen erhalten.

Sprachen, die die Reflexion unterstützen, können die Reflexionsinformationen von Variablen wie Feldnamen, Typinformationen, Strukturinformationen usw. während der Programmkompilierung in die ausführbare Datei integrieren und dem Programm eine Schnittstelle für den Zugriff auf die Reflexionsinformationen bereitstellen , damit das Programm ausgeführt werden kann. Bietet Zugriff auf Typreflexionsinformationen und die Möglichkeit, diese zu ändern.

Die C/C++-Sprache unterstützt die Reflexionsfunktion nicht und kann nur sehr abgeschwächte Informationen zum Programmlaufzeittyp bereitstellen. Sprachen wie Java und C# unterstützen alle vollständige Reflexionsfunktionen wie Lua und JavaScript Aufgrund ihrer eigenen grammatikalischen Eigenschaften kann der Code zur Laufzeit auf die eigenen Wert- und Typinformationen des Programms zugreifen, sodass kein Reflexionssystem erforderlich ist.

Das Reflexionssystem des Go-Sprachprogramms kann nicht alle Arten von Informationen in einem ausführbaren Dateibereich oder einem Paket abrufen. Es muss den entsprechenden lexikalischen Syntaxparser und abstrakten Syntaxbaum (AST) in der Standardbibliothek verwenden, um die Quellcodeverarbeitung durchzuführen . Scannen Sie, um diese Informationen zu erhalten.

Die Go-Sprache stellt das Reflect-Paket bereit, um auf die Reflection-Informationen des Programms zuzugreifen.

Reflect-Paket

Reflection in der Go-Sprache wird durch das Reflect-Paket unterstützt, das zwei wichtige Typen definiert: Typ und Wert. Jeder Schnittstellenwert in Reflection kann als reflektiert verstanden werden. Typ und Reflect .Value bestehen aus Es besteht aus zwei Teilen, und das Reflect-Paket bietet zwei Funktionen: Reflect.TypeOf und Reflect.ValueOf, um den Wert und den Typ eines beliebigen Objekts abzurufen.

Reflektiertes Typobjekt (reflect.Type)

In einem Go-Sprachprogramm können Sie die Funktion „reflect.TypeOf()“ verwenden, um ein Typobjekt (reflect.Type) mit einem beliebigen Wert abzurufen, auf den das Programm zugreifen kann Jedes Typobjekt über das Typobjekt. Das Folgende ist ein Beispiel zum Verständnis des Prozesses zum Erhalten des Typobjekts: folgt:

Zeile 9 definiert eine Variable vom Typ int. Hat Go-Sprache Reflexion?

In Zeile 10 wird das Typobjekt typeOfA der Variablen a über Reflect.TypeOf () abgerufen, und der Typ ist Reflect.Type ().
  • In Zeile 11 kann über die Mitgliedsfunktion des Typobjekts typeOfA der Typname der Variable typeOfA bzw. int abgerufen werden, und der Typ (Kind) ist int.
  • Typ und Art der Reflexion

Wenn Sie Reflexion verwenden, müssen Sie zunächst den Unterschied zwischen Typ und Art verstehen. In der Programmierung ist der Typ der am häufigsten verwendete Typ. Wenn jedoch eine große Vielfalt von Typen unterschieden werden muss, wird in der Reflexion auch Art (Kind) verwendet. Wenn Sie beispielsweise Zeiger in Typen einheitlich beurteilen müssen, ist es bequemer, Art-Informationen zu verwenden.

1) Definition des Reflexionstyps (Kind)

Typ (Typ) im Go-Sprachprogramm bezieht sich auf die systemeigenen Datentypen wie int, string, bool, float32 und andere Typen sowie auf die mit definierten Typen das Schlüsselwort type. Typen, deren Namen die Namen der Typen selbst sind. Wenn Sie beispielsweise struct{} vom Typ A verwenden, um eine Struktur zu definieren, ist A der Typ von struct{}.

Kind bezieht sich auf den Objekttyp, der im Reflect-Paket wie folgt definiert ist:

package main
import (
    "fmt"
    "reflect"
)
func main() {
    var a int
    typeOfA := reflect.TypeOf(a)
    fmt.Println(typeOfA.Name(), typeOfA.Kind())
}
Map, Slice und Chan sind Referenztypen, die den verwendeten Zeigern ähneln, aber in der Typkonstantendefinition immer noch unabhängig sind Kategorie, gehört nicht zu Ptr. Die durch Typ A struct{} definierte Struktur gehört zum Typ Struct und *A gehört zum Typ Ptr.

2) Holen Sie sich den Typnamen und den Typ aus dem Typobjekt

Die dem Typnamen entsprechende Reflexionserfassungsmethode in der Go-Sprache ist die Name()-Methode in Reflect.Type, die eine Zeichenfolge zurückgibt, die den Typnamen darstellt ; der Typ gehört Kind (Kind) verwendet die Kind()-Methode in Reflect.Type und gibt eine Konstante vom Typ Reflect.Kind zurück.

下面的代码中会对常量和结构体进行类型信息获取。

package main
import (
    "fmt"
    "reflect"
)
// 定义一个Enum类型
type Enum int
const (
    Zero Enum = 0
)
func main() {
    // 声明一个空结构体
    type cat struct {
    }
    // 获取结构体实例的反射类型对象
    typeOfCat := reflect.TypeOf(cat{})
    // 显示反射类型对象的名称和种类
    fmt.Println(typeOfCat.Name(), typeOfCat.Kind())
    // 获取Zero常量的反射类型对象
    typeOfA := reflect.TypeOf(Zero)
    // 显示反射类型对象的名称和种类
    fmt.Println(typeOfA.Name(), typeOfA.Kind())
}

运行结果如下:

Hat Go-Sprache Reflexion?

代码说明如下:

  • 第 17 行,声明结构体类型 cat。

  • 第 20 行,将 cat 实例化,并且使用 reflect.TypeOf() 获取被实例化后的 cat 的反射类型对象。

  • 第 22 行,输出 cat 的类型名称和种类,类型名称就是 cat,而 cat 属于一种结构体种类,因此种类为 struct。

  • 第 24 行,Zero 是一个 Enum 类型的常量。这个 Enum 类型在第 9 行声明,第 12 行声明了常量。如没有常量也不能创建实例,通过 reflect.TypeOf() 直接获取反射类型对象。

  • 第 26 行,输出 Zero 对应的类型对象的类型名和种类。

指针与指针指向的元素

Go语言程序中对指针获取反射对象时,可以通过 reflect.Elem() 方法获取这个指针指向的元素类型,这个获取过程被称为取元素,等效于对指针类型变量做了一个*操作,代码如下:

package main
import (
    "fmt"
    "reflect"
)
func main() {
    // 声明一个空结构体
    type cat struct {
    }
    // 创建cat的实例
    ins := &cat{}
    // 获取结构体实例的反射类型对象
    typeOfCat := reflect.TypeOf(ins)
    // 显示反射类型对象的名称和种类
    fmt.Printf("name:'%v' kind:'%v'\n", typeOfCat.Name(), typeOfCat.Kind())
    // 取类型的元素
    typeOfCat = typeOfCat.Elem()
    // 显示反射类型对象的名称和种类
    fmt.Printf("element name: '%v', element kind: '%v'\n", typeOfCat.Name(), typeOfCat.Kind())
}

运行结果如下:

Hat Go-Sprache Reflexion?

代码说明如下:

  • 第 13 行,创建了 cat 结构体的实例,ins 是一个 *cat 类型的指针变量。

  • 第 15 行,对指针变量获取反射类型信息。

  • 第 17 行,输出指针变量的类型名称和种类。Go语言的反射中对所有指针变量的种类都是 Ptr,但需要注意的是,指针变量的类型名称是空,不是 *cat。

  • 第 19 行,取指针类型的元素类型,也就是 cat 类型。这个操作不可逆,不可以通过一个非指针类型获取它的指针类型。

  • 第 21 行,输出指针变量指向元素的类型名称和种类,得到了 cat 的类型名称(cat)和种类(struct)。

【相关推荐:Go视频教程

Das obige ist der detaillierte Inhalt vonHat Go-Sprache Reflexion?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn