Java的instanceof等结构的功能是什么?

时间:2018-08-24 13:18:33

标签: oop object struct rust instanceof

我正在Rust中制作一个OOP聊天客户端。模块messages.rs创建并处理作为其他结构的消息传递给其他模块:SimpleMessageComplexMessage结构:

//! # Messages

use time::SteadyTime;

/// Represents a simple text message
pub struct SimpleMessage<'a> {
    pub user: ...
    pub time: &'a SteadyTime<'a>,
    pub content: &'a str,
}

/// Represents attachments, like text or multimedia files.
pub struct ComplexMessage<'a> {
    pub user: ...
    pub time: &'a SteadyTime<'a>,
    //pub content: PENDING
}

impl<'a> SimpleMessage<'a> { }
impl<'a> ComplexMessage<'a> { }

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn is_simple() {
        assert_eq!(&self.instance_of(), SimpleMessage);
    }

    #[test]
    fn is_complex() {
        assert_eq!(&self.instance_of(), ComplexMessage);
    }
}

我很难为结构找到类似Java的函数,例如InstanceOf(),该函数可能会像这样:

&self.instance_of() -> str

这将用于在GUI中处理与ComplexMessage不同的SimpleMessage,为ComplexMessage添加预览和下载按钮。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

首先,如果您尝试将Java OOP习惯用法移植到Rust,您将会遇到困难。 Rust程序员使用完全不同的习惯用法和模式,更适合于语言的设计。

也就是说,您可以使用> df2 Time A 1 5 4.80 2 6 7.76 3 7 10.72 4 8 13.68 5 9 16.64 6 10 19.60 7 11 21.18 8 12 22.76 9 13 24.34 10 14 25.92 11 15 27.50 12 16 29.94 13 17 32.38 14 18 34.82 15 19 37.26 16 20 39.70 比较类型。与std::any::TypeId相似函数可以这样实现:

instanceOf

并像这样使用它:

use std::any::{Any, TypeId};

trait InstanceOf
where
    Self: Any,
{
    fn instance_of<U: ?Sized + Any>(&self) -> bool {
        TypeId::of::<Self>() == TypeId::of::<U>()
    }
}

// implement this trait for every type that implements `Any` (which is most types)
impl<T: ?Sized + Any> InstanceOf for T {}

输出:

let msg = ComplexMessage::new();

println!("msg is ComplexMessage: {}", msg.instance_of::<ComplexMessage>());
println!("msg is SimpleMessage: {}", msg.instance_of::<SimpleMessage>());

请注意,Rust不像Java那样具有类型继承的概念,因此只会告诉您它是否完全相同。


如DK在此答案下方所评论的那样,对问题的更生锈的方法是使用msg is ComplexMessage: true msg is SimpleMessage: false 来建模您有两种消息的事实。 Rust enum与Java enum完全不同,Rust enumstruct一样强大,只不过它们模拟了替代方案而不是聚合方案。这是使用现有类型并将其包装起来的一种实现方式:

enum Message<'a> {
    Complex(ComplexMessage<'a>),
    Simple(SimpleMessage<'a>),
}

只要函数只能接受ComplexMessage,您就可以编写签名来体现这一点:

fn send_multimedia(msg: ComplexMessage) { ... }

只要您可以接受任何一种类型,请使用enum

fn get_msg_size(msg: Message) -> usize {
    match(msg) {
        Message::Complex(complex) => complex.content.len() + complex.file.size(),
        Message::Simple(simple) => simple.content.len(),
    }
}