2

我开始对 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 现在它是负责正确类型转换的枚举的构造函数。好奇是否有办法做到这一点......是的,在某些时候我需要 &str 因为这是其他地方的参数,特别是:

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

我经历了很多事情,比如尝试返回 String 而不是&strfrom into(),但这只会导致转换问题与 a map()of String->发生关系&str。从一开始就让元组正确是最简单的事情,而不是在那之后动辄与编译器对抗。

- 更新 -

好的,所以我回到枚举函数中的一个(String,String)元组。into()事实证明,有一个url::form_urlencoded::serialize()与之兼容的功能的“拥有”版本。

pub fn serialize_owned(pairs: &[(String, String)]) -> String

但是,现在我也在尝试对 中的查询字符串使用相同的模式hyper::URL,特别是:

fn set_query_from_pairs<'a, I>(&mut self, pairs: I) 
    where I: Iterator<Item=(&'a str, &'a str)>

然后我尝试map()在 (String,String) 元组中使用的迭代器上使用:

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) } ));

但这会出错:x.0活得不够长。在这种情况下 Ref 似乎是正确的,对吧?如果我不使用 ref,那么它的 k/v 寿命不够长。我在其中缺少什么“简单”的东西吗?

4

1 回答 1

3

目前还不清楚为什么你不能这样做:

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()

你总是可以得到一个&strfrom String,例如使用 deref coercion 或显式切片。

于 2015-04-22T09:37:18.400 回答