[英]How to add trait bound to a non-generic type?
I have this simple generic function:我有这个简单的通用 function:
fn add_five<T: Into<i32>>(t: T) -> i32 {
5_i32 + t.into()
}
Which I would like to express using the From
trait instead of the Into
trait, however my attempted refactor:我想使用
From
特征而不是Into
特征来表达,但是我尝试重构:
fn add_five<T, i32: From<T>>(t: T) -> i32 {
5_i32 + <i32 as From<T>>::from(t)
}
Throws this compile error:引发此编译错误:
error[E0277]: cannot add `i32` to `i32`
--> src/main.rs:24:11
|
| 5_i32 + <i32 as From<T>>::from(t)
| ^ no implementation for `i32 + i32`
|
= help: the trait `Add<i32>` is not implemented for `i32`
Which is very confusing, because there is indeed an impl Add<i32> for i32
in the standard library, so what's the real problem?这很令人困惑,因为标准库中确实有一个
impl Add<i32> for i32
,那么真正的问题是什么?
Adding a trait bound to a non-generic type can only be done from the where clause:添加绑定到非泛型类型的特征只能通过 where 子句完成:
fn add_five<T>(t: T) -> i32
where
i32: From<T> // now compiles!
{
5_i32 + <i32 as From<T>>::from(t)
}
The reason <T, i32: From<T>>
fails is because the compiler parses all of the names used within <>
as identifiers for generic type parameters. <T, i32: From<T>>
失败的原因是编译器将<>
中使用的所有名称解析为泛型类型参数的标识符。
The error message is confusing because the compiler doesn't clarify when i32
refers to the concrete 32-bit signed integer type vs the function-local identifier for a generic type parameter by the same name (which also now shadows the concrete integer type).错误消息令人困惑,因为当
i32
引用具体的 32 位签名 integer 类型与同名泛型类型参数的函数本地标识符时,编译器没有说明这一点(现在它也隐藏了具体的 integer 类型)。
Here's the error message but with added clarifications:这是错误消息,但添加了说明:
error[E0277]: cannot add `i32` (generic type) to `i32` (concrete integer type)
--> src/main.rs:24:11
|
| 5_i32 + <i32 (generic type) as From<T>>::from(t)
| ^ no implementation for `i32 (concrete integer type) + i32 (generic type)`
|
= help: the trait `Add<i32 (generic type)>` is not implemented for `i32` (concrete integer type)
Or to substitute the confusingly ambiguous i32
for the more conventional U
as the generic type:或者用令人困惑的模棱两可的
i32
代替更传统的U
作为泛型类型:
error[E0277]: cannot add `U` to `i32`
--> src/main.rs:24:11
|
| 5_i32 + <U as From<T>>::from(t)
| ^ no implementation for `i32 + U`
|
= help: the trait `Add<U>` is not implemented for `i32`
The fix is to simply move the bound into the where clause, as stated above, to avoid accidentally declaring i32
as a generic type.解决方法是简单地将边界移动到 where 子句中,如上所述,以避免意外地将
i32
声明为泛型类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.