You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中结构体变量修改后自动还原问题求助

问题:光线追踪器运行时修改变量后自动还原默认值

我正在开发一款光线追踪器,需要在运行时根据输入修改CamDir、CamPos等变量,但这些变量总是会还原为默认值。我认为问题出在将变量存储回Renderer结构体的过程中,由于是编程新手,对Rust的借用与所有权机制不太理解。已尝试过可变修饰、引用传递等多种方法但均未解决问题。代码结构为:Main.rs -> [1] App.rs -> Renderer.rs -> Camera.rs -> App.rs -> Renderer.rs -> [回到[1]]

简化复现代码

#[derive(Debug)]
pub struct feed {
    foodId: i32,
    healthy: bool
}

impl feed {
    pub fn new(foodId: i32) -> feed {
        feed {
            foodId: foodId,
            healthy: true
        }
    }
    
    pub fn newValues(mut self) {
        self.healthy = false;
        self.foodId = 234567645;
    }
}

#[derive(Debug)]
pub struct animal {
    animalType: i32, // 0 = dog, 1 = cat
    foodType: feed,
    joy: i32         // 0% -> 100%
}

impl animal {
    pub fn new(animalType: i32, foodType: feed) -> animal {
        animal {
            animalType: animalType,
            foodType: foodType,
            joy: 50
        }
    }
    
    pub fn changePetFood(self) {
        self.foodType.newValues();
    }
}

pub fn walk(mut a: animal) {
    a.changePetFood();
    a.joy = 100;
}

fn main() {
    let food = feed::new(264369);
    let doggy = animal::new(0,food);
    
    println!("{:?}",doggy); 
    walk(doggy);
    println!("{:?}",doggy);
}

核心问题与解决方案

你遇到的问题本质是值传递导致的副本修改:所有修改方法使用self参数时,会创建结构体的副本,你修改的只是临时副本而非原对象,原变量自然不会有变化。

修复后的简化代码

#[derive(Debug)]
pub struct Feed {
    food_id: i32,
    healthy: bool
}

impl Feed {
    pub fn new(food_id: i32) -> Self {
        Feed {
            food_id,
            healthy: true
        }
    }
    
    // 使用&mut self获取可变引用,直接修改原对象
    pub fn update_values(&mut self) {
        self.healthy = false;
        self.food_id = 234567645;
    }
}

#[derive(Debug)]
pub struct Animal {
    animal_type: i32, // 0 = dog, 1 = cat
    food_type: Feed,
    joy: i32         // 0% -> 100%
}

impl Animal {
    pub fn new(animal_type: i32, food_type: Feed) -> Self {
        Animal {
            animal_type,
            food_type,
            joy: 50
        }
    }
    
    // 用&mut self修改自身的food_type
    pub fn change_pet_food(&mut self) {
        self.food_type.update_values();
    }
}

// 接收可变引用,直接修改原Animal实例
pub fn walk(a: &mut Animal) {
    a.change_pet_food();
    a.joy = 100;
}

fn main() {
    let food = Feed::new(264369);
    // 声明为mut,允许后续修改
    let mut doggy = Animal::new(0, food);
    
    println!("{:?}", doggy); 
    walk(&mut doggy);
    println!("{:?}", doggy);
}

关键修改点

  1. 方法参数改为&mut self:所有需要修改结构体的方法,使用可变引用而非值传递,确保操作的是原对象而非副本
  2. 外部函数接收可变引用:walk函数接收&mut Animal,避免所有权转移,直接修改原实例
  3. 声明可变变量:主函数中doggy需用mut修饰,赋予可变性才能传递可变引用

对应到光线追踪器的修改建议

  1. 确保Renderer、Camera中修改CamDir、CamPos的方法,都使用&mut self作为参数
  2. 在整个调用链(Main -> App -> Renderer -> Camera...)中,传递可变引用而非值,避免所有权转移导致原对象未被修改
  3. 顶层的Renderer实例必须声明为mut,并在调用过程中保持可变引用传递

内容的提问来源于stack exchange,提问作者Question Asker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:37:32