缩进式与大括号式:同一段 Verse 的两种排版
主课把代码块讲成了「冒号开块、缩进定归属」,那是默认写法。但 Verse 还有第二套排版:大括号加分号。两种写法编译出来一模一样,选哪种是风格问题——而风格问题在团队里会变成真问题。
一、同一段代码,两种排版
Verse 的每一个代码块都可以写成两种形态:冒号 + 换行 + 缩进,或者大括号 { }。块里的多个表达式,可以用换行分隔,也可以用分号 ; 分隔。先看默认的缩进式:
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/Diagnostics }
turret_device := class(creative_device):
var Ammo:int = 3
Fire():void =
if (Ammo > 0):
set Ammo -= 1
Print("开火,剩 {Ammo}")
else:
Print("空仓")
同样一段逻辑,把两个分支的身体换成大括号,并用分号把同一行里的两件事分开:
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/Diagnostics }
turret_device := class(creative_device):
var Ammo:int = 3
Fire():void =
if (Ammo > 0) { set Ammo -= 1; Print("开火,剩 {Ammo}") }
else { Print("空仓") }
13 行变 10 行,行为完全一致。注意两处细节:第一,if 后面用了大括号就不写冒号了——冒号和大括号是同一个位置上的两选一;第二,类的定义体两边都还是冒号加缩进,官方文档里的类一律这么写,大括号的用武之地在函数体以内。
那能不能一路括到底?能,但你不会想看:
Fire():void = { if (Ammo > 0) { set Ammo -= 1; Print("开火,剩 {Ammo}") } else { Print("空仓") } }
这一行是合法的,也是不可读的。排版 C 存在的意义,只是提醒你:语言允许的写法和你该写的写法是两回事。
二、必须学会的一个:单行 if (X) { }
如果这一页你只带走一件事,就带走这个。翻开任何一份 Epic 官方示例代码,你都会撞见这样的行:
# 「做了就好,做不成也不管」:大括号故意空着
if (set PlayerScores[Player] = 10) {}
# 「取得到就用一下」:判断和取值一步完成
if (First := Numbers[0]) { Print("第一个是 {First}") }
拆开看:Verse 的 if 必须带一个块,而这两种场景里,「走通之后」其实没什么可做的——第一行是往表里写值,写进去就完事;第二行是取到值就打印一句。用缩进式写第一行,你得占三行(if 一行,再缩进一行放个什么东西);用大括号,一对空的 {} 就把「成功了也不用做别的」这个意思说完了。
这个惯用法为什么重要:它是 Verse 处理「可能走不通的操作」的标准姿势(往 map 里写、按下标取数组、把 option 打开,都是这类操作)。读不懂 if (…) {},你就读不懂 Epic 的示例代码——而在 UEFN 里学任何 API,示例代码是主要教材。
顺带一提,那个空的 {} 不是什么特殊语法糖,它就是一个空的代码块,不产出任何有用的值。它和蓝图里「Branch 的 True 引脚拉出来一根线,但线上什么节点都没接」是同一件事。
三、什么时候用哪种
| 场景 | 建议排版 | 理由 |
|---|---|---|
| 类体、函数体 | 缩进式 | 官方文档一律这么写;类体在文档里也只有这一种形态 |
| 多行的分支 / 循环体 | 缩进式 | 竖着读,层级一眼可数(主课第三节的那个「阶梯」) |
「做不成就算了」的 if (…) {} |
大括号式 | 缩进式要占三行,大括号一行说完 |
「取到就用一下」的 if (X := …) { … } |
大括号式 | 判断和使用挨在一起,读的人不用来回跳行 |
| 一行里想塞三件以上的事 | 两种都别用 | 拆成多行,或者抽一个函数出来 |
另外三条硬规矩,踩了会浪费你半小时:
- 同一个块只能选一种。不能开头写冒号、结尾配大括号。选定了就一路到底。
- 缩进只用空格,4 个一层,别用 Tab。缩进式最现实的风险不是写错,是粘错——从网页或聊天窗口复制一段代码,缩进被吃掉或者混进 Tab,编译器会甩给你一堆莫名其妙的报错。粘完先看一眼缩进对不对齐。
- 分号只用来分隔同一行里的多个表达式。Verse 不需要行尾分号,顺手加一个只会让人以为你在写 C#。
四、团队里怎么统一
如果你的组正从蓝图迁过来,建议在第一天就定死两条:
- 默认缩进式。理由不是它更好看,而是官方文档、Epic 示例、绝大多数社区代码都是缩进式——新人抄得动、搜得到、问 AI 也答得对。风格跟着最大的那份语料走,永远是省力的选择。
- 给大括号式划一个明确的口子:只用于单行,且这一行不超过两件事。把它限定成「惯用法」而不是「另一种风格」,就不会出现同一个文件里两种排版打架的局面。
为什么值得为排版较这个真?因为这正是你换到文本代码之后拿到的那份红利。蓝图存成二进制资产,两个人改同一张图就得靠人肉沟通,diff 基本没法看;.verse 是纯文本,能进 Git、能做 code review、能让 AI 读了改。但这份红利有前提:diff 里只出现真正的改动。排版风格来回横跳的仓库,每次 diff 都混着一堆纯格式噪音,review 的人看两次就放弃了,红利立刻归零。
说白了,排版规矩不是审美洁癖,是为了让「这次到底改了什么」这个问题永远有一个五秒钟就能回答的版本。这件事在蓝图时代你想做也做不到,现在能做了,别自己浪费掉。
五、小测验
官方代码里常见的 if (set Scores[Player] = 10) {},末尾那对空大括号是干什么的?
来源
本文整理自 Epic 官方文档与官方语言手册:Verse Language Quick Reference(官方文档)↗ · block expression(官方文档)↗ · Book of Verse — Control Flow(官方语言手册)↗