这是什么意思? "This is precisely because a library should not be deterministically recompiled for all users of the library."
what does this mean? "This is precisely because a library should not be deterministically recompiled for all users of the library."
我是 Rust 的新手,正在尝试了解 Cargo 的东西。我在他们的常见问题解答中阅读了有关 "why do binaries have Cargo.lock in version control, but not libraries?" 的内容,但不明白这是什么意思。
”依赖于该库的用户不会检查该库的Cargo.lock(即使它存在)。这恰恰是因为一个库不应该为该库的所有用户确定性地重新编译。
如果一个库最终被多个依赖项传递使用,很可能只需要该库的一个副本(基于 semver 兼容性)。如果 Cargo 使用了所有依赖项的 Cargo.lock 文件,那么可以使用库的多个副本,甚至可能会发生版本冲突。"
如果有人能解释一下,我将不胜感激。谢谢
假设我们有以下板条箱:
string-tools
:这是一种常用的库,导出一个 FastString
结构,可以更快地实现一些常用功能。这个库有两个版本:1.0.1 和 1.0.2。最近发布了 1.0.2 版本。
database
:一个与您最喜欢的数据库接口的库。它需要做一些字符串处理,所以它使用 string-tools
库。 database
中的一种 public 方法具有如下签名:
fn get_username(id: u64) -> string_tools::FastString
该库没有机会或需要更新到 string-tools
的 1.0.2 版 - 也许它不受补丁中修复的任何错误的影响。因此,Cargo.lock 将 string-tools
的版本固定为 1.0.1.
client
:该库用于与客户端交互。它还依赖于 string-tools
,并且有一个像这样的方法:
fn show_name(name: string_tools::FastString)
该库使用的是最新版本 string-tools
,版本 1.0.2。这也是其 Cargo.lock. 中的版本
您想编写一个使用 database
和 client
库的网站。当您构建项目时,Cargo 会使用 Cargo.lock 中指定的版本编译每个库的依赖项。这意味着 database
使用 string-tools
的 1.0.1 版,而 client
使用 1.0.2 版。但现在假设您编写了如下代码:
client::show_name(database::get_username(id));
这个应该编译。毕竟get_username
函数returns一个string_tools::FastString
,被show_name
函数接受。但事实并非如此!那是因为 get_username
返回的 FastString
来自 string_tools
的 1.0.1 版本,而 show_name
想要来自 1.0.2 版本的 FastString
!这行不通;毕竟,在为 1.0.2 版本编写 string-tools
的补丁时,作者可能会向该类型添加一个额外的字段。编译器没有任何合理的做法。
让 Cargo 忽略库上的 Cargo.lock 文件可以避免此类问题。相反,它所做的是针对 string_tools
的 1.0.2 版本编译 database
和 client
。这是正确的,因为 1.0.1 和 1.0.2 是“semver 兼容版本”。这意味着可以将一个换成另一个,事情仍然必须编译。现在您不再遇到编译器错误,因为一个函数 returns 和另一个函数接受的类型不再不同。
我是 Rust 的新手,正在尝试了解 Cargo 的东西。我在他们的常见问题解答中阅读了有关 "why do binaries have Cargo.lock in version control, but not libraries?" 的内容,但不明白这是什么意思。
”依赖于该库的用户不会检查该库的Cargo.lock(即使它存在)。这恰恰是因为一个库不应该为该库的所有用户确定性地重新编译。
如果一个库最终被多个依赖项传递使用,很可能只需要该库的一个副本(基于 semver 兼容性)。如果 Cargo 使用了所有依赖项的 Cargo.lock 文件,那么可以使用库的多个副本,甚至可能会发生版本冲突。"
如果有人能解释一下,我将不胜感激。谢谢
假设我们有以下板条箱:
string-tools
:这是一种常用的库,导出一个FastString
结构,可以更快地实现一些常用功能。这个库有两个版本:1.0.1 和 1.0.2。最近发布了 1.0.2 版本。database
:一个与您最喜欢的数据库接口的库。它需要做一些字符串处理,所以它使用string-tools
库。database
中的一种 public 方法具有如下签名:
该库没有机会或需要更新到fn get_username(id: u64) -> string_tools::FastString
string-tools
的 1.0.2 版 - 也许它不受补丁中修复的任何错误的影响。因此,Cargo.lock 将string-tools
的版本固定为 1.0.1.client
:该库用于与客户端交互。它还依赖于string-tools
,并且有一个像这样的方法:
该库使用的是最新版本fn show_name(name: string_tools::FastString)
string-tools
,版本 1.0.2。这也是其 Cargo.lock. 中的版本
您想编写一个使用 database
和 client
库的网站。当您构建项目时,Cargo 会使用 Cargo.lock 中指定的版本编译每个库的依赖项。这意味着 database
使用 string-tools
的 1.0.1 版,而 client
使用 1.0.2 版。但现在假设您编写了如下代码:
client::show_name(database::get_username(id));
这个应该编译。毕竟get_username
函数returns一个string_tools::FastString
,被show_name
函数接受。但事实并非如此!那是因为 get_username
返回的 FastString
来自 string_tools
的 1.0.1 版本,而 show_name
想要来自 1.0.2 版本的 FastString
!这行不通;毕竟,在为 1.0.2 版本编写 string-tools
的补丁时,作者可能会向该类型添加一个额外的字段。编译器没有任何合理的做法。
让 Cargo 忽略库上的 Cargo.lock 文件可以避免此类问题。相反,它所做的是针对 string_tools
的 1.0.2 版本编译 database
和 client
。这是正确的,因为 1.0.1 和 1.0.2 是“semver 兼容版本”。这意味着可以将一个换成另一个,事情仍然必须编译。现在您不再遇到编译器错误,因为一个函数 returns 和另一个函数接受的类型不再不同。