【问题标题】:What is the idiomatic way to convert a String to &str?将字符串转换为 &str 的惯用方法是什么?
【发布时间】:2015-03-13 06:22:01
【问题描述】:

我找到了许多将String 转换为&str 的方法。今天哪一个是正确的/惯用的?

let string = "hello".to_string();

let string_slice1 = &string[..];
let string_slice2: &str = &string;
let string_slice3 = &*string;

如何在不指定变量声明类型的情况下使第二种方法工作? &string as &str 之类的东西(但它不起作用)。我看到&string 具有&String 类型,但是当它被隐式转换为&str 时,它将执行隐式转换。如何使该转换明确?

【问题讨论】:

    标签: string rust


    【解决方案1】:

    String 实现了两件重要的事情:

    • Index<RangeFull, Output = str>:这使得 string[..] 的类型为 str,尽管您需要引用它(通过调用方法,允许自动引用发生,或显式为 &string[..]) .这解释了string_slice1

    • Deref<Target = str>:这使得*string 的类型为str,对未大小类型的考虑与在索引中相同。这就是string_slice3 起作用的原因以及string_slice2 起作用的一些隐藏行为。

    与 C++ 不同,& 不是纯引用运算符:它还允许首先进行解除引用。因此&string 通常是&String 类型,但如果需要也可以是&str 类型。例如,如果您要将它传递给采用&str 的方法,它会起作用,或者如果您尝试将它绑定到&str 类型的变量。这就是为什么 : &str 在这种情况下是必要的。

    普遍的共识是在可行的情况下应避免类型归属,因此第二种形式是不可取的。在第一个和第三个之间,对于哪个更可取尚无共识。

    还有String::as_str,有些人更喜欢:

    let string_slice4 = string.as_str();
    

    【讨论】:

    • 但是,如果不需要类型归属,即在可以推断出 &str 的上下文中,例如将参数传递给非泛型函数时,第二种形式会很好。
    • "...& 不是纯粹的引用运算符:它还允许首先进行解除引用。"你的意思是在第二种情况下,真的是let string_slice2: &str = &(*string);
    猜你喜欢
    • 2010-12-21
    • 1970-01-01
    • 2020-11-17
    • 2020-08-08
    • 2011-07-10
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    相关资源
    最近更新 更多