如何调用多种不同类型的函数?

How to call function with many different types?

假设我们有以下枚举:

#[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 中这是正确的做法吗?

如果您不想调用 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