[英]Auto coerce &String to &str
我正在嘗試將一對字符串引用列表轉換為屬性。 它適用於&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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.