当前位置: 首页 > news >正文

跟我一起学“仓颉”编程语言-反射和注解

一、反射

反射指程序可以访问、检测和修改它本身状态或行为的一种机制。

反射这一动态特性有以下的优点:

  • 提高了程序的灵活性和扩展性。

  • 程序能够在运行时获悉各种对象的类型,对其成员进行枚举、调用等操作。

  • 允许在运行时创建新类型,无需提前硬编码。

但使用反射调用,其性能通常低于直接调用,因此反射机制主要应用于对灵活性和拓展性要求很高的系统框架上。对于仓颉的反射特性,需要知道 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,并且不能是abstractopensealed修饰的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) }

三、小结

本章为大家详细的介绍了仓颉编程语言中反射和注解的内容,下一章,为大家带来跨语言互操作的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉服务端开发有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!

http://www.zskr.cn/news/1484092.html

相关文章:

  • SpringBoot自动配置翻车实录:手把手教你用@ConditionalOnMissingBean解决Bean冲突
  • 告别CAN报文丢失:深入解读S32K3的邮箱匹配算法与掩码优先级陷阱
  • 告别混乱!手把手教你为宝兰德BES中间件创建独立的“产品”与“应用”账号
  • GPT-4参数激活率真相:稀疏激活不是浪费,而是工程精算
  • 告别EVT大杂烩:手把手教你为沁恒CH573打造清爽的MounRiver独立工程
  • GPT-4的1.8万亿参数与2%激活真相:MoE架构深度解析
  • 博德之门3脚本扩展器:3步解锁游戏无限可能
  • 5分钟轻松搞定:网易云QQ音乐歌词批量提取与格式转换全攻略
  • 告别Hello World!用ESP32和ESP-IDF 4.3亲手点亮第一颗LED(保姆级避坑指南)
  • SpringBoot自动配置实战:用@ConditionalOnMissingBean优雅解决Bean冲突(附Drools配置案例)
  • 2026年别墅朗盛门窗怎么选 - 品牌宣传支持者
  • 嵌入式开发避坑指南:单片机串口接收NMEA-0183数据时,如何解决数据不完整和校验错误?
  • 年收入多少才能逃离北上广?一个技术家庭移居乡村后的真实账单与保险配置攻略
  • 5个理由告诉你为什么WinUtil是Windows用户的必备神器
  • Goque核心功能解析:栈、队列与优先级队列实战教程
  • 别再对着文档发愁了!手把手教你用STM32CubeIDE搞定涂鸦Wi-Fi模组MCU SDK移植(附完整代码)
  • ESP32-PICO-D4的Strapping引脚配置避坑指南:从启动模式到SDIO时序,一次讲清楚
  • 如何扩展Firework_Simulator:添加自定义烟花类型和特效
  • 别再一条条插了!MyBatis批量插入的三种实战方案对比(ExecutorType.BATCH vs foreach vs MyBatis-Plus)
  • 3个简单步骤,让普通鼠标在macOS上获得触控板般流畅体验
  • 2026年评价高的碳化本色耐磨竹地板/碳化加色竹地板源头工厂推荐 - 行业平台推荐
  • Anki编程闪卡美化教程:为代码添加专业语法高亮效果
  • 别再只盯着GGA了!NMEA-0183协议中GSV、GSA、RMC等语句的实战应用与避坑指南
  • 2026年比较好的极简门/西北极简门/西安极简门/陕西本地极简门批量采购厂家推荐 - 行业平台推荐
  • 2026年比较好的小型涡轮蜗杆减速机/东莞有刷直流减速电机精选厂家推荐 - 行业平台推荐
  • LabelImg图像标注工具:如何高效创建专业级计算机视觉数据集?
  • Jenkinsapi高级技巧:提升CI/CD效率的10个实用方法
  • 告别外围电路!用ESP32-PICO-D4打造超小型物联网设备的保姆级指南
  • 保姆级教程:用PS176芯片搞定DP转HDMI 2.0,手把手画原理图(附避坑点)
  • N皇后问题的遗传算法Python实战:从调试坑到收敛优化