如何在 Rust 中使用传递依赖的特征?

问题描述 投票:0回答:1

如何在我的应用程序中使用传递依赖包中的特征?

这是我遇到的问题的一个最小说明示例:

Cargo.toml
,我有:

[dependencies]
mersenne_twister = "1.1.1"
rand = "0.8.5"

我的箱子依赖于

rand ^0.8.5
mersenne_twister ^1.1.1
,它本身又依赖于
rand >=0.3, <0.5
:

my-crate ---> rand 0.8.5
         |
         |
         ---> mersenne_twister 1.1.1  ----> rand >= 0.3, < 0.5

在我的应用程序中,我想使用

trait rand::Rng for mersenne_twister::MT19937
的实现。但是当我尝试将这个特征纳入范围时,它显然没有被识别:

use mersenne_twister::MT19937;
use rand::Rng;

fn main() {
    let mut rng = MT19937::new_unseeded();
    let mut buffer = vec![0; 0xFFFF];

    // error[E0599]: no method named `fill_bytes` found for struct `MT19937` in the current scope
    rng.fill_bytes(&mut buffer);
}

我的猜测是,

Rng
导入的
use rand::Rng;
特征是来自rand 0.8.5
,而不是实际为rand 0.4.6
实现的来自
MT19937

,即使它们是拼写的同样,它们是不同且不相关的特征,因此不能互换引用。

所以我有一些问题:
  1. 如何在我的应用程序中使用适用于 
    Rng
    MT19937
     特征?我认为我无法将 
    rand
     中对 
    0.4.6
     的依赖降级为 
    Cargo.toml
    ,因为我需要在我的应用程序中使用 
    rand 0.8.5
  2. 一般来说,应该如何使用传递依赖中定义的特征?
  3. mersenne_twister
    的API设计不重新导出
    Rng
  4. 是不好的做法吗?
rust dependencies traits semantic-versioning transitive-dependency
1个回答
0
投票

我认为我无法在 Cargo.toml 中将对 rand 的依赖降级到 0.4.6,因为我需要在我的应用程序中使用其他的 rand 0.8.5。

您可以通过重命名一个或两个版本来使用两者。
[dependencies]
rand4 = { package = "rand", version = "0.4.6" }
rand8 = { package = "rand", version = "0.8.5" }

然后您可以根据需要在代码中引用 
rand4::Rng
rand8::Rng

一般来说,应该如何使用传递依赖中定义的特征?

mersenne_twister
的API设计不重新导出
Rng

是不好的做法吗?

重新导出很方便并且经常被推荐,但无论他们是否这样做,对于已经实现的任何版本的 
mersenne_twisterstop
 实施 
rand::Rng
 都将是一个 semver 破坏性更改,所以你不必担心你的代码被破坏。

© www.soinside.com 2019 - 2024. All rights reserved.