我有一些像這樣的代碼:防止忘記調用一個方法
foo.move_right_by(10);
//do some stuff
foo.move_left_by(10);
這真的很重要,我的那些操作最終的同時執行,但我常常忘記做第二第一個之後。它導致了很多錯誤,我想知道是否有一種習慣性的Rust方法來避免這個問題。有沒有辦法讓鏽蝕編譯器在我忘記時讓我知道?
我的想法是,也許在某種程度上是這樣的:
// must_use will prevent us from forgetting this if it is returned by a function
#[must_use]
pub struct MustGoLeft {
steps: usize;
}
impl MustGoLeft {
fn move(&self, foo: &mut Foo) {
foo.move_left_by(self.steps);
}
}
// If we don't use left, we'll get a warning about an unused variable
let left = foo.move_left_by(10);
// Downside: move() can be called multiple times which is still a bug
// Downside: left is still available after this call, it would be nice if it could be dropped when move is called
left.move();
有沒有更好的方式來做到這一點?
另一個想法是實施Drop
和panic!
如果在沒有調用該方法的情況下丟棄該結構。這不是很好,因爲它是一個運行時檢查,並且這是非常不可取的。
編輯:我意識到我的例子可能太簡單了。所涉及的邏輯可能會變得非常複雜。例如,我們有這樣的事情:
foo.move_right_by(10);
foo.open_box(); // like a cardboard box, nothing to do with Box<T>
foo.move_left_by(10);
// do more stuff...
foo.close_box();
請注意,操作不是以很好的,正確的嵌套順序執行的。唯一重要的是反向操作總是在之後被調用。有時需要以某種方式指定訂單,以使代碼按預期工作。
我們甚至可以有這樣的事情:
foo.move_right_by(10);
foo.open_box(); // like a cardboard box, nothing to do with Box<T>
foo.move_left_by(10);
// do more stuff...
foo.move_right_by(10);
foo.close_box();
foo.move_left_by(10);
// do more stuff...
只是爲了澄清:兩個方法必須在封閉函數內的某個點被調用?訂單是否相關?或者你只是想確保,*如果*'move_right()'被調用,'move_left()'也被調用?另外:你可以描述封閉功能嗎?它會返回任何東西嗎? –
OP,如果在調用move_right()後必須調用'move_left()',則可以將這些功能打包以返回自動調用'move_left()'的Drop類型的自定義類型 - 儘管如果你的第二個FN必須返回值等等,這可能是不可能的......這可能是一個想法,但它可能會很快變得醜陋。 – musicmatze
如果你可以表示一系列調用作爲一個狀態機來執行,那麼狀態可以被編碼爲類型,並在'self'上進行方法調用(消耗當前狀態併產生一個新狀態)。這是可能的,還是不夠靈活? –