標準庫中不存在fn take<T>(vec: Vec<T>, index: usize) -> Option<T>
的原因,是它一般不是很有用。例如,假設你有一個長度爲10的Vec<String>
,這意味着扔掉9個字符串,只使用1。這看起來很浪費。
通常,標準庫將嘗試提供在最大場景中有用的API,在這種情況下,擁有fn take<T>(vec: &mut Vec<T>, index: usize) -> Option<T>
會更合乎邏輯。
唯一的問題是如何保持不變,當然:
- 可以通過最後一個元素,這是什麼
Vec::swap_remove
做交換被保留,
- 它可以通過改變被保留後繼元素,這是
Vec::drain
做什麼。
這些非常靈活,可以適應更多特定場景,比如你的。
適應swap_remove
:
fn take<T>(mut vec: Vec<T>, index: usize) -> Option<T> {
if index < vec.len() {
Some(vec.swap_remove(index))
} else {
None
}
}
適應drain
:
fn take<T>(mut vec: Vec<T>, index: usize) -> Option<T> {
if index < vec.len() {
vec.drain(index..index+1).next()
} else {
None
}
}
注意到,前者是更有效的:它的O(1)。
爲了進一步澄清,我正在尋找消耗的Vec
,並返回一個元素的方法,無需恢復Vec
的不變量的方式remove
和swap_remove
做的開銷。
這對我來說過早的微觀優化。
首先,請注意,有必要銷燬向量的元素;您可以通過兩種方式實現:
swap_remove
,然後每個元素遍歷消滅他們,
- 遍歷每個元素來消滅它們,跳過特定
index
。
我不清楚後者會比前者快;如果有任何事情看起來更復雜,更多的分支(我建議兩個循環),這可能會甩掉預測器,並且可能不太適合矢量化。
其次,在抱怨恢復Vec
的不變量的開銷之前,你有沒有正確的配置文件的解決方案?
如果我們看一下swap_remove
變型中,有3個步驟:
swap_remove
(O(1)),
- 破壞每個剩餘元素(O(N)),
- 自由的後備記憶。
步驟2可以被優化了,如果元素沒有Drop
實施,但除此之外,我會它是一個拋是否(2)或(3)佔主導的成本。
TL; DR:恐怕你在拼鬼的問題,配置文件試圖優化之前。
你是指''選項'而不是'選項<&T>',你可以從'vec.get(index)'得到,或者你錯過'.get'存在嗎? –
loganfsmyth
@loganfsmyth我特意指'選項'就像我在問題中說的那樣。我想要的是類似於'option.take()'如果這是有道理的? –
Others
注意:如果您發現自己定期拋出「Vec」,則可能需要查看是否可以避免實現它們。不管做什麼都比做某事快,無論你做得多高效。 –