虽然文章标题是『语句与表达式』,在这篇文章中,我将陈述一个观点 每个表达式都有一个值。 在此之外,也会继续表述这个『代码之谜』系列的主题——数学与计算机之间被经常忽略的矛盾。
简单的讲
- “表达式”(expression)是一个单纯的运算过程,总是有返回值;
- “语句”(statement)是执行某种操作,没有返回值。
使用表达式也是函数式编程语言所提倡的,而传统命令式编程语言都是语句的堆砌。
表达式和语句如何区分呢? 最简单最直观的鉴别方法就是, 后面有分号的是语句, 这是一个充分条件而不是必要条件。 有分号,就是语句;没有分号,就不一定了,也可能是语句,也可能是表达式。
在动态语言——比如javascript——中是通过上下文来区分这两者的。
假如如果 function foo(){}
在一个赋值表达式的一部分,则认为它是一个表达式。 表达式的一部分,也是表达式。 而如果 function foo(){}
被包含在一个函数体内,或者位于程序中,则将它作为一个语句。
function foo(){}; // 声明,因为它是程序的一部分 var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分 new function bar(){}; // 表达式,因为它是New表达式的一部分 (function(){ function bar(){}; // 声明,因为它是函数体的一部分 })();
还有一种不那么显而易见的表达式,就是被包含在一对圆括号中—— (function foo(){})
。 将这种形式看成表达式同样是因为上下文的关系: (和)构成一个分组操作符,而 分组操作符只能包含表达式:
(function foo(){}); // 函数表达式:注意它被包含在分组操作符中 (var x = 5); // error! 分组操作符只能包含表达式,不能包含语句(这里的var就是语句)
今天突然有人问我:
alert(eval(data));
为什么会报错呢?data 是一个对象,按理说应该会弹出 ObjectObject 啊。 这是因为,当我们写
{"username" : "justjavac"}
时,它并不是一个对象。 因为我们知道有一种表示数据的方法叫做 json(javascript对象表示法), 所以想当然的认为这应该是一个对象。 其实,在大部分编程语言中,大括号({})表示的不是对象,而是代码块,这段代码其实等价于
{
"username" : "justjavac"
}
很显然,"username" : "justjavac"
并不是合法的语句。 然而解决方法也很简单,就是添加括号——分组操作符
({"username" : "justjavac"})
这样就构成了一个合法的表达式,当我们进行 json 对象解析的时候可以写如下代码:
eval('(' + json + ')')
在表达式中,只能存在表达式,不能存在语句。
例如表达式
(var a = 4) + 4;
这段代码将产生一个错误,因为 var a = 4
是一个语句, 而不是表达式—— 对表达式求值必须返回值,但对语句求值则未必有返回值。
类似的
if (var a = 0) {}
也产生错误,因为 var a = 0' 是一条语句,而 **语句没有返回值**。if 语句的语法结构为
if (expression) {
statement;
statement;
……
}
因此
if (var a = 0) {}
是错误的,但是
if (true) {
var a = 0;
}
则是正确的。
最后重申一下,每个表达式都有一个值。 理解了这个,就可以很容易的理解 FP(函数式编程)的一些核心思想了。
相关推荐
代码之谜(二)讨论了语句与表达式的区别和联系。该篇博客旨在让读者更好地理解代码中的语句和表达式。 5. 代码之谜(三)- 运算符 代码之谜(三)讨论了运算符的概念和应用。该篇博客旨在让读者更好地理解代码中...
二、Kotlin与Android开发 1. Android Studio集成:Android Studio是Google官方推荐的Android开发环境,集成了Kotlin插件,提供了丰富的代码提示和自动完成功能。 2. Anko库:Anko是JetBrains开发的一个库,简化了...
##### 第8课:密码锁之谜——if语句 - **读故事** - 通过故事情境介绍条件语句的概念。 - **2. 问题思考** - 思考如何使用条件语句实现不同的行为。 - **3. 算法分析** - 分析if语句的基本结构和使用场景。 - **...
- **嵌入式SQL语句**:开发者通常需要在代码中直接写SQL语句,这不仅难以阅读和维护,而且容易出错。 - **数据类型不匹配**:编程语言的数据类型和SQL数据库的数据类型不统一,增加了转换的复杂性。 - **缺乏统一...
《JavaScript解码2020年度“代码之谜”》 在编程的世界里,每年的 Advent of Code(AOC)活动都备受关注。2020年的AOC,主题为"advent-of-code-2020",吸引了无数开发者用代码解决一系列精心设计的谜题。这次活动...
- 使用欧拉函数 \(\varphi(30000)\) 来计算小于等于 30000 与之互质的数的数量,公式为 \(\varphi(n) = n \left(1 - \frac{1}{p_1}\right)\left(1 - \frac{1}{p_2}\right)...\left(1 - \frac{1}{p_k}\right)\),...
在编程领域,算法和数据结构是核心技术之一,对于任何编程语言来说都至关重要,Go语言(Golang)也不例外。Go语言以其简洁的语法、高效的性能以及内置的并发支持,成为了很多开发者首选的系统级编程语言。本资料包...
10. **游戏逻辑**:游戏的每个关卡都有独特的逻辑,玩家需通过编写代码来解谜。这可能涉及到算法设计、问题分解、逻辑推理等多个方面。 通过参与《GuessTheCode》,玩家不仅能够巩固已有的C#编程技能,还能锻炼解决...
10. **Lambda表达式和函数式编程**:自Java 8引入以来,lambda表达式和函数式接口已经成为编写简洁代码的重要工具。谜题可能要求使用这些特性实现函数式风格的编程。 解决这些谜题不仅能加深对Java语言的理解,还能...
《代码来临2020:Java解题之旅》 “Advent-of-Code”(代码来临)是一项由美国程序员Eric Wastl每年圣诞节期间推出的在线编程挑战活动,旨在通过一系列有趣的逻辑问题激发开发者对编程的兴趣和挑战精神。2020年的...
2. 函数与方法:C#支持函数和方法,它们是一组可执行的语句集合。函数可以作为独立单元使用,而方法是类的一部分。 3. 枚举(Enum):枚举是用于定义一组相关的命名常量,便于代码的可读性和维护性。 4. 泛型:...
- **二分查找**:在有序数组中查找特定元素,通常与排序算法结合使用。 - **动态规划**:解决最优化问题,如斐波那契数列、背包问题等。 - **贪心算法**:每次做出局部最优决策,解决问题,例如求最小生成树、...
- **变量与数据类型**:在Python中,有基本的数据类型如整型(int)、浮点型(float)、字符串(str)、布尔型(bool)等。在解题过程中,我们需要熟练掌握这些数据类型的转换和操作。 - **列表(List)**:列表是Python中最...
“文明盛世”可能是一个游戏主题或者背景设定,暗示了这个谜题可能与某种文化、历史或者虚构的世界观有关。游戏可能涉及解谜、策略或者角色扮演元素,而饮料作为谜题的一部分,可能需要玩家通过推理和逻辑分析来解开...
《Java之谜:挑战思维的游戏与实用工具》 在编程世界中,Java是一种广泛应用的编程语言,以其跨平台性、稳健性和丰富的库而备受青睐。"java-puzzlers"项目正是针对Java爱好者和开发者设计的一系列游戏和实用程序,...
4. **函数和模块化**:为了保持代码组织有序,开发者可能会使用函数封装特定功能,并利用IIFE(立即调用的函数表达式)或ES6的`export`和`import`实现模块化。 5. **条件语句和循环**:游戏逻辑通常包含许多条件...
8. **调试和测试**:使用`print()`语句、`pdb`调试器或单元测试框架(如`unittest`)来确保代码按预期工作。 在解决www.pythonchallenge.com的第三题时,上述技能将是你的重要工具。通过仔细阅读题目描述,理解隐藏...
玩家与游戏环境的互动,如战斗、对话和解谜,都可以通过方法调用来处理。 此外,考虑到游戏的文本驱动性质,开发者可能会使用Java的字符串操作来处理和展示游戏文本。例如,使用StringBuilder或StringBuffer类来...