声明式编程和命令式编程有什么区别?
我一直在寻找网络寻找一个声明和命令式编程的定义,这将为我提供一些启示。 然而,我发现的一些资源所使用的语言令人望而生畏,例如维基百科。 有没有人有一个真实世界的例子,他们可以告诉我可能会给这个主题带来一些观点......也许在C#中。
声明式与命令式编程的一个很好的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);
}
在这里,我们说:
另一方面,使用声明式编程,您可以编写描述您想要的代码,但不一定知道如何获取它(声明您期望的结果,但不是一步一步的):
var results = collection.Where( num => num % 2 != 0);
在这里,我们说“给我们所有的地方很奇怪”,而不是“逐步收集这个项目,如果它很奇怪,请将它添加到结果集合中。”
在很多情况下,代码也将是两种设计的混合体,所以它并不总是黑白的。
声明式编程就是当你说出你想要的东西时,而命令式语言就是当你说出如何得到你想要的东西时。
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个内核进行快速并行搜索的最佳时机。 作为一名程序员,您不关心任何这些情况,您也不必编写代码来处理任何特殊情况。
说明性与必要性
编程范例是计算机编程的基本风格。 有四种主要范式:命令式,声明式,功能性(被认为是声明范式的一个子集)和面向对象。
声明式编程:是一种编程范式,它表达计算的逻辑(做什么)而不描述其控制流程(怎么做)。 一些众所周知的声明性域特定语言(DSL)示例包括CSS,正则表达式和SQL子集(例如,SELECT查询)。许多标记语言(如HTML,MXML,XAML,XSLT等)通常都是声明式的。 声明性编程试图模糊作为一组指令的程序和作为关于期望的答案的断言的程序之间的区别。
命令式编程:是一种编程范式,它根据改变程序状态的语句来描述计算。 声明性程序可以被视为编程命令或数学断言。
函数式编程:是一种将计算看作是数学函数的评估并避免状态和可变数据的编程范例。 它强调功能的应用,与强调状态变化的命令式编程风格形成鲜明对比。 在一个纯粹的函数式语言中,比如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将提供所要求的结果。
链接地址: http://www.djcxy.com/p/525.html上一篇: What is the difference between declarative and imperative programming