簡體   English   中英

自動強制&String到&str

[英]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);
}

鏈接到Rust游樂場

我認為這不能使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM