1. 程式人生 > >C++開發EOS基礎指南:叠代器和Lambda表達式

C++開發EOS基礎指南:叠代器和Lambda表達式

i++ 深入學習 數字 variable java工程師 結束 有意義 pen 需要

讓我們來談談叠代器,它是一個非常有用的工具,在整個EOS代碼庫中大量使用。如果您來自JavaScript背景,您可能已經熟悉叠代器,就像它們用於循環一樣。叠代器的關鍵概念是提供一種更好的方法來遍歷項集合。額外的好處是您可以為任何自定義類實現叠代器接口,使叠代器成為遍歷數據的通用方法。

// @url: https://repl.it/@MrToph/CPPBasics-Iterators
#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<int> v{2, 3, 5, 8};
  // old way to iterate
  for (int i = 0; i < v.size(); i++)
  {
    cout << v[i] << "\n";
  }

  // using Iterators
  // begin() returns an iterator that points to the beginning of the vector
  // end() points to the end, can be compared using != operator
  // iterators are incremented by using the + operator thanks to operator-overloading
  for (vector<int>::iterator i = v.begin(); i != v.end(); i++)
  {
    // iterators are dereferenced by * like pointers
    // returns the element the iterator is currently pointing to
    cout << *i << "\n";
  }

  // auto keyword allows you to not write the type yourself
  // instead C++ infers it from the return type of v.begin
  for (auto i = v.begin(); i != v.end(); i++)
  {
    cout << *i << "\n";
  }

  // can use arithmetic to "jump" to certain elements
  int thirdElement = *(v.begin() + 2);
  cout << "Third: " << thirdElement << "\n";
  // end is the iterator that points to the "past-the-end" element
  // The past-the-end element is the theoretical element that would follow the last element in the vector.
  // It does not point to any element, and thus shall not be dereferenced.
  int lastElement = *(v.end() - 1);
  cout << "Last: " << lastElement << "\n";

  // do not go out of bounds by iterating past the end() iterator
  // the behavior is undefined
  // BAD: v.end() + 1, v.begin() + 10
}

在現代C++中,叠代器是叠代元素集合(向量,列表,映射)的首選方式。另外,auto關鍵字可以避免輸入word類型,但可能會導致代碼性能降低。

Lambda表達式

使用叠代器,我們可以開始研究現代C++的函數式編程概念。標準庫中的許多函數采用由兩個叠代器(開始和結束)和匿名函數(lambda函數)表示的一系列元素作為參數。然後將此匿名函數應用於範圍內的每個元素。它們被稱為匿名函數,因為它們不是綁定到變量,而是它們是短邏輯塊,作為內聯參數傳遞給更高階函數。通常,它們對於傳遞給它們的函數是唯一的,因此不需要具有名稱(匿名)的整個開銷。

有了它,我們可以實現類似於排序,映射,過濾等的構造,這些構造在JavaScript等語言中很容易實現:

[1,2,3,4].map(x => x*x).filter(x => x % 2 === 1).sort((a,b) => b - a)

C++中的代碼並不簡潔,但結構相同。來自std庫的許多函數式編程助手以半開間隔運行,這意味著包括較低範圍,排除較高範圍。

// @url: https://repl.it/@MrToph/CPPBasics-Lambdas
#include <iostream>
#include <vector>
// for sort, map, etc.
#include <algorithm>

using namespace std;

int main()
{
  vector<int> v{2, 1, 4, 3, 6, 5};
  // first two arguments are the range
  // v.begin() is included up until v.end() (excluded)
  // sorts ascending
  sort(v.begin(), v.end());

  // in C++, functions like sort mutate the container (in contrast to immutability and returning new arrays in other languages)
  for (auto i = v.begin(); i != v.end(); i++)
  {
    cout << *i << "\n";
  }

  // sort it again in descending order
  // third argument is a lambda function which is used as the comparison for the sort
  sort(v.begin(), v.end(), [](int a, int b) { return a > b; });

  // functional for_each, can also use auto for type
  for_each(v.begin(), v.end(), [](int a) { cout << a << "\n"; });

  vector<string> names{"Alice", "Bob", "Eve"};
  vector<string> greetings(names.size());

  // transform is like a map in JavaScript
  // it applies a function to each element of a container
  // and writes the result to (possibly the same) container
  // first two arguments are range to iterate over
  // third argument is the beginning of where to write to
  transform(names.begin(), names.end(), greetings.begin(), [](const string &name) {
    return "Hello " + name + "\n";
  });
  // filter greetings by length of greeting
  auto new_end = std::remove_if(greetings.begin(), greetings.end(), [](const string &g) {
    return g.size() > 10;
  });
  // iterate up to the new filtered length
  for_each(greetings.begin(), new_end, [](const string &g) { cout << g; });
  // alternatively, really erase the filtered out elements from vector
  // so greetings.end() is the same as new_end
  // greetings.erase(new_end, greetings.end());

  // let‘s find Bob
  string search_name = "Bob";
  // we can use the search_name variable defined outside of the lambda scope
  // notice the [&] instead of [] which means that we want to do "variable capturing"
  // i.e. make all local variables available to use in the lambda function
  auto bob = find_if(names.begin(), names.end(), [&](const string &name) {
    return name == search_name;
  });
  // find_if returns an iterator referncing the found object or the past-the-end iterator if nothing was found
  if (bob != names.end())
    cout << "Found name " << *bob << "\n";
}

匿名函數的語法是在C++中習慣的東西。它們由括號指定,後跟參數列表,如[](int a,int b) - &gt; bool {return a&gt; b; }。請註意,- &gt; bool指定一個布爾返回值。通常,您可以避免表達返回類型,因為它可以從函數體中的返回類型推斷出來。

如果要使用lambda函數之外的作用域中定義的變量,則需要進行變量捕獲。還有可能通過引用或值將參數傳遞給您的函數。

  • 要通過引用傳遞,您需要使用字符啟動lambda(就像在函數中使用引用時一樣):[&]
  • 要傳遞值,請使用=字符:[=]

還可以通過值和參考來混合和匹配捕獲。

例如,[=,&foo]將為除foo之外的所有變量創建副本,這些變量通過引用捕獲。

它有助於理解使用lambdas時幕後發生的事情:

事實證明,lambdas的實現方式是創建一個小類;這個類重載了operator(),因此它就像一個函數一樣。lambda函數是這個類的一個實例;構造類時,周圍環境中的任何變量都將傳遞給lambda函數類的構造函數並保存為成員變量。事實上,這有點像已經可能的仿函數的想法。C++ 11的好處是,這樣做變得非常簡單——所以你可以一直使用它,而不是僅僅在非常罕見的情況下編寫一個全新的類是有意義的。

Lambda函數在EOS智能合約中大量使用,因為它們提供了一種非常方便的方法來修改少量代碼中的數據。標準庫中有更多函數,它們與我們在sorttransformremove_iffind_if中看到的函數類似。它們都通過&lt;algorithm&gt;標頭導出。

======================================================================

分享一些比特幣、以太坊、EOS等區塊鏈相關的交互式在線編程實戰教程:

  • EOS入門教程,本課程幫助你快速入門EOS區塊鏈去中心化應用的開發,內容涵蓋EOS工具鏈、賬戶與錢包、發行代幣、智能合約開發與部署、使用代碼與智能合約交互等核心知識點,最後綜合運用各知識點完成一個便簽DApp的開發。
  • 深入淺出玩轉EOS錢包開發,本課程以手機EOS錢包的完整開發過程為主線,深入學習EOS區塊鏈應用開發,課程內容即涵蓋賬戶、計算資源、智能合約、動作與交易等EOS區塊鏈的核心概念,同時也講解如何使用eosjs和eosjs-ecc開發包訪問EOS區塊鏈,以及如何在React前端應用中集成對EOS區塊鏈的支持。課程內容深入淺出,非常適合前端工程師深入學習EOS區塊鏈應用開發。
  • java比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Java代碼中集成比特幣支持功能,例如創建地址、管理錢包、構造裸交易等,是Java工程師不可多得的比特幣開發學習課程。
  • php比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Php代碼中集成比特幣支持功能,例如創建地址、管理錢包、構造裸交易等,是Php工程師不可多得的比特幣開發學習課程。
  • c#比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在C#代碼中集成比特幣支持功能,例如創建地址、管理錢包、構造裸交易等,是C#工程師不可多得的比特幣開發學習課程。
  • java以太坊開發教程,主要是針對java和android程序員進行區塊鏈以太坊開發的web3j詳解。
  • python以太坊,主要是針對python工程師使用web3.py進行區塊鏈以太坊開發的詳解。
  • php以太坊,主要是介紹使用php進行智能合約開發交互,進行賬號創建、交易、轉賬、代幣開發以及過濾器和交易等內容。
  • 以太坊入門教程,主要介紹智能合約與dapp應用開發,適合入門。
  • 以太坊開發進階教程,主要是介紹使用node.js、mongodb、區塊鏈、ipfs實現去中心化電商DApp實戰,適合進階。
  • ERC721以太坊通證實戰,課程以一個數字藝術品創作與分享DApp的實戰開發為主線,深入講解以太坊非同質化通證的概念、標準與開發方案。內容包含ERC-721標準的自主實現,講解OpenZeppelin合約代碼庫二次開發,實戰項目采用Truffle,IPFS,實現了通證以及去中心化的通證交易所。
  • C#以太坊,主要講解如何使用C#開發基於.Net的以太坊應用,包括賬戶管理、狀態與交易、智能合約開發與交互、過濾器和交易等。
  • Hyperledger Fabric 區塊鏈開發詳解,本課程面向初學者,內容即包含Hyperledger Fabric的×××書與MSP服務、權限策略、通道配置與啟動、鏈碼通信接口等核心概念,也包含Fabric網絡設計、nodejs鏈碼與應用開發的操作實踐,是Nodejs工程師學習Fabric區塊鏈開發的最佳選擇。
  • Hyperledger Fabric java 區塊鏈開發詳解,課程面向初學者,內容即包含Hyperledger Fabric的×××書與MSP服務、權限策略、頻道配置與啟動、鏈碼通信接口等核心概念,也包含Fabric網絡設計、java鏈碼與應用開發的操作實踐,是java工程師學習Fabric區塊鏈開發的最佳選擇。
  • tendermint區塊鏈開發詳解,本課程適合希望使用tendermint進行區塊鏈開發的工程師,課程內容即包括tendermint應用開發模型中的核心概念,例如ABCI接口、默克爾樹、多版本狀態庫等,也包括代幣發行等豐富的實操代碼,是go語言工程師快速入門區塊鏈開發的最佳選擇。

匯智網原創翻譯,轉載請標明出處。這裏是C++開發EOS基礎指南:叠代器和Lambda表達式

C++開發EOS基礎指南:叠代器和Lambda表達式