如何定义实现具有相同名称但具有不同返回类型的结构的函数

问题描述 投票:0回答:2

我希望能够向结构体添加两个具有相同名称的方法,它们将返回不同的数据类型。

struct NumParser<'a> {
    splitting: Split<'a, &'a str>,
}

impl NumParser<'_> {
    fn new<'a>(string: &'a str) -> NumParser<'a> {
        NumParser{
            splitting: string.trim().split(" "),
        }
    }
    fn next(&mut self) -> u32 {
        self.splitting.next().unwrap().parse().unwrap()
    }
    fn next(&mut self) -> u8 {
        self.splitting.next().unwrap().parse().unwrap()
    }
}

返回的类型将由注释或我分配给它的变量的类型决定。

let mut parser: NumParser = NumParser::new(String::from("1 2 3 4 5"));

let var1: u32 = parser.next(); // the first next() would be called
let var2: u8 = parser.next(); // the second next() would be called
let arr: [u8; 2] = [parser.next(), parser.next()]; // both times the second next() would be called
var1 = parser.next(); // the first next() would be called, even without annotation

我尝试使用特征,但我似乎也无法以这种方式实现两个同名的函数。

rust struct methods
2个回答
3
投票

Rust 没有方法重载,所以这是根本不可能的。您可以使用单独的方法(

next_u8
next_u32
)或使用一种对
FromStr
通用的方法。 (我冒昧地让
next()
返回
Option<T>
。)

impl NumParser<'_> {
    fn new<'a>(string: &'a str) -> NumParser<'a> {
        NumParser {
            splitting: string.trim().split(" "),
        }
    }

    fn next<T>(&mut self) -> Option<T>
    where
        T: FromStr,
        <T as FromStr>::Err: Debug,
    {
        self.splitting.next().map(|x| x.parse().unwrap())
    }
}

fn main() {
    let mut np = NumParser::new("1 2 3");
    println!("{:?}", np.next::<u32>());
    println!("{:?}", np.next::<f32>());
    println!("{:?}", np.next::<char>());
    println!("{:?}", np.next::<u8>());
}
Some(1)
Some(2.0)
Some('3')
None

2
投票

正如另一个答案所指出的,你不能在 Rust 中这样做,因为它不允许方法重载。但是,如果您不喜欢多个函数,还有一个不涉及多个函数名称的替代解决方案——使用枚举:

#[derive(Debug)]
enum Answer {
    Number(u8),
    Text(String)
}

struct Foo {}

impl Foo {
    fn do_something(condition: bool) -> Answer {
        if condition {
            Answer::Number(123)
        } else {
            Answer::Text("Hello".to_string())
        }
    }
}


fn main() {
    println!("{:?}", Foo::do_something(true));
    println!("{:?}", Foo::do_something(false));
}

playground 中运行它将会显示以下输出:

Number(123)
Text("Hello")
© www.soinside.com 2019 - 2024. All rights reserved.