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

rust学习-any中的downcast和downcast_ref

背景

看rust官方文档,好奇Any和Go的Any是否是一回事,看到下文的一行代码,了解下它的功能

pub trait Any: 'static {// Required methodfn type_id(&self) -> TypeId;
}

std::any 用于 dynamic typing 或者 type reflection
模拟动态类型的trait。

大多数类型都实现 Any。但是,任何包含非静态引用的类型都不会。

use std::any::Any;fn main() {use std::any::{Any, TypeId};fn is_string(s: &dyn Any) -> bool {TypeId::of::<String>() == s.type_id()}assert_eq!(is_string(&0), false);assert_eq!(is_string(&"cookie monster".to_string()), true);
}

Any and TypeId

TypeId 代表一个全局唯一类型标识符
Any 本身可以用来获取 TypeId,并且当用作 Trait 对象时具有更多功能(used as a trait object)。

  • 作为 &dyn Any(借用的trait对象)
    它具有 is 和 downcast_ref 方法,用于测试包含的值是否属于给定类型(is of a given type),并获取对内部值的引用(get a reference to the inner value as a type)。
  • 作为 &mut dyn Any
    有 downcast_mut 方法,用于获取对内部值的可变引用(mutable reference)。 Box 添加向下转换方法,该方法尝试转换为 Box。

注意
&dyn Any 仅限于测试值是否属于指定的具体类型(alue is of a specified concrete type)
不能用于测试类型是否实现特征(a type implements a trait)。

Smart pointers 和 dyn Any

使用 Any 作为trait对象时要记住的一个行为,尤其是使用 Box 或 Arc 等类型时,只需对值调用 .type_id() 将生成容器的 TypeId(比如Box、Arc) ,而不是底层trait对象(simply calling .type_id() on the value will produce the TypeId of the container, not the underlying trait object)。

可以通过将智能指针转换为 &dyn Any 来避免这种情况,这将返回对象的 TypeId。

use std::any::{Any, TypeId};fn main() {let boxed: Box<dyn Any> = Box::new(3_i32);let boxed_any: &dyn Any = &Box::new(3_i32);// 对值调用 .type_id() 将生成容器的 TypeIdlet boxed_id = boxed.type_id();// 将智能指针转换为 &dyn Any 来避免这种情况,返回对象的 TypeIdlet boxed_any_id = boxed_any.type_id();// 但是你可能更期待这样let actual_id = (&*boxed).type_id();assert_eq!(boxed_id, TypeId::of::<Box<dyn Any>>()); // Box<dyn Any>assert_eq!(boxed_any_id, TypeId::of::<Box<i32>>()); // Box<i32>assert_eq!(actual_id, TypeId::of::<i32>());         // i32
}

考虑一种情况,要打印(log out)传递给函数的值。已知道正在处理的值实现 Debug(the value we’re working on implements Debug),但不知道它的具体类型。
同时又希望对某些类型给予特殊处理:在这种情况下,先打印 String 值的长度,再打印它们的值(print out the length of String values prior to their value.)。在编译时不知道值的具体类型,因此我们需要使用运行时反射(runtime reflection)。

use std::fmt::Debug;
use std::any::Any;// 对任何实现了Debug的类型进行Logger打印
fn log<T: Any + Debug>(value: &T) {// 一个值 value 进行类型转换,并将其转换为 &dyn Any 类型的引用。// 这种转换允许将一个具体类型的值视为实现了 Any trait 的类型,// 并且可以在运行时进行类型检查和转换// // 【value_any视为一个实现了 Any trait 的类型】let value_any = value as &dyn Any;// 【将动态类型转换为具体类型】// downcast_ref 方法来尝试将 &dyn Any 引用转换为 String 类型的引用// 它会返回一个 Option,以便在转换失败时处理错误情况match value_any.downcast_ref::<String>() {Some(as_string) => {println!("String ({}): {}", as_string.len(), as_string)
http://www.lryc.cn/news/179912.html

相关文章:

  • js检测数据类型总结
  • 获奖作品展示 | 2023嵌入式大赛AidLux系列作品精彩纷呈
  • Mybatis 二级缓存(使用Redis作为二级缓存)
  • VMware vSphere ESXI 6.7 U3封装RTL8125B网卡驱动
  • 黑马JVM总结(二十五)
  • 基础数据结构之——【顺序表】(上)
  • Apollo自动驾驶系统概述(文末参与活动赠送百度周边)
  • Java 21 新特性:Unnamed Classes and Instance Main Methods
  • Tomcat启动后的日志输出为乱码
  • CSP-J第二轮试题-2021年-4题
  • 10.1 今日任务:select实现服务器并发
  • P1540 [NOIP2010 提高组] 机器翻译(模拟)
  • 生信教程:ABBA-BABA分析之滑动窗口
  • 二分答案(求最大值的最小值||求最小值的最大值)
  • 思维模型 周期
  • 从 0 到 1 ,手把手教你编写《消息队列》项目(Java实现) —— 介绍项目/ 需求分析
  • Python学习之索引与切片
  • 编程每日一练(多语言实现)基础篇:满足abcd=(ab+cd)^2的数 (增加Go语言实现)
  • LeetCode 热题 HOT 100:回溯专题
  • 喝健康白酒 有益生心健康
  • 动态规划:两个数组的dp问题(C++)
  • BASH shell脚本篇2——条件命令
  • 【图论C++】Floyd算法(多源最短路径长 及 完整路径)
  • 小谈设计模式(11)—模板方法模式
  • C#程序中很多ntdll.dll、clr.dll的线程
  • 低代码工作流程管理系统:提升企业运营效率的利器
  • HIVE SQL regexp_extract和regexp_replace配合使用正则提取多个符合条件的值
  • debian 安装matlab2022b报错解决方法与问题解决思路
  • Jenkins集成AppScan实现
  • 10.1 File类