在分离的mod中使用实现时,多个``impl''错误
挖掘孤儿规则的主题,我最终得到了类型的实现”板条箱。但是结果,我现在还有另一个关于特征实现的问题。以下示例效果很好:
orphan/ | c1/ | src/lib.rs | pub trait MyTrait<T> {
| | | fn my_task(&self);
| | | }
| |
| | Cargo.toml -> DEFINITION BELOW
|
| c2/ | src/lib.rs | pub struct MyStruct;
| |
| | Cargo.toml -> DEFINITION BELOW
|
| c3/ | src/lib.rs | use c1::MyTrait; use c2::MyStruct;
| | | pub enum MyT {}
| | | impl MyTrait<MyT> for MyStruct {
| | | fn my_task(&self) { println!("This is c3 implementation"); }
| | | }
| |
| | Cargo.toml -> DEFINITION BELOW
|
| c4/ | src/lib.rs | use c1::MyTrait; use c2::MyStruct;
| | | pub enum MyT {}
| | | impl MyTrait<MyT> for MyStruct {
| | | fn my_task(&self) { println!("This is c4 implementation"); }
| | | }
| |
| | Cargo.toml -> DEFINITION BELOW
|
| c5/ | src/main.rs | mod _3 {
| | | use c1::*; use c2::*; use c3::*;
| | | pub fn f() { MyTrait::<MyT>::my_task(&MyStruct); }
| | | }
| | | mod _4 {
| | | use c1::*; use c2::*; use c4::*;
| | | pub fn f() { MyTrait::<MyT>::my_task(&MyStruct); }
| | | }
| | | fn main() { _3::f(); _4::f(); }
| |
| | Cargo.toml -> DEFINITION BELOW
|
| Cargo.toml | [workspace]
| members = [ "c1", "c2", "c3", "c4", "c5", ]
与结果:
cargo run --release
Compiling c5 v0.0.1 (XXX\orphan\c5)
Finished release [optimized] target(s) in 0.27s
Running `target\release\c5.exe`
This is c3 implementation
This is c4 implementation
但是,如果我替换了主:
main.rs | mod _3 {
| use c1::*; use c2::*; use c3::*;
| pub fn f() { MyTrait::my_task(&MyStruct); }
| }
| mod _4 {
| use c1::*; use c2::*; use c4::*;
| pub fn f() { MyTrait::<MyT>::my_task(&MyStruct); }
| }
| fn main() { _3::f(); _4::f(); }
获得以下错误:
--> c5\src\main.rs:3:18
|
3 | pub fn f() { MyTrait::my_task(&MyStruct); }
| ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the trait `MyTrait`
|
= note: multiple `impl`s satisfying `c2::MyStruct: c1::MyTrait<_>` found in the following crates: `c3`, `c4`:
- impl c1::MyTrait<c3::MyT> for c2::MyStruct;
- impl c1::MyTrait<c4::MyT> for c2::MyStruct;
为什么使用“使用c3 :: ...;”时,为什么会出现此错误。和“使用C4 :: ...;”在分离的mod中应用吗?
顺便说一句,以下情况非常有效(Unused_imports仅避免警告):
main.rs | mod _3 {
| use c1::*; use c2::*; #[allow(unused_imports)] use c3::*;
| pub fn f() { MyTrait::my_task(&MyStruct); }
| }
| fn main() { _3::f(); }
带有结果:
cargo run --release
Compiling c5 v0.0.1 (XXX\orphan\c5)
Finished release [optimized] target(s) in 0.28s
Running `target\release\c5.exe`
This is c3 implementation
因此,此行为有点奇怪:仅当C3 :: myt and c4 :: myt c3 :: myt均缺乏涡轮人的编译器,而没有涡轮。被使用,但这似乎是紫色的,因为它们用于分离的mod中。
附加组件:货物文件的详细定义:
c1/Cargo.toml | [package]
| name = "c1"
| version = "0.0.1"
| edition = "2021"
| [dependencies]
c2/Cargo.toml | [package]
| name = "c2"
| version = "0.0.1"
| edition = "2021"
| [dependencies]
c3/Cargo.toml | [package]
| name = "c3"
| version = "0.0.1"
| edition = "2021"
| [dependencies]
| c1 = { path = "../c1", version = "0.0.1" }
| c2 = { path = "../c2", version = "0.0.1" }
c4/Cargo.toml | [package]
| name = "c4"
| version = "0.0.1"
| edition = "2021"
| [dependencies]
| c1 = { path = "../c1", version = "0.0.1" }
| c2 = { path = "../c2", version = "0.0.1" }
c5/Cargo.toml | [package]
| name = "c5"
| version = "0.0.1"
| edition = "2021"
| [dependencies]
| c1 = { path = "../c1", version = "0.0.1" }
| c2 = { path = "../c2", version = "0.0.1" }
| c3 = { path = "../c3", version = "0.0.1" }
| c4 = { path = "../c4", version = "0.0.1" }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是因为您的特征是通用的,并且Rust没有真正的方法可以找出没有Turbofish的类型(
::&lt;&gt;
)。在此情况下,这似乎很明显,因为只有一个impl
,但这并不是典型的,因为它实际上并不是一个通用的意义。要亲自查看此内容,在
C3
中,您可以添加第二个Impl
block,现在很容易看到无法推断type type type parameter t t
,它很容易成为myt
或i32
。然后,您可以指定任何一个类型
_3 :: f
来歧义函数呼叫:我对为什么您的最后一个示例(“以下情况非常有效”)没有很好的解释同样的问题。
It is because your trait is generic, and there is no real way for Rust to figure out which type it should be without the turbofish (
::<>
). In this case, it seems obvious because there is only oneimpl
, but that's not typical, because then there isn't really a point of it being generic.To see this yourself, in
c3
, you can add a secondimpl
block, and now it is pretty easy to see what it means bycannot infer type parameter T
, it could just as easily beMyT
ori32
.You can then specify either type in
_3::f
to disambiguate the function call:I don't have a good explanation on why your last example ("the following case works perfectly") doesn't experience the same issues though.
如图所示: [Playground]
导致:
因此,在此问题的示例中不可能将MyTrait的两个实现用于同一板条箱C5中的Mytruct而不使用Turbofish。
Implementations seem ubiquitous through the entire crate as shown in example: [playground]
resulting in:
For this reason, it is not possible in the example of this question to use the two implementations of MyTrait for MyStruct in same crate c5 without using the turbofish.