Rust 是否会擦除泛型类型? [英] Does Rust erase generic types or not?

查看:74
本文介绍了Rust 是否会擦除泛型类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Rust 中是否存在泛型类型擦除(就像在 Java 中一样)?我找不到明确的答案.

解决方案

当你使用泛型函数或泛型类型时,编译器会为每组不同的类型参数生成一个单独的实例(我相信生命周期参数会被忽略,因为它们对生成的代码没有影响).这个过程称为单态化.例如,VecVec 是不同的类型,因此 Vec::len()Vec::len() 是不同的函数.这是必要的,因为 VecVec 具有不同的内存布局,因此需要不同的机器码!因此,,没有类型擦除.

如果我们使用 Any::type_id(),如下例所示:

使用 std::any::Any;fn 主(){让 v1:Vec= Vec::new();let v2: Vec= Vec::new();让 a1 = &v1 作为 &dyn Any;让 a2 = &v2 作为 &dyn Any;println!("{:?}", a1.type_id());println!("{:?}", a2.type_id());}

我们为 Vec 的两个实例获得了不同的类型 ID.这支持 VecVec 是不同类型的事实.

然而,Rust 中的反射能力是有限的;Any 几乎就是我们现在所拥有的.您无法获得有关运行时值类型的更多信息,例如其名称或其成员.为了能够使用 Any,您必须强制转换它(使用 Any::downcast_ref()Any::downcast_mut() 到编译时已知的类型.>

Is there type erasure of generics in Rust (like in Java) or not? I am unable to find a definitive answer.

解决方案

When you use a generic function or a generic type, the compiler generates a separate instance for each distinct set of type parameters (I believe lifetime parameters are ignored, as they have no influence on the generated code). This process is called monomorphization. For instance, Vec<i32> and Vec<String> are different types, and therefore Vec<i32>::len() and Vec<String>::len() are different functions. This is necessary, because Vec<i32> and Vec<String> have different memory layouts, and thus need different machine code! Therefore, no, there is no type erasure.

If we use Any::type_id(), as in the following example:

use std::any::Any;

fn main() {
    let v1: Vec<i32> = Vec::new();
    let v2: Vec<String> = Vec::new();
    
    let a1 = &v1 as &dyn Any;
    let a2 = &v2 as &dyn Any;
    
    println!("{:?}", a1.type_id());
    println!("{:?}", a2.type_id());
}

we obtain different type IDs for two instances of Vec. This supports the fact that Vec<i32> and Vec<String> are distinct types.

However, reflection capabilities in Rust are limited; Any is pretty much all we've got for now. You cannot obtain more information about the type of a runtime value, such as its name or its members. In order to be able to work with Any, you must cast it (using Any::downcast_ref() or Any::downcast_mut() to a type that is known at compile time.

这篇关于Rust 是否会擦除泛型类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆