借用/移动字段似乎可以移动整个结构

时间:2019-05-23 21:10:51

标签: rust borrow-checker borrowing borrow

我遇到一个问题,其中我有一个结构(称为HomotopyOptimizer),该结构具有许多字段(有些是借来的)。在HomotopyOptimizer中,有一个带有参数&self mut的方法。

我要做的是获取结构的某些字段,然后将其借用到其他职能部门或转移其所有权,因为我将不再需要它们。

让我用图形描述情况(我将在最后提供代码):

Borrow checker issue

我的HomotopyOptimizer有两个字段:(i)类型为HomotopyProblem的一个和(ii)类型为&Cache的一个。

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

我需要使用Problem的字段并通过借用 HomotopyProblem的{​​{1}}类型的字段来构造Cache类型的结构但是,Rust抱怨我不能借用它,因为 self 本身已经被借用了(或者至少看起来是这样)。

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


让我以相反的顺序显示我的代码。首先是出现编译错误的函数:

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);
    }
}

出于完整性考虑: HomotopyOptimizer 的定义是

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`.

及其构造函数为

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,
}

HomotopyProblem 的定义是

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,
        }
    }

及其构造函数为

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,
}

0 个答案:

没有答案