gpt4 book ai didi

rust - 为什么 String 不实现 From<&String>?

转载 作者:行者123 更新时间:2023-11-29 07:58:06 26 4
gpt4 key购买 nike

背景

我知道在 Rust 中人们更喜欢 &str而不是 &String .但在某些情况下,我们只得到了 &String .

一个例子是当你调用 std::iter::Iterator::peekable .返回值为 Peekable<I>将原始迭代器包装到其中并为您提供一个额外方法的对象 peek .

这里的重点是 peek只给你一个迭代器项的引用。因此,如果您有一个包含 String 的迭代器s,你只有&String在这种情况下。当然,您可以轻松使用 as_str得到 &str但在我将在下面显示的代码中,它等效于对 clone 的调用.

问题

这段代码

#[derive(Debug)]
struct MyStruct(String);

impl MyStruct {
fn new<T>(t: T) -> MyStruct
where
T: Into<String>,
{
MyStruct(t.into())
}
}

fn main() {
let s: String = "Hello world!".into();
let st: MyStruct = MyStruct::new(&s);
println!("{:?}", st);
}

不编译因为String没有实现 From<&String> .这不直观。

为什么这不起作用?它只是标准库缺少的功能,还是有其他一些原因阻止标准库实现它?

在实际代码中,我只引用了一个String。我知道要让它工作我只需要调用clone相反,但我想知道为什么。

最佳答案

要解决您的问题,可以想象向标准库添加一个新的通用实现:

impl<'a, T: Clone> From<&'a T> for T { ... }

或者让它更通用:

impl<B, O> From<B> for O where B: ToOwned<Owned=O> { ... }

但是,这样做有两个问题:

  1. 特化:允许重叠 trait-impls 的特化特性仍然不稳定。事实证明,以合理的方式设计特化是一种方式more difficult than expected (主要是由于生命周期)。

    如果它不稳定,Rust 开发人员会非常小心,不要在标准库的公共(public) API 中的某处公开该功能。这并不意味着它根本没有在 std 中使用!一个著名的例子是 str 的专用 ToString impl。有人介绍in this PR .正如您在 PR 的讨论中看到的那样,他们只接受了它,因为它不会更改 API(to_string() 已经为 str 实现)。

    但是,当我们添加上面的通用 impl 时就不一样了:它会更改 API。因此,std 中还不允许使用它。

  2. corestd:特征 FromInto定义在 core library ,而 CloneToOwned 是在 std 中定义的。这意味着我们不能在 core 中添加一个通用的 impl,因为 corestd 一无所知。但是我们也不能在 std 中添加泛型 impl,因为泛型 impl 需要与 trait 在同一个 crate 中(这是孤立规则的结果)。

    因此,在能够添加此类通用实现之前,需要某种形式的重构和移动定义(这可能困难也可能不困难)。


注意添加

impl<'a> From<&'a String> for String { ... }

... 工作得很好。它不需要特化,也没有孤儿规则的问题。但当然,当通用实现有意义时,我们不想添加特定实现。

(感谢 IRC 上可爱的人们向我解释东西)

关于rust - 为什么 String 不实现 From<&String>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45118060/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com