一、反射
反射指程序可以访问、检测和修改它本身状态或行为的一种机制。
反射这一动态特性有以下的优点:
提高了程序的灵活性和扩展性。
程序能够在运行时获悉各种对象的类型,对其成员进行枚举、调用等操作。
允许在运行时创建新类型,无需提前硬编码。
但使用反射调用,其性能通常低于直接调用,因此反射机制主要应用于对灵活性和拓展性要求很高的系统框架上。对于仓颉的反射特性,需要知道 TypeInfo 这一类型,这个核心类型中记录任意类型的类型信息,并且定义了方法用于获取类型信息、设置值等。
package Study // 导包 import std.reflect.* class User{ User(var name: String, var age: Int64){} func show() { println(name) println(age) } } main () { let user: User = User("钝子生", 23) // 用反射来获取一个自定义类型的类型信息 let info: ClassTypeInfo = ClassTypeInfo.of(user) let info2: ClassTypeInfo = ClassTypeInfo.get("Study.User") println(info) println(info2) }使用反射还可以获取类里面的成员
package Study // 导包 import std.reflect.* public class User{ public let _name: String = "钝子生" public var _age: Int64 = 23 public prop name: String { get () { this._name } } public mut prop age: Int64 { get () { this._age } set (_age) { this._age = _age } } public static func add(a: Int64, b: Int64) { a + b } } main () { let user = User() let info = ClassTypeInfo.of(user) let instanceProps = info.instanceProperties.toArray() println("user的实例成员属性包含${instanceProps}") let PropName = info.getInstanceProperty("name") let PropAge = info.getInstanceProperty("age") println((PropName.getValue(user) as String).getOrThrow()) println((PropAge.getValue(user) as Int64).getOrThrow()) // 通过反射修改name的值 if (PropName.isMutable()) { PropName.setValue(user, 10) } // 通过反射修改age的值 if (PropAge.isMutable()) { PropAge.setValue(user, 20) } println((PropName.getValue(user) as String).getOrThrow()) println((PropAge.getValue(user) as Int64).getOrThrow()) // 通过反射获取函数 let funcInfo: StaticFunctionInfo = TypeInfo.of<User>().getStaticFunction("add", TypeInfo.of<Int64>(), TypeInfo.of<Int64>()) let result = (funcInfo.apply(info, [1, 5]) as Int64).getOrThrow() println(result) }二、注解
自定义注解机制用来让反射(详见反射章节)获取标注内容,目的是在类型元数据之外提供更多的有用信息,以支持更复杂的逻辑。
开发者可以通过自定义类型标注@Annotation方式创建自己的自定义注解。@Annotation只能修饰class,并且不能是abstract或open或sealed修饰的class。当一个class声明它标注了@Annotation,那么它必须要提供至少一个const init函数,否则编译器会报错。
package Study // 导包 import std.reflect.* /* * 自定义注解 */ @Annotation public class Version { let code: String const init(code: String) { this.code = code } } @Version["V1.0"] public class User { public let _name: String = "钝子生" public var _age: Int64 = 23 public prop name: String { get () { this._name } } public mut prop age: Int64 { get () { this._age } set (_age) { this._age = _age } } public static func add(a: Int64, b: Int64) { a + b } } main () { let version = ClassTypeInfo.of(User()).findAnnotation<Version>().getOrThrow() println(version.code) }三、小结
本章为大家详细的介绍了仓颉编程语言中反射和注解的内容,下一章,为大家带来跨语言互操作的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉服务端开发有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!