未实现复制特征时重构`clone`吗?

时间:2020-02-03 22:34:57

标签: rust

鉴于我在评论中指出的限制,是否有办法摆脱#include <cstddef> #include <iostream> #include <string> #include <vector> int closed_source_function(int argc, char* argv[]) { for(int i = 0; i < argc; ++i) { std::cout << argv[i] << '\n'; } return 0; } int pybind_to_this(std::vector<std::string> args) { // create a char*[] std::vector<char*> argv(args.size() + 1); // make the pointers point to the C strings in the std::strings in the // std::vector for(size_t i = 0; i < args.size(); ++i) { argv[i] = args[i].data(); } // add a terminating nullptr (main wants that, so perhaps the closed source // function wants it too) argv[args.size()] = nullptr; // call the closed source function return closed_source_function(static_cast<int>(args.size()), argv.data()); } ?我真的很想知道在这种情况下是否可以使用借用,因为在这种情况下无法修改第三方功能签名。

clone()

playground

2 个答案:

答案 0 :(得分:2)

不,您不能在这里摆脱对user-data-dir的呼叫。

这里的问题是第三方库。现在编写函数clone时,确实可以使用third_party;它不需要所有权,因为它只是移出&Vec<i32>的值。但是,由于实现不在您的控制范围之内,因此没有什么可以阻止维护该功能的人更改其功能以利用拥有Copy的优势。如果允许其覆盖提供的内存,则所做的任何事情都可能会更容易或需要更少的内存,并且函数编写器将来会为此敞开大门。如果不是这种情况,则可能值得建议更改第三方功能的签名并同时依靠Vec

答案 1 :(得分:2)

只要您的foo()方法接受&self,就不可能,因为

pub fn third_party(data: Vec<i32>) -> i32

签名非常明确:无论此third_party函数做什么,API都按值表示需要它自己的Vec实例。这排除了使用任何形式的借用的可能性,并且由于foo()通过引用接受self,因此除克隆外,您实际上无法做任何事情。

此外,据推测,此third_party的编写没有任何奇怪的不安全的技巧,因此可以肯定地假设传递给它的Vec最终会被丢弃并释放。因此,不安全地创建原始Vec的副本而不克隆(通过复制内部指针)是不成问题的-如果您这样做,肯定会获得免费使用。

虽然您的问题没有说明,但是您想要保留data的原始值的事实是一种自然的假设。如果这个假设可以放宽,那么您可以放出data实例,例如在内部用空向量替换它,那么您可以做几件事:

  1. foo(&self)切换为foo(&mut self),然后可以很容易地提取data并将其替换为空向量。
  2. 使用CellRefCell存储数据。这样,当您从单元格中提取值并将其替换为某些默认值时,您可以继续使用foo(&self),但需要进行一些运行时检查。

但是,这两种方法都会导致您丢失原始的Vec。有了给定的第三方API,就无法解决此问题。

如果您仍然可以以某种方式影响此外部API,那么最好的解决方案是将其更改为接受&[i32],可以很容易地从Vec<i32>借来获得。

相关问题