0

我面临一个问题,我有一个结构(称为HomotopyOptimizer),它有许多字段(有些是借来的)。里面有HomotopyOptimizer一个带参数的方法&self mut

我所做的是,我将结构中的一些字段借给其他功能或转移它们的所有权,因为我将不再需要它们。

让我用一张图描述一下情况(我会在最后提供代码):

借用检查器问题

MyHomotopyOptimizer有两个字段:(i)一个 typeHomotopyProblem和(ii)一个 type &Cache

这些又是具有某些字段的结构。特别是,该HomotopyProblem字段具有三个字段。

Problem我需要使用 of 的字段HomotopyProblem并通过借用type 的字段来构造一个类型的结构Cacheself但是,Rust 抱怨我不能借用它,因为self本身之前已经被借过(或者至少看起来如此)。

我的主要问题是我是否可以在不移动或借出结构本身的情况下移动结构字段的所有权。


让我以相反的顺序展示我的代码。首先是我得到编译错误的函数:

impl<'cache_lifetime, 
     ParametricPenaltyFunctionType, 
     ParametricGradientType, 
     ConstraintType, ParametricCostType>
    HomotopyOptimizer<...same_as_above...>
where
    ParametricPenaltyFunctionType: Fn(&[f64], &[f64], &mut [f64]) -> Result<(), Error>,
    ParametricGradientType: Fn(&[f64], &[f64], &mut [f64]) -> Result<(), Error>,
    ParametricCostType: Fn(&[f64], &[f64], &mut f64) -> Result<(), Error>,
    ConstraintType: constraints::Constraint,
{

    pub fn solve(&'cache_lifetime mut self, u: &mut [f64]) {
        let p_ = [1., 2., 3.];

        let f_ = |u: &[f64], cost: &mut f64| -> Result<(), Error> {
            (self.homotopy_problem.parametric_cost)(u, &p_, cost)
        };
        let df_ = |u: &[f64], grad: &mut [f64]| -> Result<(), Error> {
            (self.homotopy_problem.parametric_gradient)(u, &p_, grad)
        };
        let problem_ = Problem::new(&self.homotopy_problem.constraints, df_, f_);

        let mut panoc_ = panoc::Optimizer::new(problem_, &mut self.panoc_cache);
        panoc_.solve(u);
        println!("u = {:#?}", u);
    }
}

我收到以下错误:

Compiling optimization_engine v0.3.1 (/home/chung/NetBeansProjects/RUST/optimization-engine)
error[E0502]: cannot borrow `self.panoc_cache` as mutable because it is also borrowed as immutable
  --> src/continuation/homotopy_optimizer.rs:83:63
   |
75 |         let f_ = |u: &[f64], cost: &mut f64| -> Result<(), Error> {
   |                  ------------------------------------------------ immutable borrow occurs here
76 |             (self.homotopy_problem.parametric_cost)(u, &p_, cost)
   |              ---- first borrow occurs due to use of `self` in closure
...
83 |         let mut panoc_ = panoc::Optimizer::new(problem_, &mut self.panoc_cache);
   |                          --------------------------           ^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
   |                          |
   |                          immutable borrow later used by call

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
error: Could not compile `optimization_engine`.
warning: build failed, waiting for other jobs to finish...
error[E0502]: cannot borrow `self.panoc_cache` as mutable because it is also borrowed as immutable
  --> src/continuation/homotopy_optimizer.rs:83:63
   |
75 |         let f_ = |u: &[f64], cost: &mut f64| -> Result<(), Error> {
   |                  ------------------------------------------------ immutable borrow occurs here
76 |             (self.homotopy_problem.parametric_cost)(u, &p_, cost)
   |              ---- first borrow occurs due to use of `self` in closure
...
83 |         let mut panoc_ = panoc::Optimizer::new(problem_, &mut self.panoc_cache);
   |                          --------------------------           ^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
   |                          |
   |                          immutable borrow later used by call

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
error: Could not compile `optimization_engine`.

为了完整起见:HomotopyOptimizer的定义是

pub struct HomotopyOptimizer<
    'cache_lifetime,
    ParametricPenaltyFunctionType,
    ParametricGradientType,
    ConstraintType,
    ParametricCostType,
> where
    ParametricPenaltyFunctionType: Fn(&[f64], &[f64], &mut [f64]) -> Result<(), Error>,
    ParametricGradientType: Fn(&[f64], &[f64], &mut [f64]) -> Result<(), Error>,
    ParametricCostType: Fn(&[f64], &[f64], &mut f64) -> Result<(), Error>,
    ConstraintType: constraints::Constraint,
{
    homotopy_problem: HomotopyProblem<
        ParametricPenaltyFunctionType,
        ParametricGradientType,
        ConstraintType,
        ParametricCostType,
    >,
    panoc_cache: &'cache_lifetime mut panoc::Cache,
}

它的构造函数是

pub fn new(
        homotopy_problem: HomotopyProblem<
            ParametricPenaltyFunctionType,
            ParametricGradientType,
            ConstraintType,
            ParametricCostType,
        >,
        panoc_cache: &'cache_lifetime mut panoc::PANOCCache,
    ) -> HomotopyOptimizer<
        ParametricPenaltyFunctionType,
        ParametricGradientType,
        ConstraintType,
        ParametricCostType,
    > {
        HomotopyOptimizer {
            homotopy_problem: homotopy_problem,
            panoc_cache: panoc_cache,
        }
    }

HomotopyProblem的定义是

pub struct HomotopyProblem<
    ParametricPenaltyFunctionType,
    ParametricGradientType,
    ConstraintType,
    ParametricCostType,
> where
    ParametricPenaltyFunctionType: Fn(&[f64], &[f64], &mut [f64]) -> Result<(), Error>,
    ParametricGradientType: Fn(&[f64], &[f64], &mut [f64]) -> Result<(), Error>,
    ParametricCostType: Fn(&[f64], &[f64], &mut f64) -> Result<(), Error>,
    ConstraintType: constraints::Constraint,
{
    pub(crate) constraints: ConstraintType,
    pub(crate) parametric_gradient: ParametricGradientType,
    pub(crate) parametric_cost: ParametricCostType,
    pub(crate) penalty_function: ParametricPenaltyFunctionType,
    idx: Vec<usize>,
    from: Vec<f64>,
    to: Vec<f64>,
    transition_mode: Vec<i32>,
    num_parameters: usize,
}

它的构造函数是

pub fn new(
        constraints: ConstraintType,
        parametric_gradient: ParametricGradientType,
        parametric_cost: ParametricCostType,
        penalty_function: ParametricPenaltyFunctionType,
        num_parameters: usize,
    ) -> HomotopyProblem<
        ParametricPenaltyFunctionType,
        ParametricGradientType,
        ConstraintType,
        ParametricCostType,
    > {
        HomotopyProblem {
            constraints: constraints,
            parametric_gradient: parametric_gradient,
            parametric_cost: parametric_cost,
            penalty_function: penalty_function,
            idx: Vec::new(),
            from: Vec::new(),
            to: Vec::new(),
            transition_mode: Vec::new(),
            num_parameters: num_parameters,
        }
    }
4

0 回答 0