Rumah > Artikel > pembangunan bahagian belakang > Adakah bahasa pergi mempunyai refleksi?
Bahasa Go mempunyai refleksi. Bahasa Go menyediakan mekanisme untuk mengemas kini dan menyemak nilai pembolehubah, kaedah panggilan pembolehubah, dan operasi intrinsik yang disokong oleh pembolehubah pada masa jalan, tetapi jenis khusus pembolehubah ini tidak diketahui pada masa penyusunan. Refleksi dalam bahasa Go disokong oleh pakej reflect, yang mentakrifkan dua jenis penting: Jenis dan Nilai Mana-mana nilai antara muka dalam refleksi boleh difahami sebagai terdiri daripada dua bahagian: reflect.Type dan reflect.Value.
Persekitaran pengendalian tutorial ini: sistem Windows 7, GO versi 1.18, komputer Dell G3.
Bahasa Go menyediakan mekanisme untuk mengemas kini dan menyemak nilai pembolehubah, kaedah panggilan pembolehubah dan operasi intrinsik yang disokong oleh pembolehubah pada masa jalan, tetapi jenis khusus pembolehubah ini tidak diketahui pada masa penyusunan ini mekanisme dipanggil refleksi. Refleksi juga membolehkan kami menganggap jenis itu sendiri sebagai jenis nilai kelas pertama.
Refleksi dalam bahasa go
Refleksi merujuk kepada keupayaan untuk mengakses dan mengubah suai program itu sendiri semasa program dijalankan disusun apabila Pembolehubah ditukar kepada alamat memori, nama pembolehubah tidak ditulis ke dalam bahagian boleh laku oleh pengkompil, dan atur cara tidak boleh mendapatkan maklumatnya sendiri semasa menjalankan program.
Bahasa yang menyokong pantulan boleh mengintegrasikan maklumat pantulan pembolehubah, seperti nama medan, maklumat jenis, maklumat struktur, dll., ke dalam fail boleh laku semasa penyusunan atur cara dan menyediakan antara muka untuk atur cara akses maklumat refleksi, supaya maklumat Refleksi tentang jenis boleh diperolehi semasa masa jalan program dan mempunyai keupayaan untuk mengubah suainya.
Bahasa C/C tidak menyokong fungsi refleksi dan hanya boleh memberikan maklumat jenis masa jalan program yang sangat lemah melalui bahasa taip seperti Java dan C# semuanya menyokong fungsi pantulan lengkap seperti Lua dan JavaScript, kerana mereka Sintaks itu sendiri membenarkan kod untuk mengakses nilai program sendiri dan menaip maklumat semasa masa jalan, jadi tiada sistem pantulan diperlukan.
Sistem refleksi program bahasa Go tidak boleh mendapatkan semua jenis maklumat dalam ruang fail boleh laku atau pakej Ia perlu menggunakan penghurai leksikal dan sintaks dan pepohon sintaks abstrak (AST) dalam pustaka standard. untuk mendapatkan maklumat ini selepas mengimbas kod sumber.
Bahasa Go menyediakan pakej reflect untuk mengakses maklumat refleksi program.
pakej refleksi
Refleksi dalam bahasa Go disokong oleh pakej reflect, yang mentakrifkan dua jenis penting: Jenis dan Nilai Mana-mana nilai antara muka boleh difahami dalam refleksi sebagai terdiri daripada dua bahagian, reflect.Type dan reflect.Value, dan pakej reflect menyediakan dua fungsi, reflect.TypeOf dan reflect.ValueOf, untuk mendapatkan Nilai dan Jenis mana-mana objek.
Objek jenis pantulan (reflect.Type)
Dalam atur cara bahasa Go, gunakan fungsi reflect.TypeOf() untuk mendapatkan sebarang Jenis nilai objek (reflect.Type), program boleh mengakses maklumat jenis apa-apa nilai melalui objek jenis Berikut adalah contoh untuk memahami proses mendapatkan objek jenis:
package main import ( "fmt" "reflect" ) func main() { var a int typeOfA := reflect.TypeOf(a) fmt.Println(typeOfA.Name(), typeOfA.Kind()) }
Hasil yang dijalankan adalah. seperti berikut:
Penerangan kod adalah seperti berikut:
Barisan 9 mentakrifkan pembolehubah jenis int.
Dalam baris 10, jenis objek typeOfA bagi pembolehubah a diperolehi melalui reflect.TypeOf(), dan jenisnya adalah reflect.Type().
Dalam baris 11, melalui fungsi ahli objek jenis typeOfA, anda boleh mendapatkan nama jenis pembolehubah typeOfA int dan jenis (Jenis) int.
Jenis dan Jenis pantulan
Apabila menggunakan refleksi, anda perlu terlebih dahulu memahami jenis Perbezaan antara ( Jenis) dan jenis (Jenis). Dalam pengaturcaraan, jenis yang paling biasa digunakan ialah jenis, tetapi dalam refleksi, apabila pelbagai jenis yang besar perlu dibezakan, jenis (Jenis) digunakan. Sebagai contoh, apabila anda perlu menilai secara seragam penunjuk dalam jenis, adalah lebih mudah untuk menggunakan maklumat jenis (Jenis).
1) Definisi jenis pantulan (Jenis)
Jenis (Jenis) dalam atur cara bahasa Go merujuk kepada jenis data asli sistem, seperti int, rentetan, bool , float32 dan jenis lain, serta jenis yang ditakrifkan menggunakan kata kunci jenis, nama jenis ini ialah nama jenis itu sendiri. Contohnya, apabila menggunakan jenis A struct{} untuk mentakrifkan struktur, A ialah jenis struct{}.
Jenis merujuk kepada jenis objek, yang ditakrifkan seperti berikut dalam pakej pantulan:
type Kind uint const ( Invalid Kind = iota // 非法类型 Bool // 布尔型 Int // 有符号整型 Int8 // 有符号8位整型 Int16 // 有符号16位整型 Int32 // 有符号32位整型 Int64 // 有符号64位整型 Uint // 无符号整型 Uint8 // 无符号8位整型 Uint16 // 无符号16位整型 Uint32 // 无符号32位整型 Uint64 // 无符号64位整型 Uintptr // 指针 Float32 // 单精度浮点数 Float64 // 双精度浮点数 Complex64 // 64位复数类型 Complex128 // 128位复数类型 Array // 数组 Chan // 通道 Func // 函数 Interface // 接口 Map // 映射 Ptr // 指针 Slice // 切片 String // 字符串 Struct // 结构体 UnsafePointer // 底层指针 )
Peta, Slice dan Chan ialah jenis rujukan dan serupa dengan penunjuk yang digunakan. Walau bagaimanapun, ia masih tergolong dalam kategori bebas dalam kategori definisi malar dan tidak tergolong dalam Ptr. Struktur yang ditakrifkan mengikut jenis A struct{} tergolong dalam jenis Struct, dan *A milik Ptr.
2) Dapatkan nama jenis dan taip daripada objek jenis
Kaedah pemerolehan pantulan yang sepadan dengan nama jenis dalam bahasa Go ialah kaedah Name() dalam reflect .Type , mengembalikan rentetan yang mewakili nama jenis; atribut jenis (Jenis) menggunakan kaedah Kind() dalam reflect.Type, dan mengembalikan pemalar jenis reflect.Kind.
下面的代码中会对常量和结构体进行类型信息获取。
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()) }
运行结果如下:
代码说明如下:
第 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()) }
运行结果如下:
代码说明如下:
第 13 行,创建了 cat 结构体的实例,ins 是一个 *cat 类型的指针变量。
第 15 行,对指针变量获取反射类型信息。
第 17 行,输出指针变量的类型名称和种类。Go语言的反射中对所有指针变量的种类都是 Ptr,但需要注意的是,指针变量的类型名称是空,不是 *cat。
第 19 行,取指针类型的元素类型,也就是 cat 类型。这个操作不可逆,不可以通过一个非指针类型获取它的指针类型。
第 21 行,输出指针变量指向元素的类型名称和种类,得到了 cat 的类型名称(cat)和种类(struct)。
【相关推荐:Go视频教程】
Atas ialah kandungan terperinci Adakah bahasa pergi mempunyai refleksi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!