使用convert :: Into with enum来解包和转换值

时间:2015-04-22 09:04:31

标签: rust hyper

我开始对Rust感到满意,但仍有一些事情让我终生受挫。在这种特殊情况下,我想要做的是有一个枚举,可以将不同的类型包装为通用参数类,以在URL中创建强类型查询参数,尽管具体的用例是无关紧要的,并返回包装的转换价值进入& str。这是我想要做的一个例子:

enum Param<'a> {
   MyBool(bool),
   MyLong(i64),
   MyStr(&'a str),
}

impl<'a> Param<'a> {
    fn into(self) -> (&'static str, &'a str) {
        match self {
            Param::MyBool(b) => ("my_bool", &b.to_string()), // clearly wrong
            Param::MyLong(i) => ("my_long", &i.to_string()), // clearly wrong
            Param::Value(s) => ("my_str", s),
        }
    }
}

我最终要做的是处理明显的终生问题(是的,对我来说很明显,为什么生命周期对于into()函数来说还不够长):

enum Param<'a> {
   MyBool(&'a str), // no more static typing :(
   MyLong(&'a str), // no more static typing :(
   MyStr(&'a str),
}

impl<'a> Param<'a> {
    fn into(self) -> (&'static str, &'a str) {
        match self {
            Param::MyBool(b) => ("my_bool", b),
            Param::MyLong(i) => ("my_long", i),
            Param::Value(s) => ("my_str", s),
        }
    }
}

这似乎是一个丑陋的解决方法,在我真正想做的是保证某些参数的静态类型的情况下,b / c现在它是enum的构造函数,负责适当的类型转换。好奇,如果有办法做到这一点......是的,在某些时候我需要&amp; str,因为这是其他地方的参数,具体来说:

let body = url::form_urlencoded::serialize(
               vec![Param::MyBool(&true.to_string()).
                       into()].
                   into_iter());

我经历了很多事情,例如尝试从&str返回String而不是into(),但这只会导致map() {{1}的转换问题} - &gt; String。从一开始就让元组正确是最简单的事情,而不是在此后的每一个回合中对抗编译器。

- 更新 -

好的,所以我回到&str函数中的(String,String)元组作为枚举。事实证明,有一个&#34;拥有&#34;与此兼容的into()函数的版本。

url::form_urlencoded::serialize()

但是,现在我也试图在pub fn serialize_owned(pairs: &[(String, String)]) -> String 中对查询字符串使用相同的模式,特别是:

hyper::URL

然后我尝试在(String,String)元组的迭代器上使用fn set_query_from_pairs<'a, I>(&mut self, pairs: I) where I: Iterator<Item=(&'a str, &'a str)>

map()

但这会出错:params: Iterator<Item=(String, String)> url.set_query_from_pairs(params.map(|x: (String, String)| -> (&str, &str) { let (ref k, ref v) = x; (k, v) } )); 活得不够久。在这种情况下,参考似乎是对的,对吧?如果我不使用ref,那么它的k / v不能长寿。有什么东西&简单&#39;我错过了吗?

1 个答案:

答案 0 :(得分:3)

为什么你不能做到这一点并不是很清楚:

report(\d)=(?=MyReportIDToBeTested)

enum Param<'a> { MyBool(bool), MyLong(i64), MyStr(&'a str), } impl<'a> Param<'a> { fn into(self) -> (&'static str, String) { match self { Param::MyBool(b) => ("my_bool", b.to_string()), Param::MyLong(i) => ("my_long", i.to_string()), Param::MyStr(s) => ("my_str", s.into()), } } } 转化的into()效率略高于&str -> String

您始终可以从to_string()获得&str,例如用deref强制或明确的切片。