第一章 Introduction to functional programming-函數式編程介紹

第一章 函數式編程介紹

函數式編程是一種編程範式。在其中,函數是一等公民,函數能夠付給其餘變量,也能夠做爲另外一個函數的參數或返回值。函數式編程要求,只使用表達式,不使用語句。c++

函數式編程是聲明式的編程,它與命令式編程不一樣。命令意味着要命令計算機作某事,明確它須要執行的每一步,以計算結果。聲明意味着你說明該作什麼,而後編程語言的任務是找出如何作,一般它定義是什麼,而不是一步一步告訴計算機去執行。算法

理解命令式和聲明式編程的例子

想象一下,你編寫一個函數,它接收文件列表並計算每一個文件中的行數。
命令式的作法可能會是這樣:編程

  • 打開每個文件
  • 定義一個count變量去存儲行數
  • 每次一個字符一個字符的讀文件,當遇到換行符時,count++
  • 到了文件末尾,存儲count的值

下面是代碼:編程語言

auto count_lines_in_file(const std::vector<std::string>& files) -> std::vector<int>
{
    std::vector<int> result;
    int c = 0;

    for (const auto& file : files)
    {
        int count_lines = 0;
        std::ifstream in(file);
        while (c = in.get())
        {
            if (c == '\n')
                count_lines++;
        }
        result.push_back(count_lines);
    }
    return result;
}

但上面的代碼易出錯,好比未初始化的變量、if、while的條件等等。
下面作法用到了std::count算法和輸入流迭代器簡化了代碼:函數式編程

int count_lines(const std::string& file)
{
    std::ifstream in(file);
    // 像對容器同樣,也能夠對流迭代器使用stl算法
    return std::count(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), '\n');
}

auto count_lines_in_file(std::vector<std::string>& files) -> std::vector<int>
{
    std::vector<int> result;

    for (auto& file : files)
    {
        result.push_back(count_lines(file));
    }
}

在上面這個解決方案中,你不用關心count_lines是如何實現的,count_lines只是指出了計算文件的行數。這就是函數式編程的意圖。函數

讓咱們再次簡化代碼,接近函數式編程,此次使用了std::transform:code

auto coutn_lines_in_file3(std::vector<std::string>& files)
{
    std::vector<int> result;
    std::transform(files.begin(), files.end(), result.begin(), count_lines);
    return result;
}

到了c++20,能夠使用範圍庫再次簡化:orm

auto count_lines_in_file4(std::vector<std::string>& files)
{
    // 使用管道操做符(c++20)
    return files | std::transform(count_lines);
}
相關文章
相關標籤/搜索