要求維護(hù)公司做網(wǎng)站整改的函百度信息流
Lambda 表達(dá)式的靈活性和強(qiáng)大功能確實(shí)為編程提供了許多便利。但是我們發(fā)現(xiàn)許多開發(fā)者仍然無法靈活運(yùn)用其便利,于是寫了這篇文章。
Lambda 允許我們編寫更簡潔和靈活的代碼。例如在處理網(wǎng)絡(luò)請(qǐng)求時(shí),我們經(jīng)常需要確保響應(yīng)與當(dāng)前的狀態(tài)或需求仍然相關(guān)。通過捕獲上下文變量,Lambda 表達(dá)式可以幫助我們?cè)谔幚懋惒交卣{(diào)時(shí)簡化邏輯。
網(wǎng)絡(luò)請(qǐng)求
案例1:通過捕獲 i64RequestIndex 實(shí)現(xiàn)丟棄過期的請(qǐng)求回包
在第一個(gè)案例中,我們通過捕獲請(qǐng)求索引 i64RequestIndex 來確保只處理最新的網(wǎng)絡(luò)請(qǐng)求。如果請(qǐng)求索引與保存在對(duì)象中的最后一個(gè)請(qǐng)求索引相匹配,則我們可以確定這是最新的請(qǐng)求,并且可以安全地處理響應(yīng)。如果索引不匹配,表明在此請(qǐng)求和響應(yīng)之間,已經(jīng)發(fā)起了新的請(qǐng)求,因此當(dāng)前的響應(yīng)已經(jīng)過時(shí),可以被丟棄。
// 成員變量:用于記錄請(qǐng)求序號(hào)
int m_myLastRequestIndex = 0;// 發(fā)送網(wǎng)絡(luò)請(qǐng)求并處理響應(yīng)
uint64_t i64RequestIndex = ++m_myLastRequestIndex;
core::network::Send(request, [=](Rsp rsp) {if (this->m_myLastRequestIndex == i64RequestIndex) {// 只處理與最后一次請(qǐng)求索引匹配的響應(yīng)}},nullptr);
案例2:合并請(qǐng)求以減少后臺(tái)壓力
第一個(gè)案例可能會(huì)發(fā)起很多無效請(qǐng)求。因此,在第二個(gè)案例中,我們不僅要檢查請(qǐng)求是否為最新的,還需要考慮合并請(qǐng)求。當(dāng)多個(gè)相似的請(qǐng)求在短時(shí)間內(nèi)發(fā)起時(shí),我們可以選擇等待第一個(gè)請(qǐng)求的響應(yīng),然后根據(jù)需要決定是否發(fā)起新的請(qǐng)求。這種方式可以減輕服務(wù)器的壓力,并提高應(yīng)用程序的性能。
// 成員變量:用于跟蹤是否有正在進(jìn)行的請(qǐng)求
bool m_isRequestPending = false;
bool m_isNeedNewRequest = false;// 發(fā)起請(qǐng)求的包裝函數(shù)
auto sendRequest = [&]() {m_isRequestPending = true;core::network::Send( request, [=](Rsp rsp) {m_isRequestPending = false;if (m_isNeedNewRequest ) {m_isNeedNewRequest = false;sendRequest();// 需要再次發(fā)起請(qǐng)求} else {// 處理最后一次請(qǐng)求的響應(yīng)}},nullptr);
};// 邏輯判斷是否需要發(fā)起請(qǐng)求
if (m_isRequestPending ) {// 如果當(dāng)前已經(jīng)有一個(gè)請(qǐng)求在進(jìn)行,則等待這個(gè)請(qǐng)求的響應(yīng)m_isNeedNewRequest = true;
} else {// 如果當(dāng)前沒有請(qǐng)求正在進(jìn)行,則發(fā)起新的請(qǐng)求sendRequest();
}
在這個(gè)例子中,我們使用一個(gè)布爾變量 m_isRequestPending 來跟蹤是否有請(qǐng)求正在進(jìn)行。如果有請(qǐng)求正在進(jìn)行,我們就等待該請(qǐng)求完成。在請(qǐng)求的回調(diào)中,我們將 isRequestPending 設(shè)置為 false 以表示請(qǐng)求已完成,并在必要時(shí)發(fā)起新的請(qǐng)求。
更多場(chǎng)景
1. 延遲執(zhí)行(Lazy Evaluation)
Lambda 可以用來實(shí)現(xiàn)延遲計(jì)算,這允許代碼僅在需要時(shí)才執(zhí)行相關(guān)計(jì)算。這在優(yōu)化性能和資源使用方面非常有用。
auto lazyValue = [expensiveComputation]() { return expensiveComputation(); };
// expensiveComputation 不會(huì)立即執(zhí)行,直到調(diào)用 lazyValue()auto result = lazyValue(); // 在這里實(shí)際執(zhí)行計(jì)算
2. 作為回調(diào)(Callbacks)
Lambda 經(jīng)常用作回調(diào)函數(shù),尤其是在 GUI 編程或事件驅(qū)動(dòng)編程中。這允許開發(fā)者在同一處代碼內(nèi)部即定義事件行為,也提供了更好的上下文管理。
button->onClick([this](){ this->doSomething(); });
3. 作為函數(shù)對(duì)象(Functors)
Lambda 可以替代傳統(tǒng)的函數(shù)對(duì)象(functors),簡化語法并提高代碼的可讀性。
std::sort(vec.begin(), vec.end(), [](int a, int b) { return a < b; });
4. 作用域保護(hù)(Scope Guard)
Lambda 可以用來實(shí)現(xiàn)作用域保護(hù)模式,確保退出作用域時(shí)自動(dòng)執(zhí)行特定的清理代碼。
auto guard = scope_guard([&] { cleanUpResources(); });
5. 實(shí)現(xiàn)裝飾器模式(Decorator Pattern)
可以使用 Lambda 表達(dá)式來實(shí)現(xiàn)裝飾器模式,動(dòng)態(tài)地添加功能。
auto withLogging = [](auto func) {return [=](auto... args) {logBefore(args...);auto result = func(args...);logAfter(result);return result;};
};auto decoratedFunction = withLogging(someFunction);
6. 線程封閉(Thread Encapsulation)
在啟動(dòng)新線程時(shí),Lambda 可以用來封裝要在線程中運(yùn)行的代碼,從而使得創(chuàng)建線程的代碼更加簡潔。
std::thread t([=] { doWork(); });
t.join();
7. 實(shí)現(xiàn)狀態(tài)機(jī)(State Machines)
Lambda 可以存儲(chǔ)在容器中,使得狀態(tài)轉(zhuǎn)換和事件處理更加靈活。
std::map<State, std::function<void(Event)>> stateMachine;
stateMachine[State::INIT] = [](Event e) { /* 處理 INIT 狀態(tài)的事件 */ };
8. 自定義迭代行為(Custom Iteration)
Lambda 可以與算法結(jié)合使用,以實(shí)現(xiàn)自定義的迭代行為。
std::for_each(collection.begin(), collection.end(), [](auto& item) { processItem(item); });
Lambda 表達(dá)式由于其匿名和內(nèi)聯(lián)特性,對(duì)于創(chuàng)建簡潔、靈活的代碼非常有用,它們已經(jīng)成為現(xiàn)代C++編程中不可或缺的工具。