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

做校园网站长治做网站

做校园网站,长治做网站,旅行的意义 wordpress主题,算命手机网站开发不同于 java 中的反射#xff0c;Rust 没有提供以往意义上的运行时反射#xff0c;取而代之的是 “编译期反射”#xff0c;如 类型分析、类型转换、类型签名。但即便如此#xff0c;也已经能对 Rust元编程 提供很多助力了。 这种操作#xff0c;主要通过 Any 来实现…  不同于 java 中的反射Rust 没有提供以往意义上的运行时反射取而代之的是 “编译期反射”如 类型分析、类型转换、类型签名。但即便如此也已经能对 Rust元编程 提供很多助力了。 这种操作主要通过 Any 来实现Rust 中提供了 Any Trait所有类型含自定义类型都自动实现了该特征因此通过它我们可以进行一些类似反射的功能 实际上在 Rust 早期版本中是提供了 Reflection 的但是在 14年移除了相关代码原因是 反射打破了原有的封装原则能任意访问结构体内容不安全反射的存在使得代码过于臃肿移除后编译器可以简化很多反射功能设计的比较弱开发者对于是否在未来的版本中还拥有反射功能存疑 另一篇 关于Rust为何不引入 Runtime Reflection 大致信息如下 不一定非要使用反射来实现 Rust中可以有更好的实现派生宏和Trait之间的配合可以将实现从运行时转移到编译时 例如利用过程宏实现编译时反射以实现依赖注入等功能 - https://github.com/dtolnay/reflect 至于保留 Any 的原因 在调试范型类型相关代码时有TypeId会更方便更容易给出正确的错误提示有利于编译器作出代码的优化 Any源码简读 参看Any源码文档 作为 dyn Any (借用的 trait 对象)具有 is 和 downcast_ref 方法可测试值是否为给定类型并对类型的内部值进行引用作为 mut dyn Any还有 downcast_mut 方法用于获取内部值的 “可变引用” Boxdyn Any 具有 downcast 方法该方法尝试转换为 BoxT也有称 “类型具象化”。但需注意dyn Any 仅限于测试值是否为具体的类型而不能用于测试类型是否实现了 Trait 总结就是 std::any 起到的作用有4个 获得变量的类型 a.type_id()判断变量是否是指定的具体类型 a.is::String() 或 TypeId::of::String() a.type_id()把any转换成指定类型 a.downcast_ref::String()获取类型的名字 (_: T) - String { std::any::type_name::T().to_string() } 下面看一段 Any Trait 部分核心源码可帮助更好理解 Any pub trait Any: static {fn type_id(self) - TypeId; }// 获得变量的类型TypeId // 为所有的T实现了Any #[stable(feature rust1, since 1.0.0)] implT: static ?Sized Any for T {fn type_id(self) - TypeId { TypeId::of::T() } }// 判断变量是否是指定类型 #[stable(feature rust1, since 1.0.0)] #[inline] pub fn isT: Any(self) - bool {// Get TypeId of the type this function is instantiated with.let t TypeId::of::T();// Get TypeId of the type in the trait object.let concrete self.type_id();// Compare both TypeIds on equality.t concrete }// 把any转换成指定类型 #[stable(feature rust1, since 1.0.0)] #[inline] pub fn downcast_refT: Any(self) - OptionT {if self.is::T() {// SAFETY: just checked whether we are pointing to the correct typeunsafe {Some(*(self as *const dyn Any as *const T))}} else {None} }// 获取类型名字 pub const fn type_nameT: ?Sized() - static str {intrinsics::type_name::T() }#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub struct TypeId {t: u64, }补充说明 Rust 中所有拥有静态生命周期的类型都会实现Any未来可能会考虑加入生命周期是非‘static的情况 Rust 中所有类型都有一个全局唯一的标识 TypeIdA TypeId represents a globally unique identifier for a type 这些 TypeId 都是通过调用 intrinsic 模块中定义的函数创建的即 TypeId 的生成是由编译器的实现来决定的 关于intrinsic 模块 intrinsic 库函数是指由编译器内置实现的函数一般是具有如下特点的函数 与CPU架构相关性很大必须利用汇编实现或者利用汇编才能具备最高性能的函数和编译器密切相关的函数由编译器来实现最为合适具体实现 - https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs Any基本使用 examples/main.rs use std::any::{Any, TypeId};struct Person {pub name: String, }/// 判断是否为指定类型-1 fn is_string(s: dyn Any) - bool {TypeId::of::String() s.type_id() // 获取TypeId }/// 判断是否为指定类型-2 fn check_string(s: dyn Any) {if s.is::String() {println!(Its a string!);} else {println!(Not a string...);} }/// 转换Any为特定类型 fn print_if_string(s: dyn Any) {if let Some(ss) s.downcast_ref::String() {println!(Its a string({}): {}, ss.len(), ss);} else {println!(Not a string...);} }/// 获取类型的名字 /// 但需注意, 此方式获取的名字不唯一 /// 如 type_name::OptionString 可能返回 OptionString 或 std::option::Optionstd::string::String /// 同时, 编译器版本不同、可能返回值不同 fn get_type_nameT(_: T) - String {std::any::type_name::T().to_string() }fn main() {let p Person { name: John.to_string() };assert!(!is_string(p));assert!(is_string(p.name));check_string(p);check_string(p.name);print_if_string(p);print_if_string(p.name);println!(Type name of p: {}, get_type_name(p));println!(Type name of p.name: {}, get_type_name(p.name)); }输出如下 Not a string... Its a string! Not a string... Its a string(4): John Type name of p: 0_any::Person Type name of p.name: alloc::string::StringAny适用场景 Rust 中的 Any 类似于 Java 中的 Object可以传入任何拥有静态生命周期的类型因此当入参类型复杂但后续又没有更多功能性操作时就可以简化入参。例如打印任何类型的值。 examples/1_print_any.rs use std::any::Any; use std::fmt::Debug;#[derive(Debug)] struct MyType {name: String,age: u32, }fn print_anyT: Any Debug(value: T) {let value_any value as dyn Any;if let Some(string) value_any.downcast_ref::String() {println!(String ({}): {}, string.len(), string);} else if let Some(MyType { name, age }) value_any.downcast_ref::MyType() {println!(MyType ({}, {}), name, age)} else {println!({:?}, value)} }fn main() {let ty MyType {name: Rust.to_string(),age: 30,};let name String::from(Rust);print_any(ty);print_any(name);print_any(30); }运行后输出 MyType (Rust, 30) String (4): Rust 30如上所示不论 String、MyType 自定义类型、还是内置的 i32 类型都可以被打印只要他们实现了 Debug Trait这也可以认为是Rust 中、一种函数重载的方式在读取一些结构复杂的配置时也可以直接使用 Any。 最后总结 Any Trait 并非常规意义上的 Reflection而最多是编译期反射、且只启用了 “类型检查” 和 “类型转换”并不检查结构的任意内容。 Any 符合零成本抽象因为Rust只会针对调用该函数的相关类型生成代码并且返回的是编译器内部的类型ID没有额外开销甚至可以直接使用 TypeId::of::String从而没有了 dyn any 的动态绑定开销。 虽然 Rust 没有真正的 运行时 Reflection但使用过程宏、仍可以实现大部分反射能够实现的功能如上一节的 AOP 增强 就这样bye bye 参考资料 https://www.jianshu.com/p/c4ef17bb1ca3https://rust.ffactory.org/std/any/index.htmlhttps://jasonkayzk.github.io/2022/11/24/Rust%E5%8F%8D%E5%B0%84%E4%B9%8BAny/
http://www.hkea.cn/news/14399227/

相关文章:

  • 张家港市住房城乡建设局网站达州建设局网站
  • 外国人做的篆字网站openwrt安装wordpress
  • 镇网站制作价格网站建设如何快速增加用户
  • 品牌手机网站开发深圳装饰企业前50强
  • 在西部数码做的企业网站不能与阿里巴巴网站相连接联想电脑网站建设策划书
  • 昆明个人网站建设平台支付网站认证费用怎么做分录
  • 沈阳公司网站建设公司网站做百度推广需要交费吗
  • 歌曲网站源码做网站和APP需要注册公司吗
  • 浏览器网页版免费进入淘宝seo搜索引擎原理
  • 30天网站建设全程实录做查询网站费用
  • 简单设置网站首页阳泉建设局网站
  • 关于绿色环保网站的建设历程wordpress 代码规范
  • 第9类商标有网站开发河北助手app下载
  • 谁有人跟动物做的网站要怎么做网站推广
  • 淄博市沂源县城乡建设局网站网站策划需要什么
  • 集团品牌网站建设网站不备案会怎样
  • 毕设网站代做一般预算多少钱做网站什么的好
  • 做网站的背景怎么做国外浏览器app
  • 深圳市网站设江西中联建设集团有限公司网站
  • 专业做营销网站网络广告策划的流程顺序为
  • 网站标题字体大小个人网站视频建设
  • 网站建设总体规划包括怎样免费设计logo
  • 郑州网站设计收费大型社区网站开发文档
  • 56m做图片视频的网站是什么wordpress模板关系
  • 最传统的网站推广手段济南建设工程招标网
  • 黄梅那里有做网站的房地产营销门户网站开发
  • 网站建设怎么样工作软装设计师要学什么
  • 淘宝网站建设手机版wordpress 报名插件
  • 加强宣传阵地建设 高校 网站养生网站源码下载
  • 网站交易移动网络