# Reflect # 概述 Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect对象的设计目的有这样几个。 **现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。 Reflect.apply(target, thisArg, args) Reflect.construct(target, args) Reflect.get(target, name, receiver (target, name) Reflect.has(target, name) Reflect.ownKeys(target) Reflect.isExtensible(target) Reflect.preventExtensions Reflect.set(1, 'foo', {}) // 报错 Reflect.set(false, 'foo', {}) // 报错 # Reflect.has(obj, name) Reflect.has
Reflect.png Reflect 概述 Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty ),放到Reflect对象上 修改某些Object方法的返回结果,让其变得更合理 让Object操作都变成函数行为 Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在 Reflect对象上找到对应的方法 静态方法 Reflect.apply(target, thisArg, args) Reflect.construct(target, args) Reflect.get , desc) Reflect.deleteProperty(target, name) Reflect.has(target, name) Reflect.ownKeys(target) Reflect.isExtensible (target) Reflect.preventExtensions(target) Reflect.getOwnPropertyDescriptor(target, name) Reflect.getPrototypeOf
领8888元新春采购礼包,抢爆款2核2G云服务器95元/年起,个人开发者加享折上折
一、使用 reflect.Type 创建实例 在通过 reflect.TypeOf 函数获取到变量的反射类型对象之后,可以通过反射类型对象 reflect.Type 的 New 函数来创建一个新的实例 reflect.Value 的 Call 方法调用该函数 使用反射调用函数需要将参数使用反射值对象的切片 []reflect.Value 构造后传入 Call 方法中,调用之后再通过切片 []reflect.Value []reflect.Value 切片参数列表 paramValueOfSlice := []reflect.Value{reflect.ValueOf(3), reflect.ValueOf(8 切片参数列表 paramValueOfSlice2 := []reflect.Value{reflect.ValueOf(3), reflect.ValueOf(0)} // 调用函数 true, reflect.Value 当除数为 0 的情况: 返回值切片长度为:2 0, reflect.Value false, reflect.Value 不管是函数只有一个返回值还是多个返回值的情况
import "reflect" reflect包实现了运行时反射,允许程序操作任意类型的对象。
描述 与大多数全局对象不同,Reflect没有构造函数。你不能将其与一个 new 运算符一起使用,或者将 Reflect 对象作为一个函数来调用。 方法 Reflect.apply() Reflect.construct(target, argumentsList[, newTarget]) 静态方法 Reflect.apply() 通过指定的参数列表发起对目标 ; // 4 Reflect.apply("".charAt, "ponies", [3]); // "i" Reflect.construct() Reflect.construct() 方法的行为有点像 Reflect.deleteProperty(Object.freeze({ foo: 1 }), "foo"); // false Reflect.get() Reflect.get() 方法的工作方式 Reflect.set() 静态方法 Reflect.set() 工作方式就像在一个对象上设置一个属性。
, 看起来功能不错,但是大家也都知道一点: 使用reflect是有性能代价的! 测试 Java中的reflect的使用对性能也有影响, 但是和Java reflect不同, Java中不区分Type和Value类型的, 所以至少Java中我们可以预先讲相应的reflect对象缓存起来 ,减少反射对性能的影响, 但是Go没办法预先缓存reflect, 因为Type类型并不包含对象运行时的值,必须通过ValueOf和运行时实例对象才能获取Value对象。 当然,不同的reflect使用的姿势, 以及对象类型的不同,都会多多少少影响性能的测试数据,我们就以一个普通的struct类型为例: 1package test 2import ( 3 "reflect 对于字段的赋值,一共四个测试用例: Reflect_Set: 通过反射生成对象,并将这个对象转换成实际的对象,直接调用对象的字段进行赋值, 需要73.6纳秒 Reflect_SetFieldByName
个人觉得,reflect使用如此频繁的一个重要原因离不开go的另一个特性,空接口interface{},reflect配合空接口,让原本是静态类型的go具备了很多动态类型语言的特征。 go的reflect库有两个重要的类型: reflect.Type reflect.Value Type,Value分别对应对象的类型和值数据 还有两个重要的函数: reflect.TypeOf(i interface {}) Type reflect.TypeOf()返回值的类型就是reflect.Type。 reflect.ValueOf(i interface{}) Value reflect.ValueIOf()返回值的类型就是reflect.Value reflect.Type reflect.TypeOf reflect.ValueOf(i interface{}) Value reflect.ValueOf()的返回值类型为reflect.Value,它实现了interface{}参数到reflect.Value
reflect.Typeof 会把这个空接口拆包(unpack)恢复出类型信息。 ("type:", reflect.TypeOf(x)) fmt.Println("value:", reflect.ValueOf(x)) //Valueof方法会返回一个Value类型的对象 ("value:", reflect.ValueOf(x)) //Valueof方法会返回一个Value类型的对象 fmt.Println(reflect.ValueOf(x).Type()) fmt.Println(reflect.TypeOf(x).Kind()) fmt.Println(reflect.ValueOf(x).Kind()) } //结果 type: main.MyInt (x) // v.Kind() 为 reflect.Int 即使x的静态类型是MyInt而不是int。
reflect.ValueOf func main() { type MyInt int var x MyInt = 7 v := reflect.ValueOf(x) switch t.Kind() { case reflect.Bool: return boolEncoder case reflect.Int, reflect.Int8, reflect.Int16 , reflect.Int32, reflect.Int64: return intEncoder case reflect.Uint, reflect.Uint8, reflect.Uint16 , reflect.Uint32, reflect.Uint64, reflect.Uintptr: return uintEncoder case reflect.Float32: return case reflect.Interface: return interfaceEncoder case reflect.Struct: return newStructEncoder(t
描述 Reflect并非一个构造函数,所以不能通过new运算符对其进行调用,或者将Reflect对象作为一个函数来调用,就像Math对象一样,Reflect对象的所有属性和方法都是静态的。 实际上Reflect对象是ES6为操作对象而提供的新API,而这个API设计的目的主要有: 将Object对象的一些属于语言内部的方法放到Reflect对象上,从Reflect上能拿到语言内部的方法,例如 方法 Reflect.apply() Reflect.apply(target, thisArgument, argumentsList) 静态方法Reflect.apply()通过指定的参数列表发起对目标 ); // true Reflect.has() Reflect.has(target, propertyKey) 方法Reflect.has()作用与in操作符类似,但它是通过一个函数执行来操作的。 Reflect.set() Reflect.set(target, propertyKey, value[, receiver]) 方法Reflect.set()是在一个对象上设置一个属性。
String Struct UnsafePointer ) func String 获取类型字符名称 func (k Kind) String() string intType := reflect.Int return m.name } c := Man{"coco"} // 应为GetName方法绑定在类型指针上所以这里传入的参数为指针 // 侧面也证明了结构体方法的绑定及调用方式 t := reflect.TypeOf (10) func PtrTo 获取类型的指针类型 num := 10 numType := reflect.TypeOf(num) fmt.Println(numType.Kind ()) // >>> int PType := reflect.PtrTo(numType) fmt.Println(PType.Kind()) // >>> ptr func SliceOf (i) fmt.Println(v.IsValid()) // >>> true var i interface{} v := reflect.ValueOf(i) fmt.Println(v.IsValid
获取变量的值: reflect.ValueOf(x).Int() reflect.ValueOf(x).Float() reflect.ValueOf(x).String() reflect.ValueOf (x).Bool() 通过反射的来改变变量的值reflect.Value.SetXX相关方法 reflect.Value.SetInt(),//设置整数 reflect.Value.SetFloat() ,//设置浮点数 reflect.Value.SetString(),//设置字符串 反射结构体 reflect.Value.NumField()获取结构体中字段的个数 reflect.Value.Method "%v\n", a) //5 } 通过reflect.ValueOf来进行方法的调用 import ( "fmt" "reflect" ) type User struct { 标签的内容不可以在一般的编程中使用,只有包reflect能获取它。
一、reflect.Value 动态修改变量值 在前来两篇文章中讲述了如何通过 reflect.Value 的各种方法来获取变量为基本数据类型、Map 和结构体形式时的 value 值或者 Key 变量可被寻址则可以被动态修改 变量无法被动态修改的情况 package main import ( "fmt" "reflect" ) func main(){ var zulu (zulu) yankeeValueOf := reflect.ValueOf(yankee) xrayValueOf := reflect.ValueOf(xray) tangoValueOf := reflect.ValueOf(tango) // 是否可以被寻址 fmt.Println(zuluValueOf.CanAddr()) // false fmt.Println " ) func main(){ var zulu = 12138 // 获取 Int 指针类型的反射值对象 zuluPtrValueOf := reflect.ValueOf(
return nil, err } x := &serverReflectionServerReflectionInfoClient{stream} return x, nil } reflect listResp := resp.GetListServicesResponse() if listResp == nil { return nil, &ProtocolError{reflect.TypeOf error) { fd, err = s.fileDescForType(st) } func (s *serverReflectionServer) fileDescForType(st reflect.Type ) (*dpb.FileDescriptorProto, error) { m, ok := reflect.Zero(reflect.PtrTo(st)).Interface(). protoc-gen-go/descriptor/descriptor.pb.go type FileDescriptorProto = descriptorpb.FileDescriptorProto 它其实就是grpc reflect
range []interface{}{"hi", 42, func() {}} { switch v := reflect.ValueOf(v); v.Kind() { case reflect.String : fmt.Println(v.String()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64 swap := func(in []reflect.Value) []reflect.Value { return []reflect.Value{in[1], in[0]} } // makeSwap writerType := reflect.TypeOf((*io.Writer)(nil)).Elem() fileType := reflect.TypeOf((*os.File)(nil)) ([]reflect.StructField{ { Name: "Height", Type: reflect.TypeOf(float64(0)), Tag: `json:"height
转载自 https://www.cnblogs.com/xinhuaxuan/p/6019524.html java.lang.reflect.Constructor 一、Constructor类是什么 Constructor是一个类,位于java.lang.reflect包下。 1 package com.testReflect; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Modifier
Reflect对象上。 Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法。 跟Proxy一样,Reflect也有13个静态方法: Reflect.apply(target, thisArg, args) Reflect.construct(target, args) Reflect.get , desc) Reflect.deleteProperty(target, name) Reflect.has(target, name) Reflect.ownKeys(target) Reflect.isExtensible = Reflect.construct(User, ['wade']); Reflect.getPrototypeOf(obj) Reflect.getPrototypeOf方法用于读取对象的__proto
ES6中Proxy与Reflect的简单学习笔记,他们也是vue3.0版本中数据劫持的重要API。 1、Proxy Proxy也就是代理,在目标对象之前做一层拦截处理,可以对目标对象做很多操作。 2、Rlfect Reflect也是跟Proxy都是在ES6中新增加的API,可以理解为对Object的美化。 (1)、将Object对象上一些明显属于语言内部的方法(如Object.defineProperty),放到Reflect上,现在阶段某些方法同时出现在Object与Reflect上,未来的新方法只会出现在 Reflect上。 } (3)、Reflect 对象的方法与 Proxy 对象的方法一一对应,只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法。
扫码关注腾讯云开发者
领取腾讯云代金券