gpt4 book ai didi

string - From<&String> 特性没有为 String 类型实现

转载 作者:行者123 更新时间:2023-11-29 07:48:10 27 4
gpt4 key购买 nike

我打算离开 this 文章,尝试编写一个接受字符串和 &str 的函数,但我遇到了问题。我有以下功能:

pub fn new<S>(t_num: S) -> BigNum where S: Into<String> {
let t_value = t_num.into();
let t_digits = t_value.len();
BigNum { value: t_value, digits: t_digits }
}

BigNum 是一个简单的结构,但是问题是当我试图用 &collections::string::String 调用它时我得到一个错误:

let line = "123456".to_string()
let big = bignum::BigNum::new(&line)

main.rs:23:15: 23:34 error: the trait `core::convert::From<&collections::string::String>` is not implemented for the type `collections::string::String` [E0277]
main.rs:23 let big = bignum::BigNum::new(&line);

我的印象是 &String 将隐式分解为 &str 不是吗?在这种情况下,Into 特性会将 &str 转换为我可以使用的字符串。我做错了什么?

最佳答案

您将两个不同的过程混为一谈。

首先是强制;特别是, Deref coercion .当编译器发现您有一个 &U 时,就会发生这种情况。 ,但你想要一个&T .如果有一个 impl Deref<Target=T> for U ,它会为你做强制。这就是为什么 &String将强制转换为 &str .

但是,当编译器替换泛型类型参数时,这不会发挥作用。当你说 BigNum::new(&line) ,编译器看到的是您正在尝试传递 &String它期望 S 的地方;因此,S必须是 &String ,因此 S必须实现 Into<String>还有……哦不!它没有! BOOM! 永远不会触发强制转换,因为编译器永远不需要强制转换任何东西;未实现的类型约束是一个不同的问题。

在这种特殊情况下,您应该做什么取决于您的情况:

  • 你可以传递一个 String ;使用 lineline.clone() .这是最有效的,因为您始终可以传入一个拥有的 String您不再需要并避免额外分配。

  • 您可以改为使用 &SS: ?Sized + AsRef<str> ,它不允许您传递拥有的字符串,但如果您总是要分配,这可能更符合人体工程学。

下面是两者的一个例子:

use std::convert::AsRef;

fn main() {
take_a_string(String::from("abc"));
// take_a_string(&String::from("abc")); // Boom!
take_a_string("def");

// take_a_string_ref(String::from("abc")); // Boom!
take_a_string_ref(&String::from("abc"));
take_a_string_ref("def");
}

fn take_a_string<S>(s: S)
where S: Into<String> {
let s: String = s.into();
println!("{:?}", s);
}

fn take_a_string_ref<S: ?Sized>(s: &S)
where S: AsRef<str> {
let s: String = s.as_ref().into();
println!("{:?}", s);
}

关于string - From<&String> 特性没有为 String 类型实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31492344/

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