我正在尝试将一对字符串引用列表转换为属性。它适用于 &str
或 &str
其次是 &String
(将 Deref
编辑为 &str)或 String.as_ref()
.但是当第一个参数是 &String
类型时,编译器错误:
the trait std::convert::AsRef<[(&'static str, &str)]> is not implemented for [(&str, &std::string::String); 1]
如何允许&String
强制&str
作为第一个参数?
use std::collections::HashMap;
#[derive(Debug)]
pub struct Attributes<'a>(HashMap<&'static str, &'a str>);
impl<'a, T> From<T> for Attributes<'a>
where
T: AsRef<[(&'static str, &'a str)]>,
{
fn from(item: T) -> Self {
Attributes(item.as_ref().into_iter().map(|&(k, v)| (k, v)).collect())
}
}
fn main() {
let fruit = "banana".to_string();
let attr: Attributes = [("fruit", "apple"), ("new_fruit", &fruit)].into(); // This works. As it is coerced into &str because of the first one.
let another: Attributes = [("fruit", &fruit)].into(); // Does not work as type is &String. Help! Make it work.
let one_more: Attributes = [("fruit", fruit.as_ref())].into(); // Works
println!("{:?}", attr);
println!("{:?}", another);
println!("{:?}", one_more);
}
最佳答案
我不认为这会使用 AsRef
起作用因为同一类型可以自由实现这两个 AsRef<[(&str, &str)]>
和 AsRef<[(&str, &String)]>
,这在您使用 AsRef
的任何方面都是模棱两可的.
您可以改为直接实现 From
对于您想要支持的那些类型,例如各种大小的数组。
use std::collections::HashMap;
#[derive(Debug)]
pub struct Attributes<'a>(HashMap<&'static str, &'a str>);
macro_rules! array_impls {
($($N:expr)+) => {
$(
impl<'a> From<[(&'static str, &'a str); $N]> for Attributes<'a> {
fn from(array: [(&'static str, &'a str); $N]) -> Self {
Attributes(array.iter().cloned().collect())
}
}
impl<'a> From<[(&'static str, &'a String); $N]> for Attributes<'a> {
fn from(array: [(&'static str, &'a String); $N]) -> Self {
Attributes(array.iter().map(|&(k, v)| (k, v.as_ref())).collect())
}
}
)*
}
}
array_impls! {
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
}
fn main() {
let fruit = "banana".to_string();
// From<[(&str, &str); 2]>
let attr: Attributes = [("fruit", "apple"), ("new_fruit", &fruit)].into();
println!("{:?}", attr);
// From<[(&str, &String); 1]>
let another: Attributes = [("fruit", &fruit)].into();
println!("{:?}", another);
}
关于rust - 自动将 &String 强制转换为 &str,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48970275/