【问题标题】:How to call function with many different types?如何调用多种不同类型的函数?
【发布时间】:2020-12-25 18:56:46
【问题描述】:

假设我们有以下枚举:

#[derive(Serialize)]
#[serde(untagged)]
pub enum CustomType {
    Foo(Foo),
    Bar(Bar),
}

为了使函数对不同的参数类型表现相同:

fn my_function(my_param: &CustomType){
  // logic to use "my_param"
  // my_param is used for the handlebars crate, therefore requires to be Serde Serializable
 let source = // ...
 handlebars.render_template(&source, my_param).unwrap();
}

我们想在程序的不同部分调用这样的函数,如下所示:

fn function_a(bar: &Bar){
  my_function(CustomType::Bar(bar.clone()));
}

fn function_b(foo: &Foo){
  my_function(CustomType::Foo(foo.clone()));
}

这段代码有效,但我真的不喜欢它,因为我必须.clone()。我已经尝试只传递引用,但它不适用于枚举。

这是在 Rust 中正确的做法吗?

【问题讨论】:

    标签: generics types rust enums overloading


    【解决方案1】:

    如果您不想调用 clone,可以让 CustomType 获取引用而不是拥有的值:

    use serde::{Serialize};
    
    #[derive(Serialize)]
    struct Foo(String);
    
    #[derive(Serialize)]
    struct Bar(String);
    
    #[derive(Serialize)]
    #[serde(untagged)]
    enum CustomType<'a> {
        Foo(&'a Foo),
        Bar(&'a Bar),
    }
    
    fn my_function(my_param: &CustomType) {
        println!("serialized {}", serde_json::to_string(&my_param).unwrap());
    }
    
    fn func_foo(foo: &Foo) {
        my_function(&CustomType::Foo(foo));
    }
    
    fn func_bar(bar: &Bar) {
        my_function(&CustomType::Bar(bar));
    }
    
    fn main() {
        let foo = Foo("Foo".to_string());
        let bar = Bar("Bar".to_string());
        func_foo(&foo);
        func_bar(&bar);
    }
    

    playground

    但是,如果CustomType 存在的唯一原因是您可以将Serializable 类型传递给my_function,那么将my_function 设为通用并接受任何Serializable 引用可能会更简单:

    use serde::{Serialize};
    
    #[derive(Serialize)]
    struct Foo(String);
    
    #[derive(Serialize)]
    struct Bar(String);
    
    fn my_function<T: Serialize>(my_param: &T) {
        println!("serialized {}", serde_json::to_string(my_param).unwrap());
    }
    
    fn main() {
        let foo = Foo("Foo".to_string());
        let bar = Bar("Bar".to_string());
        my_function(&foo);
        my_function(&bar);
    }
    

    playground

    【讨论】:

    • 是的! CustomType 的原因正是为了这个目的。我不知道你可以只使用&lt;T: Serialize&gt; 的东西(我之前尝试过&lt;T&gt;,但由于它不可序列化而停止)
    猜你喜欢
    • 2019-09-23
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多