第一章 Introduction to functional programming-函数式编程介绍

第一章 函数式编程介绍

函数式编程是一种编程范式。在其中,函数是一等公民,函数可以付给其他变量,也可以作为另一个函数的参数或返回值。函数式编程要求,只使用表达式,不使用语句。

函数式编程是声明式的编程,它与命令式编程不同。命令意味着要命令计算机做某事,明确它需要执行的每一步,以计算结果。声明意味着你说明该做什么,然后编程语言的任务是找出如何做,通常它定义是什么,而不是一步一步告诉计算机去执行。

理解命令式和声明式编程的例子

想象一下,你编写一个函数,它接收文件列表并计算每个文件中的行数。
命令式的做法可能会是这样:

  • 打开每一个文件
  • 定义一个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:


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,可以使用范围库再次简化:


auto count_lines_in_file4(std::vector<std::string>& files)
{
    // 使用管道操作符(c++20)
    return files | std::transform(count_lines);
}

猜你喜欢

转载自www.cnblogs.com/vlyf/p/12624017.html