#arguments #return #proc-macro #type #no-std #overloads #varying

macro no-std fn_overloads

创建具有不同参数和返回类型的函数。请勿使用此功能。

2 个不稳定版本

0.2.0 2023 年 10 月 27 日
0.1.0 2023 年 10 月 25 日

#713 in 过程宏

MIT/Apache

12KB
226

fn_overloads

一个简单的过程宏,利用夜间功能 fn_traitsunboxed_closures 来模拟函数重载。这使得你可以为同一个函数具有不同的函数参数和返回类型。

请勿使用此功能。

示例用法

#![feature(fn_traits, unboxed_closures)]

use fn_overloads::fn_overloads;

fn_overloads! {
    pub fn multiply {
        (first: u32, second: u32) -> u32 {
            first * second
        };
        (first: &str, second: &str) -> Option<u32> {
            Some(first.parse::<u32>().ok()? * second.parse::<u32>().ok()?)
        };
    }
}

fn main() {
    println!("{} = {}", multiply(3, 5), multiply("3", "5").unwrap());
}

泛型

此宏支持泛型,但有一些限制,所有泛型都必须在函数参数中使用。

use std::{ops::Mul, str::FromStr};

fn_overloads! {
    fn double {
        // This works
        <T: Mul<u32>>(value: T) -> T::Output {
            value * 2
        };

        // This doesn't
        <R: FromStr + Mul<u32>>(value: &str) -> Option<R> {
            Some(value.parse::<R>().ok()? * 2)
        }
    }
}

异步

此宏支持异步,但默认情况下需要 allocstd。默认情况下,会启用 std 功能标志。默认情况下,宏会将异步函数转换成 Pin<Box<dyn Future<Output = T> + Send>>。要移除 Send 特质约束,在异步后添加 !Send

开启 impl_futures 标志后,宏会将异步函数转换成 impl Future<Output = T> + Send,这需要 impl_trait_in_assoc_type 夜间功能,但这样就不需要 stdalloc

use tokio::sync::{mpsc, oneshot};
use std::{rc::Rc, cell::RefCell};

fn_overloads! {
    fn send_alert {
        async (channel: mpsc::Sender<&'static str>) {
            channel.send("Oh no!").await.ok();
        }
        async (channel: oneshot::Sender<&'static str>) {
            channel.send("Oh no!").ok();
        }
        async !Send (channel: Rc<RefCell<Vec<&'static str>>>) {
            channel.borrow_mut().push("Oh no!");
        }
    }
}

依赖关系

~275–730KB
~17K SLoC