String 来自<&;字符串>;未为类型字符串实现trait
我在写这篇文章的时候试图编写一个同时接受字符串和a&str的函数,但我遇到了一个问题。我有以下功能:String 来自<&;字符串>;未为类型字符串实现trait,string,rust,ownership,String,Rust,Ownership,我在写这篇文章的时候试图编写一个同时接受字符串和a&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 } } main.rs:
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 }
}
main.rs:23:15:23:34错误:未为类型`collections::string::string`[E0277]实现特性`core::convert::From`
main.rs:23让big=bignum::bignum::new(&line);
我的印象是
&String
将被隐式分解为&str
否?在这种情况下,转换成
特征会将&str
转换成一个我可以使用的字符串。我做错了什么?你把两个不同的过程混为一谈了
首先是强迫;特别是。当编译器看到您有一个&U
,但您想要一个&T
时,就会发生这种情况。如果U有一个impl-Deref
,它将为您执行强制。这就是&String
将强制为&str
的原因
但是,当编译器替换泛型类型参数时,这不会起作用。当您说BigNum::new(&line)
时,编译器看到的是您试图将&String
传递给它期望的S
;因此,S
必须是&String
,因此S
必须将实现为,并且。。。哦,不!没有轰强制从不触发,因为编译器从不需要强制任何内容;未实现的类型约束是另一个问题
在这种情况下,您应该做什么取决于您的情况:
- 您只需传递一个
字符串
;使用line
或line.clone()
。这是最有效的,因为您可以始终传入您不再需要的已拥有的字符串,并避免额外分配
- 您可以使用
S:?Sized+AsRef
来代替&S
,这不允许您传递拥有的字符串,但是如果您总是要分配,这可能更符合人体工程学
下面是两种方法都起作用的一个例子:
使用std::convert::AsRef;
fn main(){
取一个字符串(字符串::from(“abc”);
//拿一个字符串(&string::from(“abc”);//轰!
取一个字符串(“def”);
//拿一个字符串作为参考(字符串::from(“abc”);//砰!
获取字符串引用(&string::from(“abc”);
以字符串为参考(“定义”);
}
fn取一根线(s:s)
S:去哪里{
设s:String=s.into();
println!(“{:?}”,s);
}
fn获取字符串参考(s:&s)
其中S:AsRef{
设s:String=s.as_ref().into();
println!(“{:?}”,s);
}
正如DK所提到的,这是不可能的,因为trustInto
特性缺少Into for&String的实现。我找不到背后的原因,但你可以创造自己的特质来解决这个问题:
pub trait IntoString {
fn into(self) -> String;
}
impl IntoString for &String {
fn into(self) -> String {
self.to_string()
}
}
impl IntoString for &str {
fn into(self) -> String {
self.to_string()
}
}
impl IntoString for String {
fn into(self) -> String {
self
}
}
pub fn new<S>(t_num: S) -> BigNum where S: IntoString {
let t_value = t_num.into();
let t_digits = t_value.len();
BigNum { value: t_value, digits: t_digits }
}
pub-trait-IntoString{
fn为(self)->字符串;
}
impl IntoString for&String{
fn到(self)->字符串{
self.to_string()
}
}
impl IntoString for&str{
fn到(self)->字符串{
self.to_string()
}
}
字符串的impl IntoString{
fn到(self)->字符串{
自己
}
}
pub fn new(t_num:S)->BigNum其中S:IntoString{
让t_value=t_num.into();
设t_digits=t_value.len();
BigNum{value:t_值,数字:t_数字}
}
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);
pub trait IntoString {
fn into(self) -> String;
}
impl IntoString for &String {
fn into(self) -> String {
self.to_string()
}
}
impl IntoString for &str {
fn into(self) -> String {
self.to_string()
}
}
impl IntoString for String {
fn into(self) -> String {
self
}
}
pub fn new<S>(t_num: S) -> BigNum where S: IntoString {
let t_value = t_num.into();
let t_digits = t_value.len();
BigNum { value: t_value, digits: t_digits }
}