我一直在网上搜索声明式编程和命令式编程的定义,希望能给我一些启发。然而,我发现在一些资源中使用的语言令人生畏——例如在维基百科。 有没有人可以给我举一个现实世界的例子,让我对这个主题有一些了解(也许是c#)?


当前回答

已经添加了很多代码示例,所以我不再添加另一个。 相反,我将尝试用一种我认为比大多数流行的定义更清楚地解释这两种方法之间的区别:

声明性方法侧重于特定算法的目的,这通常隐藏了算法本身。 命令式方法侧重于特定目的的算法,通常隐藏了目的本身。

其他回答

Imperative programming requires developers to define step by step how code should be executed. To give directions in an imperative fashion, you say, “Go to 1st Street, turn left onto Main, drive two blocks, turn right onto Maple, and stop at the third house on the left.” The declarative version might sound something like this: “Drive to Sue’s house.” One says how to do something; the other says what needs to be done. The declarative style has two advantages over the imperative style: It does not force the traveler to memorize a long set of instructions. It allows the traveler to optimize the route when possible.

卡尔弗特,C库尔卡尼,D(2009)。LINQ至关重要。艾迪森·韦斯利48岁

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

一个简单的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说同样的话。

声明式编程的一个好处是,它允许编译器做出可能比手工编写更好的代码的决定。运行SQL示例,如果您有这样的查询

SELECT score FROM games WHERE id < 100;

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

我喜欢剑桥一门课程的解释和他们的例子:

声明性-指定要做什么,而不是如何做 例如:HTML描述的是什么应该出现在网页上,而不是它应该如何在屏幕上绘制 命令式-同时指定“什么”和“如何” int x;-什么(陈述性的) x = x + 1;——如何

命令式编程是显式地告诉计算机做什么,以及如何做,比如指定顺序等

C#:

for (int i = 0; i < 10; i++)
{
    System.Console.WriteLine("Hello World!");
}

说明性是指你告诉计算机做什么,而不是如何做。Datalog / Prolog是在这方面首先想到的语言。基本上所有东西都是声明性的。你不能保证秩序。

c#是一种更命令式的编程语言,但某些c#特性更具有声明性,如Linq

dynamic foo = from c in someCollection
           let x = someValue * 2
           where c.SomeProperty < x
           select new {c.SomeProperty, c.OtherProperty};

同样的东西也可以写成命令式:

dynamic foo = SomeCollection.Where
     (
          c => c.SomeProperty < (SomeValue * 2)
     )
     .Select
     (
          c => new {c.SomeProperty, c.OtherProperty}
     )

(例子来自维基百科Linq)

再举一个手机应用开发的例子。在iOS和Android中,我们有界面构建器,在那里我们可以定义应用程序的UI。

使用这些生成器绘制的UI本质上是声明性的,我们可以在其中拖放组件。实际的绘图发生在框架和系统下面,由框架和系统执行。

但我们也可以在代码中画出整个组件,这在本质上是必要的。

此外,一些新语言,如Angular JS,专注于以声明方式设计ui,我们可能会看到许多其他语言提供同样的支持。就像Java在Java swing或Java FX中没有任何好的声明性方法来绘制本地桌面应用程序,但在不久的将来,他们可能会这样做。