声明式编程和命令式编程有什么区别?

2024-04-20 15:44:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在网上寻找一个声明式和命令式编程的定义,这会给我一些启发。然而,在我发现的一些资源中使用的语言是令人生畏的——例如在Wikipedia。 有没有人能给我举一个现实世界的例子,让我对这个话题有一些看法(也许用C#)呢?


Tags: 语言声明定义编程世界资源wikipedia例子
3条回答

陈述句与祈使句

Aprogramming paradigm是计算机编程的基本风格。 有四种主要的范例:命令式、声明式、功能性(被认为是声明式范例的一个子集)和面向对象。

Declarative programming:是一种编程范例,它表示计算的逻辑(做什么),而不描述其控制流(如何做)。 一些著名的声明性领域特定语言(dsl)示例包括CSS、正则表达式和SQL的子集(例如SELECT查询) 许多标记语言,如HTML、MXML、XAML、XSLT。。。通常是陈述性的。 声明式编程试图模糊程序作为指令集和程序作为关于所需答案的断言之间的区别。

Imperative programming:是一种编程范例,它用改变程序状态的语句来描述计算。声明式程序可以双重地看作是编程命令或数学断言。

函数式编程:是一种将计算视为数学函数的求值并避免状态和可变数据的编程范式。它强调函数的应用,而不是强调状态变化的命令式编程风格。 在纯函数语言(如Haskell)中,所有函数都没有副作用,状态更改仅表示为转换状态的函数。

下面是MSDN中的命令式编程示例,它遍历数字1到10,并查找偶数。

var numbersOneThroughTen = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//With imperative programming, we'd step through this, and decide what we want:
var evenNumbers = new List<int>();
foreach (var number in numbersOneThroughTen)
{    if (number % 2 == 0)
    {
        evenNumbers.Add(number);
    }
}
//The following code uses declarative programming to accomplish the same thing.
// Here, we're saying "Give us everything where it's odd"
var evenNumbers = numbersOneThroughTen.Select(number => number % 2 == 0);

两个例子产生的结果是一样的,一个既不比另一个好也不比另一个差。第一个例子需要更多的代码,但是代码是可测试的,命令式方法使您能够完全控制实现细节。在第二个示例中,可以说代码更具可读性;但是,LINQ不能让您控制幕后发生的事情。您必须相信LINQ将提供请求的结果。

声明式编程是当你说你想要什么,命令式语言是当你说如何得到你想要的。

Python中的一个简单示例:

# Declarative
small_nums = [x for x in range(20) if x < 5]

# Imperative
small_nums = []
for i in range(20):
    if i < 5:
        small_nums.append(i)

第一个例子是声明性的,因为我们没有指定构建列表的任何“实现细节”。

一般来说,在C示例中,使用LINQ会产生一种声明式风格,因为您并不是说如何获得想要的东西;您只是说想要什么。关于SQL,你也可以这么说。

声明式编程的一个好处是,它允许编译器做出可能产生比手工生成更好代码的决策。如果您有一个类似于

SELECT score FROM games WHERE id < 100;

SQL“编译器”可以“优化”这个查询,因为它知道id是一个索引字段——或者它可能没有索引,在这种情况下,它无论如何都必须遍历整个数据集。或者,SQL引擎知道现在是利用所有8个核心进行快速并行搜索的最佳时机。作为一个程序员,您不关心任何这些条件,也不必编写代码来处理任何特殊情况。

声明式编程和命令式编程的一个很好的C#示例是LINQ。

使用命令式编程,您可以一步一步地告诉编译器您想要发生什么。

例如,让我们从这个集合开始,并选择奇数:

List<int> collection = new List<int> { 1, 2, 3, 4, 5 };

对于命令式编程,我们将逐步完成这一步,并决定我们想要什么:

List<int> results = new List<int>();
foreach(var num in collection)
{
    if (num % 2 != 0)
          results.Add(num);
}

在这里,我们要说:

  1. 创建结果集合
  2. 遍历集合中的每个数字
  3. 检查号码,如果是奇数,把它加到结果中

另一方面,使用声明式编程,您可以编写描述所需内容的代码,但不一定要说明如何获取这些内容(声明您所需的结果,但不必逐级声明):

var results = collection.Where( num => num % 2 != 0);

在这里,我们说的是“给我们所有奇怪的东西”,而不是“一步一步地收集”。选中此项,如果它很奇怪,请将其添加到结果集合中。”

在许多情况下,代码也将是两种设计的混合体,因此并不总是黑白的。

相关问题 更多 >