如何在Rust中使用参数重载或可选参数?

15
我正在尝试编写二叉树的打印函数,以下是我的代码:
impl TreeNode {
    fn print(&self) {
        self.print(0);
    }
    fn print(&self, level: u8) {
        for _i in range(0,level) {
            print!("\t");
        }
        match self.data {
            Some(x) => println!("{}",x),
            None => ()
        };
        match self.left {
            Some(ref x) => x.print(level+1),
            None => ()
        };
        match self.right {
            Some(ref x) => x.print(level+1),
            None => ()
        };
    }
}

我遇到了一个错误:值print的定义重复了。因此,我想知道是否有办法创建具有相同名称但不同参数的函数。另外,可选参数可以解决这个问题,但我认为目前还不可能实现(至少我在通过谷歌搜索时找不到)。那么,最好的方法是什么?重命名第二个打印函数虽然可行,但看起来很丑,并且如果我想(例如)从树的中间开始打印,则需要记住多个函数名称。
1个回答

13

Rust没有重载,因此不可能有两个名称相同但参数集不同的函数或方法。

然而,有时可以使用特质来模拟重载。这种方法可能不适用于您的用例,但您可以在标准库中看到如何实现它,其中Path::new()构造函数可以使用类似字节向量的东西调用:

Path::new("/a/b/c/d")   // argument is &str
Path::new(b"/a/b/c/d")  // argument is &[u8]
Path::new(Path::new("/a/b/c/d"))  // argument is another Path

这是通过 BytesContainer trait 完成的,new() 方法的定义如下:

fn new<T: BytesContainer>(bytes: T) -> Path { ... }

然后,你需要为所有想要实现此特性的类型进行实现:
impl<'a> BytesContainer for &'a str { ... }
impl<'a> BytesContainer for &'a [u8] { ... }
impl BytesContainer for Path { ... }
// and more

这类似于重载,因为new()无论提供什么类型的输入都会执行完全相同的操作;它只是一个方便的东西,使Path构造函数更加灵活。最终,new()只是将其参数转换为字节切片。然而,这不允许您拥有完全不同的函数名称。


3
让我感到悲伤。那么,回到我的例子,最好的做法是将第二个函数命名为“print_at_level”,然后就这样离开吗? - user439299
1
@user439299,是的,完全正确。 - Vladimir Matveev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接