在 Rust 中将结构作为参数传递

Posted

技术标签:

【中文标题】在 Rust 中将结构作为参数传递【英文标题】:Passing structures as arguments in Rust 【发布时间】:2021-08-16 01:00:12 【问题描述】:

我正在用 Rust 从头开始​​构建一个图形引擎。 我有一个结构点:

struct Point 
  x: i32,
  y: i32

还有一个三角形结构,就是三个点:

struct Triangle (Point,Point,Point)

.

我制作了一个特征引擎,稍后我将使用 SDL 实现它

trait Engine 
  fn draw_triangle(&self,tri:Triangle)
     self.draw_line(tri.0,tri.1);
     self.draw_line(tri.1,tri.2); // <-
     self.draw_line(tri.2,tri.0);
  
  fn draw_line(&self,p1:Point,p2:Point)


我得到一个带有箭头的错误:使用移动的值 tri.1,移动后使用的值。 我知道这与引用和所有权有关,并且尝试过改变事物,但我只是不知道自己在做什么。 我找了又找,但无济于事:我无法理解。

谁能告诉我为什么这不起作用?不仅仅是一个解决方案,我希望了解

【问题讨论】:

欢迎来到 ***!你读过关于 Rust 的书吗,比如官方的书,或者 O'Reilly 的《Programming Rust》?两者都很好地解释了 moving 的概念,足以让您理解解决方案(如您所愿)。解决办法是在struct Point的定义上面加上#[derive(Copy, Clone)]。它将使Point 的行为更像一个非常简单的原始对象(如数字或布尔值),允许通过复制而不是移动将其传递给函数。 【参考方案1】:

在第一个 draw_line 调用中,您通过了两个点 tri.0tri.1。这会将变量“移动”到draw_line 函数中,之后就不能使用它们了。有两种方法可以解决此问题。

首先,您可以在调用函数时复制(或克隆)这些点,只需在struct Point 行上方添加#[derive(Clone, Copy)]。这允许点被显式克隆(通过使用.clone() 方法)或隐式复制。这意味着每次将数据传递给函数时都会复制数据,在这种情况下这没什么大不了的。但是,对于较大的结构,需要避免这种情况,因此您可以使用以下方法。

其次,您可以将点作为参考而不是按值传递。这可以通过更改 draw_line 签名以接受 Point 引用来完成,如下所示:

fn draw_line(&self, p1: &Point, p2: &Point);

但是,这意味着您现在还需要通过引用传递点,从而导致以下特征定义:

trait Engine 
    fn draw_triangle(&self, tri: Triangle) 
        self.draw_line(&tri.0, &tri.1);
        self.draw_line(&tri.1, &tri.2);
        self.draw_line(&tri.2, &tri.0);
    

    fn draw_line(&self, p1: &Point, p2: &Point);

这导致 Points 本身没有被传递到函数中,而是对单个 Point 的引用——这意味着不需要复制结构六次(每个函数调用两次)。如果这个方法被调用很多,或者结构更大,这可能是一个显着的加速。

锈书的以下章节对所有权、引用和借用提供了详尽的解释:https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html

【讨论】:

以上是关于在 Rust 中将结构作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章

在返回视图中将 json 作为参数传递

在 AutoIT 中将函数作为参数传递

如何将 Rust 函数作为参数传递?

使用rust-protobuf时我作为参数传递什么?

在 Postman 中将类对象作为参数传递

是否可以在c中将函数作为参数传递? [复制]