然而现在官方并不支持

但有几种方法可以安排

一. 使用Option

定义

fn add(a: Option<i32>, b: Option<i32>) -> i32 {  
    a.unwrap_or(1) + b.unwrap_or(2)
}

使用

add(Some(2), None);  
add(None, Some(4));  
add(None,None);  

用Option这种方式可以很明确的让调用者明白可以不传值的语意。

二. 使用macro

定义

fn add(a: i32, b: i32) -> i32 {  
    a + b
}
macro_rules! add {  
    ($a: expr) => {
        add($a, 2)
    };
    () => {
        add(1, 2)
    };
}

甚至可以来实现rust同样不支持的变参默认值.

macro_rules! add {  
    () => {
            0
        };
    ($a: expr) => {
            $a
        };
    ($a: expr, $($ots: expr),+) => {
        $a + add!($($ots),+)
    }


}
三. 使用From/Into trait
pub struct FooArgs {  
    a: f64,
    b: i32,
}

impl Default for FooArgs {  
    fn default() -> Self {
        FooArgs { a: 1.0, b: 1 }
    }
}

impl From<()> for FooArgs {  
    fn from(_: ()) -> Self {
        Self::default()
    }
}

impl From<f64> for FooArgs {  
    fn from(a: f64) -> Self {
        Self {
            a: a,
            ..Self::default()
        }
    }
}

impl From<i32> for FooArgs {  
    fn from(b: i32) -> Self {
        Self {
            b: b,
            ..Self::default()
        }
    }
}

impl From<(f64, i32)> for FooArgs {  
    fn from((a, b): (f64, i32)) -> Self {
        Self { a: a, b: b }
    }
}

pub fn foo<A>(arg_like: A) -> f64  
where  
    A: Into<FooArgs>,
{
    let args = arg_like.into();
    args.a * (args.b as f64)
}

fn main() {  
    println!("{}", foo(()));
    println!("{}", foo(5.0));
    println!("{}", foo(-3));
    println!("{}", foo((2.0, 6)));
}

Default trait 介绍

相比macro,代码多了,但错误提示更友好,可自定义From trait,更灵活.

Stackoverflow: Default function arguments in Rust