处理std :: borrow :: Cow的集合

时间:2018-04-07 20:46:25

标签: rust

我有这个设置:

Shape

我得到的错误是:

use std::borrow::Cow;

fn encode_text<'a, T: Into<Cow<'a, str>>>(text: T) {}

fn encode_texts<'a, T: Into<Cow<'a, str>>>(texts: &[T]) {
    for text in texts {
        encode_text(text);
    }
}

fn main() {
    encode_texts(&vec!["foo", "bar"]);
}

这是有道理的,因为error[E0277]: the trait bound `std::borrow::Cow<'_, str>: std::convert::From<&T>` is not satisfied --> src/main.rs:7:9 | 7 | encode_text(text); | ^^^^^^^^^^^ the trait `std::convert::From<&T>` is not implemented for `std::borrow::Cow<'_, str>` | = help: consider adding a `where std::borrow::Cow<'_, str>: std::convert::From<&T>` bound = note: required because of the requirements on the impl of `std::convert::Into<std::borrow::Cow<'_, str>>` for `&T` note: required by `encode_text` --> src/main.rs:3:1 | 3 | fn encode_text<'a, T: Into<Cow<'a, str>>>(text: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ T的有效参数而encode_text不是,但不知怎的,我无法使其发挥作用。我无法致电&T,因为我无法将其从借来的内容(encode_text(*text)的{​​{1}}参数)中移除。

我没有添加texts,因为它基本上表明我希望标准库类型encode_texts能够实现where std::borrow::Cow<'_, str>: std::convert::From<&T>。如果情况不是这样,那么我添加约束将无济于事。

我遇到困难,我找不到有关如何在集合或切片中使用Cow的任何资源。

1 个答案:

答案 0 :(得分:3)

您的代码不能成为通用,因为它在非通用情况中不起作用。用以下的具体类型代替:

use std::borrow::Cow;

fn encode_text<'a, T: Into<Cow<'a, str>>>(text: T) {}

fn encode_texts(texts: &[&'static str]) {
    for text in texts {
        encode_text(text);
    }
}

fn main() {
    encode_texts(&["foo", "bar"]);
}
error[E0277]: the trait bound `std::borrow::Cow<'_, str>: std::convert::From<&&str>` is not satisfied
 --> src/main.rs:7:9
  |
7 |         encode_text(text);
  |         ^^^^^^^^^^^ the trait `std::convert::From<&&str>` is not implemented for `std::borrow::Cow<'_, str>`
  |
  = help: the following implementations were found:
            <std::borrow::Cow<'a, std::path::Path> as std::convert::From<&'a std::path::Path>>
            <std::borrow::Cow<'a, std::path::Path> as std::convert::From<std::path::PathBuf>>
            <std::borrow::Cow<'a, str> as std::convert::From<&'a str>>
            <std::borrow::Cow<'a, [T]> as std::convert::From<&'a [T]>>
          and 2 others
  = note: required because of the requirements on the impl of `std::convert::Into<std::borrow::Cow<'_, str>>` for `&&str`
note: required by `encode_text`
 --> src/main.rs:3:1
  |
3 | fn encode_text<'a, T: Into<Cow<'a, str>>>(text: T) {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Cow有一组有限的From实施:

impl<'a> From<&'a str> for Cow<'a, str> {}

impl<'a, T> From<&'a [T]> for Cow<'a, [T]>
where
    T: Clone
{}

impl<'a, T> From<Vec<T>> for Cow<'a, [T]>
where
    T: Clone,
{}

impl<'a> From<String> for Cow<'a, str> {}

&&str转换不在列表中。这有点意义,因为从&&str取消引用一个级别会给你&str,这在Cow中没用。

相反,我将代码实现为采用任何迭代器,其中值可以转换为Cow。然后,您需要在传递之前调整切片:

use std::borrow::Cow;

fn encode_text<'a, T>(_text: T)
where
    T: Into<Cow<'a, str>>,
{}

fn encode_texts<'a, I>(texts: I)
where
    I: IntoIterator,
    I::Item: Into<Cow<'a, str>>,
{
    for text in texts {
        encode_text(text);
    }
}

fn main() {
    encode_texts(["foo", "bar"].iter().cloned());
}