学习目标
完成本模块后,你将能够:
- 定义什么是代码(code)。
- 描述在哪里存储和编辑代码。
- 描述创建代码注释(comments)的两种方式。
- 解释代码注释为何重要。
想扩展 Salesforce 知识、学习 Apex 代码?你来对地方了。本模块将一步步带你进入阅读和编写代码的世界。作为管理员,你已经熟悉 Salesforce 的功能和局限,也有使用 Flow Builder 自动化业务流程的经验。本模块先介绍编程概念,再给出可亲自测试的示例。
什么是代码?
代码(code)是人类与计算机交流的语言。我们用代码编写一组精确的指令来执行特定操作。可以把代码想象成一份食谱(recipe)——每种原料和每个步骤都必须精确,菜品才会如你所愿。
正如世界各地的人使用不同语言,计算机也使用不同语言,例如 JavaScript、Java、Ruby、Python 等。虽然编程语言各不相同,但它们都建立在相同的基础结构之上,都能被计算机解读以创建应用程序。随着你对 Apex 编程语言的深入学习,你会逐步理解这些编程结构。
Apex 代码存储在哪里?
代码存储在文件(files)中。这些文件可以存放在本地(你的 PC 或 Mac)、云端(你的 Salesforce org),也可以保存在本地并自动同步到云端。
开发者控制台(Developer Console):开发者控制台是开发者用来创建和编辑代码文件的工具。本模块中,我们用开发者控制台在你的 Salesforce org 中存储和执行代码。
访问开发者控制台:先确保已登录 Trailhead,点击页面右上角的用户头像并选择 Hands-on Orgs,点击用户名启动 org,然后在 Trailhead Playground 中选择 Developer Console。
编写伪代码
作为管理员,参与任何项目最重要的部分就是规划。规划帮助你理解客户需求、整理思路、预判开发中可能遇到的问题。
在项目规划阶段,开发者开始写 Apex 代码之前,会先写伪代码(pseudocode)——用自然语言(而非编程语言)编写的、对程序或功能要做什么的详细可读描述。伪代码让不懂编程的人也能审阅步骤,确认所提代码满足应用需求。
以「为朋友泡一壶茶」为例,伪代码可能是:
Get Utensils and Ingredients
Get Teacup
Get Spoon
Get Tea Kettle
Get Teapot
Get Tea
Get Sugar
Boil water in a Tea Kettle
Fill Kettle with Water
Switch Kettle On
Wait for Kettle to Boil
Make Tea in Teapot
Put Tea in Teapot
Put Boiling Water in Teapot
Wait 2 Minutes
Add Tea and Sugar to Teacup
Pour Tea in Teacup
Put 1 teaspoon of Sugar in Teacup
Stir Tea in Teacup
Serve Tea to a Friend
写伪代码时,要把每一步尽量拆解,以覆盖所有可能的情况。例如「给水壶装水」——如果水壶已经满了怎么办?像开发者一样思考,就需要从不同角度考虑多种可能性。
代码注释
代码中的注释(comments)描述一块代码(一行或多行)的用途,帮助开发者理解要写什么代码、现有代码做什么、以及出错的代码本应做什么。开发者把注释嵌入代码,并用特殊字符括起来,告诉计算机不要读取或运行这些注释。
注释有两种方式:
- 单行注释(Single-line comments):以两个斜杠
//开头,计算机运行时会忽略同一行中//右侧的字符。 - 多行注释(Multiline comments):以
/*开头、*/结尾,可跨多行。
// 这是单行注释,计算机会忽略它。 /* 这是多行注释, 可以跨越多行 */
为什么要写注释?解释代码「为什么」这样做(而非「是什么」),为未来的自己和其他开发者留下说明,在调试时临时禁用代码。保持一致的缩进也是提高可读性的重要实践。好的注释解释「为什么」,代码本身已经展示了「是什么」。
在开发者控制台中练习
本单元动手实践:在开发者控制台中创建变量、使用 System.debug 查看输出,并学习 Apex 语法基础。
变量
把变量(variable)想象成存放数据的容器。你可以给它起个名字来描述里面装了什么,给它贴上一个唯一的标签,把东西放进容器里,等需要时再取出来。变量也类似于临时字段——每个变量都有名字和数据类型。
选择清晰、描述性的变量名能大大减少他人(以及未来的你)理解变量用途的时间。数据类型则定义了变量能存放什么内容。
常见数据类型:
- Integer:没有小数点的正整数或负整数。
- Decimal:带小数点的数。
- String:用单引号括起来的一串字符,可短到一个字母,长到多个句子。
- Boolean:通常为 true 或 false(在 Apex 中 null 也是合法值),常用于复选框。
- ID:任何有效的 18 位 Salesforce 记录 ID。
Apex 是强类型(strongly-typed)语言:每次声明变量时都要设置数据类型、名字,并可选择设置初始值。
Integer i = 2; // Integer 是数据类型,i 是变量名,2 是初始值
初始化变量时,赋的值必须与数据类型匹配;如果声明时不赋值,变量的值为 null。在开发者控制台点击 Debug | Open Execute Anonymous Window,粘贴代码并勾选 Open log 后点击 Execute 即可运行:
Integer numberOfSpoons; System.debug(numberOfSpoons);
执行日志会显示结果,选择底部的 Debug Only 只看 System.debug 输出——包含行号(2)、日志级别(DEBUG)和变量值(null)。
System.debug
写了代码却不工作,又没人可问?System.debug 来救场!开发者用 System.debug 监控变量的变化,以定位代码出错的地方。
下面这段代码声明变量、改值,并两次打印:
Integer numberOfSpoons; System.debug(numberOfSpoons); numberOfSpoons = 1; System.debug(numberOfSpoons);
有趣的是:第 2 行和第 5 行是相同的代码,却在日志中产生不同的值(null 和 1)——因为变量值可以随时改变。
开发者用拼接(concatenation)把字面文本和变量值用 + 号连接起来,让日志更易读:
Integer numberOfSpoons;
System.debug('The variable numberOfSpoons is: ' + numberOfSpoons);
numberOfSpoons = 1;
System.debug('The variable numberOfSpoons is: ' + numberOfSpoons);
现在就能清楚地看到 null 和 1 都是 numberOfSpoons 变量的值了。
语法
文本和标点的组织方式构成了一种编程语言,称为语法(syntax)。Apex 代码的几条语法规则:
- 每条语句以分号结尾——分号结束 Apex 语句,就像句号结束句子。
String whatTimeIsIt;如果忘了分号,会收到友好的错误提示。 - 字符串用单引号把字面文本和代码分开;数字和 Boolean 值不需要引号。
String whatTimeIsIt = 'It is Tea Time!'; Integer sugarCount = 2; Boolean needsSugar = false;
现在你了解了变量、数据类型和语法,也学会了声明变量、赋值、创建调试语句并在日志中查看。做得很好!
使用集合
本单元学习集合(Collections)——一种可同时处理多个值的变量,重点学习最常用的 List。
集合与 List
集合(collection)是一种可以存储多个项目的变量。在我们的茶示例中,糖碗里装了几块方糖——糖碗就是集合,方糖就是集合中存储的项目(item)。
Apex 有三种集合类型(List、Set、Map),本模块重点学习 List。
List 是一组有序的、同类型的项目,就像购物清单:Tea、Sugar、Honey、Milk。每个项目在列表中都有位置。
声明一个 List 需要:保留字 List、<> 内的数据类型(所有项目必须是同一类型)、保留字 new,以及结尾必需的括号:
List<String> groceries = new List<String>();
保留字(reserved words)是有特殊含义、不能用作变量名的词,如 new、string、false、null 等。
声明与初始化 List
声明空 List:
List<String> groceries = new List<String>();
System.debug('Groceries Value: ' + groceries); // 输出空列表 ()
因为还没有添加任何项目,所以列表是空的。
声明指定大小的 List:如果知道列表需要多大,可以在数据类型后用方括号 [] 设置大小:
String[] groceries = new String[4];
项目的顺序位置称为索引(index)。很多编程语言从 0 开始计数(而不是 1),所以 Tea 是索引 0、Sugar 是索引 1、Honey 是索引 2……
初始化 List(两种添加项目的方式):
// 方式一:声明并初始化
List<String> groceries = new List<String>{'Tea'};
// 方式二:先声明空 List,再用 add() 添加
List<String> groceries = new List<String>();
groceries.add('Tea');
初始化时用花括号 { }(而非括号 ( ))添加值。也可以用 add() 方法把项目添加到列表,或用 add(index, item) 插入到指定位置(注意 groceries 和 add 之间的点号,这是 Apex 的点表示法 dot notation):
groceries.add(2, 'Milk'); // 插入到索引 2 的位置
揭开 List 的面纱:不同的添加方式会产生不同结果。试试这段代码:
String[] groceries = new String[4];
System.debug('Groceries: ' + groceries);
groceries.add('Tea');
groceries.add('Sugar');
System.debug('Added 2 items: ' + groceries);
groceries.add(1, 'Honey');
System.debug('Added Honey in index 1: ' + groceries);
System.debug('Item 0: ' + groceries[0]);
不加索引地 add() 会把 Tea 和 Sugar 追加到列表末尾,使大小从 4 增至 6;而 add(1, 'Honey') 明确指定索引 1,但第一个索引仍是 0(当前为 null)。写代码就像做数学题,一个问题有多种解法。
控制数据流
本单元学习表达式(expressions)、条件语句(if/else)和逻辑运算符,让代码根据不同情况做出决策。
表达式与表达式运算符
做决策前常要先做比较:这个比那个大吗?这个等于那个吗?表达式(expression)是求值后得到一个值的代码片段——可能是字面值(如 12)、变量(如 numberOfTeaCups),或数学运算(如 7 x 4)。
表达式运算符(expression operators)比较两个值或判断它们是否相等。比较语句由两个表达式和一个运算符组成,结果是一个 Boolean 值(true 或 false)。
比较运算符包括:<(小于)、<=(小于等于)、==(等于)、!= / <>(不等于)、>(大于)、>=(大于等于)。
为什么「等于」要用两个等号?
Integer i = 2; // 一个 = 是赋值运算符,给变量赋值 10 == 10 // 两个 == 是比较运算符,判断是否相等
一个等号 = 是赋值运算符(assigns values),两个等号 == 是比较运算符(compares two values)。
条件语句
条件语句(conditional statement)设置两个或多个选项。如果你用过 Flow Builder 里的条件,就已经用过条件语句了。例如「如果 State 等于 California,就在列表视图显示记录」——「State equals California」是条件,「显示记录」是条件为真时才执行的动作。
If-Else 语句:第 1 行定义条件(写在括号内),第 2 行是条件为真时运行的代码,第 3 行的 else 引入第二个选项,第 4 行是条件为假时运行的代码。在 Apex 中用花括号 { } 括住条件语句,每个 { 必须与 } 配对。
String waterLevel = 'full';
if (waterLevel == 'empty') {
System.debug('Fill the tea kettle');
waterLevel = 'full';
} else {
System.debug('The tea kettle is full');
}
这里把 waterLevel 硬编码(hard coding)为 full,所以 if 条件为假,会运行 else 分支。
If-Else If 语句:要处理两个以上可能(例如水壶可能「半满」),在最终 else 前再加一个 if 条件:
String waterLevel = 'half';
if (waterLevel == 'empty') {
System.debug('Fill the tea kettle');
waterLevel = 'full';
} else if (waterLevel == 'half') {
System.debug('Fill the tea kettle');
waterLevel = 'full';
} else {
System.debug('The tea kettle is full');
}
把最常见的条件放在最前面,可减少每次执行的代码量。
Switch 语句:是 if-else 语句更高效的替代,指定一组值并测试表达式是否匹配其中某个值(一个 when 后可跟一个或多个值):
String waterLevel = 'empty';
switch on waterLevel {
when 'empty', 'half' {
System.debug('Fill the tea kettle');
}
when 'full' {
System.debug('The tea kettle is full');
}
when else {
System.debug('Error!');
}
}
逻辑运算符
当一个条件可以由多个值满足时,就用逻辑运算符(logical operators)。Apex 的逻辑运算符:
- OR(
||):至少一个值为 true 即满足条件。 - AND(
&&):所有值都为 true 才满足条件。 - NOT(
!):反转布尔值。
以 if-else if 语句为例,第 4-5 行和第 7-8 行完全相同——这叫冗余代码(redundant code)。消除冗余是最佳实践,能让代码更易读、易调试、易维护。用 || 把 empty 和 half 合并成一个条件:
String waterLevel = 'half';
if (waterLevel == 'empty' || waterLevel == 'half') {
System.debug('Fill the tea kettle');
waterLevel = 'full';
} else {
System.debug('The tea kettle is full');
}
使用逻辑运算符(&& 和 ||)是消除冗余、提高可读性的有效方式。编程中往往有多种实现方式(switch 或 if-else 都能得到相同结果),选择时重点考虑对代码可读性的影响——保持代码清晰易懂。
使用循环
本单元学习循环(loops)——重复执行代码块直到满足某个条件,重点学习 while 和 do-while 循环。
While 循环
如果要把茶端给 100 个人,就需要一遍又一遍重复同样的步骤——这就是循环(loop)的用武之地。循环是一段重复执行、直到满足某个条件的代码块。Apex 有 while、do-while 和 for 三种循环,本模块先学前两种。
While 循环先验证条件是否满足:条件为真就执行,为假就停止。
应用到泡茶场景:
Integer totalGuests = 100;
Integer totalAmountSugar = 159;
Integer totalAmountTea = 35;
While (totalGuests > 0) {
System.debug(totalGuests + ' Guests Remaining');
if (totalAmountSugar == 0 || totalAmountTea == 0) {
System.debug('Out of ingredients!');
break;
}
totalAmountSugar--;
totalAmountTea--;
totalGuests--;
}
那个 -- 不是笔误,而是后缀递减运算符(post-decrement operator)——「从这个值减 1」的简写。++ 是后缀递增运算符,加 1。每服务一位客人,糖、茶和客人数都减 1;当糖或茶用完(为 0)或客人为 0 时循环停止。
Do-While 循环
Do-while 循环先执行一次任务,再验证条件:条件为真就再执行一次,为假就停止。它与 while 的区别在于:while 先检查条件(可能执行 0 次),do-while 先执行再检查(至少执行 1 次)。
应用于泡茶场景:
Integer totalGuests = 100;
Integer totalAmountSugar = 159;
Integer totalAmountTea = 35;
do {
totalAmountSugar--;
totalAmountTea--;
totalGuests--;
System.debug(totalGuests + ' Guests Remaining!');
if (totalAmountSugar == 0 || totalAmountTea == 0) {
System.debug('Out of ingredients!');
break;
}
} while (totalGuests > 0);
你已经声明了变量、实例化了值、创建了 List,并用多种方式循环了数据。恭喜!你完成了 Apex 入门,正在通往理解代码的路上。


















