可以在Rust中模拟或使用Python的实例吗?

时间:2016-01-15 09:20:02

标签: rust

在Python中你可以这样做:

if isinstance("hello", basestring):
   print "hello is a string"
else:
   print "Not a string"

我的问题是可以使用Rust重新创建或模拟这种代码吗?如果可能的话,这种检查在Rust中是必要的还是有用的?

3 个答案:

答案 0 :(得分:4)

Rust可以通过Any提供向下转发的限制:您可以Any查询具体类型是X还是Y

虽然构造的有用性相当有限; Rust是一种静态类型的语言,所以在大多数情况下你:

  • 要么知道确切的具体类型
  • 或使用具有满足您需求的足够方法的trait

仍然,Chris Morgan开发了一个AnyMap例如存储每种类型的一个值,而不知道所述类型a-priori,然后他用来为HTTP头提供一个类型化接口而不限制头集到一个已知的集合。

答案 1 :(得分:4)

Python是动态类型的。当您编写函数def foo(x):时,调用者可以选择将任何类型的值作为参数x。这就是为什么Python有isinstance(),以便你可以检查它何时重要。

Rust是静态类型的。代码中的任何变量都具有在编译时已知的类型。对于函数参数,您必须明确地编写它:fn foo(x: String) {。对于局部变量,您可以编写它:let x: String = something();或将其留给编译器的类型推断,以根据其他信息(这里基于{的返回类型)找出:let x = something(); {1}})。有时候类型推断没有足够的上下文,你必须编写一个显式的类型注释。

如果所有内容都是已知类型,则返回true或false的something()函数没有意义。所以Rust没有一个。

请注意,特征对象和isinstance特征可以使用某种形式的动态类型:

所以你可以写:

Any

fn foo(object: &Any) { if object.is::<String>() { // ... } } 的类型仍然是静态的:它是object。但它也代表一些其他任意类型的值。您可以使用其他&Any方法访问该值,例如Any

答案 2 :(得分:1)

我认为Rust中最相似的范例是对枚举类型使用match关键字。例如,在std::net::IpAddr情况下,您可以使用匹配来决定要处理Ipv4Addr还是Ipv6Addr

use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

fn main() {
    do_something(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)));
    do_something(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)));
}

fn do_something(v: IpAddr) {
    match v {
        IpAddr::V4(_x) => {
            println!("I'm an IPv4 Address!");
        }
        IpAddr::V6(_x) => {
            println!("I'm an IPv6 Address!");
        }
    }
}

Link to Rust Playground with working example

这具有在所有地方都具有定义明确的类型的优势,这当然是必需的,因为Rust是强类型的。但是,它确实会对您如何安排数据结构产生潜在影响。因此,这种行为必须提前进行计划。