aboutsummaryrefslogtreecommitdiff
path: root/doc/docs
diff options
context:
space:
mode:
Diffstat (limited to 'doc/docs')
-rwxr-xr-xdoc/docs/zh/doc/README.md183
1 files changed, 92 insertions, 91 deletions
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md
index a799a5b..845198c 100755
--- a/doc/docs/zh/doc/README.md
+++ b/doc/docs/zh/doc/README.md
@@ -9,7 +9,7 @@ title: 参考手册
9 9
10## 介绍 10## 介绍
11 11
12月之脚本(YueScript)是一种动态语言,可以编译为Lua。它是[MoonScript](https://github.com/leafo/moonscript)的方言。用月之脚本编写的代码既有表现力又非常简洁。它适合编写一些更易于维护的代码,并在嵌入 Lua 的环境中运行,如游戏或网站服务器。 12月之脚本(YueScript)是一种动态语言,可以编译为 Lua。它是 [MoonScript](https://github.com/leafo/moonscript) 的方言。用月之脚本编写的代码既有表现力又非常简洁。它适合编写一些更易于维护的代码,并在嵌入 Lua 的环境中运行,如游戏或网站服务器。
13 13
14Yue(月)是中文中“月亮”的名称。 14Yue(月)是中文中“月亮”的名称。
15 15
@@ -109,7 +109,7 @@ export 🌛 = "月之脚本"
109 109
110* **Lua 模块** 110* **Lua 模块**
111 111
112 安装 [luarocks](https://luarocks.org),一个Lua模块的包管理器。然后作为Lua模块和可执行文件安装它: 112 安装 [luarocks](https://luarocks.org),一个 Lua 模块的包管理器。然后作为 Lua 模块和可执行文件安装它:
113 113
114``` 114```
115> luarocks install yuescript 115> luarocks install yuescript
@@ -150,14 +150,14 @@ export 🌛 = "月之脚本"
150 150
151### Lua 模块 151### Lua 模块
152 152
153在Lua中使用月之脚本模块: 153 Lua 中使用月之脚本模块:
154 154
155* **用法 1** 155* **用法 1**
156在Lua中引入 "你的脚本入口文件.yue"。 156 Lua 中引入 "你的脚本入口文件.yue"。
157```Lua 157```Lua
158require("yue")("你的脚本入口文件") 158require("yue")("你的脚本入口文件")
159``` 159```
160当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import**进行脚本引用即可。错误消息中的代码行号也会被正确处理。 160当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import** 进行脚本引用即可。错误消息中的代码行号也会被正确处理。
161 161
162* **用法 2** 162* **用法 2**
163手动引入月之脚本模块并重写错误消息来帮助调试。 163手动引入月之脚本模块并重写错误消息来帮助调试。
@@ -172,7 +172,7 @@ end)
172``` 172```
173 173
174* **用法 3** 174* **用法 3**
175在Lua中使用月之脚本编译器功能。 175 Lua 中使用月之脚本编译器功能。
176```lua 176```lua
177local yue = require("yue") 177local yue = require("yue")
178local codes, err, globals = yue.to_lua([[ 178local codes, err, globals = yue.to_lua([[
@@ -492,7 +492,7 @@ $printNumAndStr 123, "hello"
492 492
493## 操作符 493## 操作符
494 494
495Lua的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 495Lua 的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。
496 496
497```moonscript 497```moonscript
498tb\func! if tb ~= nil 498tb\func! if tb ~= nil
@@ -577,11 +577,11 @@ print v(1) > v(2) <= v(3)
577</pre> 577</pre>
578</YueDisplay> 578</YueDisplay>
579 579
580在上面的例子里,中间的表达式`v(2)`仅被计算一次,如果把表达式写成`v(1) < v(2) and v(2) <= v(3)`的方式,中间的`v(2)`才会被计算两次。在链式比较中,求值的顺序往往是未定义的。所以强烈建议不要在链式比较中使用具有副作用(比如做打印操作)的表达式。如果需要使用有副作用的函数,应明确使用短路 `and` 运算符来做连接。 580在上面的例子里,中间的表达式 `v(2)` 仅被计算一次,如果把表达式写成 `v(1) < v(2) and v(2) <= v(3)` 的方式,中间的 `v(2)` 才会被计算两次。在链式比较中,求值的顺序往往是未定义的。所以强烈建议不要在链式比较中使用具有副作用(比如做打印操作)的表达式。如果需要使用有副作用的函数,应明确使用短路 `and` 运算符来做连接。
581 581
582### 表追加 582### 表追加
583 583
584**[] =** 操作符用于向Lua表的最后插入值。 584**[] =** 操作符用于向 Lua 表的最后插入值。
585 585
586```moonscript 586```moonscript
587tab = [] 587tab = []
@@ -613,7 +613,7 @@ tbA[] = ...tbB
613 613
614### 表扩展 614### 表扩展
615 615
616你可以使用前置 `...` 操作符在Lua表中插入数组表或哈希表。 616你可以使用前置 `...` 操作符在 Lua 表中插入数组表或哈希表。
617 617
618```moonscript 618```moonscript
619parts = 619parts =
@@ -672,7 +672,7 @@ data.items[#] = 1
672**<>** 操作符可提供元表操作的快捷方式。 672**<>** 操作符可提供元表操作的快捷方式。
673 673
674* **元表创建** 674* **元表创建**
675使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的Lua表。 675使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的 Lua 表。
676 676
677```moonscript 677```moonscript
678mt = {} 678mt = {}
@@ -814,7 +814,7 @@ readFile "example.txt"
814 814
815### 空值合并 815### 空值合并
816 816
817如果其左操作数不是**nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非nil的值,**??** 运算符将不再计算其右操作数。 817如果其左操作数不是 **nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非 nil 的值,**??** 运算符将不再计算其右操作数。
818```moonscript 818```moonscript
819local a, b, c, d 819local a, b, c, d
820a = b ?? c ?? d 820a = b ?? c ?? d
@@ -1093,7 +1093,7 @@ export default ->
1093 1093
1094## 赋值 1094## 赋值
1095 1095
1096月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过**local**和**global**声明来改变声明变量的作用范围。 1096月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过 **local** 和 **global** 声明来改变声明变量的作用范围。
1097 1097
1098```moonscript 1098```moonscript
1099hello = "world" 1099hello = "world"
@@ -1222,9 +1222,9 @@ do
1222 1222
1223## 解构赋值 1223## 解构赋值
1224 1224
1225解构赋值是一种快速从Lua表中按名称或基于数组中的位置提取值的方法。 1225解构赋值是一种快速从 Lua 表中按名称或基于数组中的位置提取值的方法。
1226 1226
1227通常当你看到一个字面量的Lua表,比如{1,2,3},它位于赋值的右侧,因为它是一个值。解构赋值语句的写法就是交换了字面量Lua表的角色,并将其放在赋值语句的左侧。 1227通常当你看到一个字面量的 Lua 表,比如 `{1,2,3}`,它位于赋值的右侧,因为它是一个值。解构赋值语句的写法就是交换了字面量 Lua 表的角色,并将其放在赋值语句的左侧。
1228 1228
1229最好是通过示例来解释。以下是如何从表格中解包前两个值的方法: 1229最好是通过示例来解释。以下是如何从表格中解包前两个值的方法:
1230 1230
@@ -1323,7 +1323,7 @@ print first, second, color
1323</pre> 1323</pre>
1324</YueDisplay> 1324</YueDisplay>
1325 1325
1326有时候我们会需要从Lua表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: 1326有时候我们会需要从 Lua 表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符:
1327 1327
1328```moonscript 1328```moonscript
1329{:concat, :insert} = table 1329{:concat, :insert} = table
@@ -1415,7 +1415,7 @@ print last -- 打印: last
1415 1415
1416### 在其它地方的解构赋值 1416### 在其它地方的解构赋值
1417 1417
1418解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在for循环中: 1418解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在 for 循环中:
1419 1419
1420```moonscript 1420```moonscript
1421tuples = [ 1421tuples = [
@@ -1438,7 +1438,7 @@ for [left, right] in *tuples
1438</pre> 1438</pre>
1439</YueDisplay> 1439</YueDisplay>
1440 1440
1441我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在for语句的名称子句中使用解构来解包它。 1441我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在 for 语句的名称子句中使用解构来解包它。
1442 1442
1443## If 赋值 1443## If 赋值
1444 1444
@@ -1506,7 +1506,7 @@ while byte := stream\read_one!
1506 1506
1507## 可变参数赋值 1507## 可变参数赋值
1508 1508
1509你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用Lua的方式访问其内容。 1509你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用 Lua 的方式访问其内容。
1510```moonscript 1510```moonscript
1511list = [1, 2, 3, 4, 5] 1511list = [1, 2, 3, 4, 5]
1512fn = (ok) -> ok, table.unpack list 1512fn = (ok) -> ok, table.unpack list
@@ -1583,7 +1583,7 @@ func --[[端口]] 3000, --[[ip]] "192.168.1.1"
1583 1583
1584## 错误处理 1584## 错误处理
1585 1585
1586用于统一进行Lua错误处理的便捷语法。 1586用于统一进行 Lua 错误处理的便捷语法。
1587 1587
1588```moonscript 1588```moonscript
1589try 1589try
@@ -1685,7 +1685,7 @@ catch e
1685 1685
1686## 属性 1686## 属性
1687 1687
1688月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。 1688月之脚本现在提供了 Lua 5.4 新增的叫做属性的语法支持。在月之脚本编译到的 Lua 目标版本低于 5.4 时,你仍然可以同时使用`const` 和 `close` 的属性声明语法,并获得常量检查和作用域回调的功能。
1689 1689
1690```moonscript 1690```moonscript
1691const a = 123 1691const a = 123
@@ -1726,9 +1726,9 @@ global const Constant = 123
1726 1726
1727## 字面量 1727## 字面量
1728 1728
1729Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 1729Lua 中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和 **nil**。
1730 1730
1731但与Lua不同的是,单引号和双引号字符串内部允许有换行: 1731但与 Lua 不同的是,单引号和双引号字符串内部允许有换行:
1732 1732
1733```moonscript 1733```moonscript
1734some_string = "这是一个字符串 1734some_string = "这是一个字符串
@@ -1927,7 +1927,7 @@ print "数字的和是", sum 10, 20
1927</pre> 1927</pre>
1928</YueDisplay> 1928</YueDisplay>
1929 1929
1930如果你需要做显式返回,可以使用return关键字: 1930如果你需要做显式返回,可以使用 return 关键字:
1931 1931
1932```moonscript 1932```moonscript
1933sum = (x, y) -> return x + y 1933sum = (x, y) -> return x + y
@@ -1953,7 +1953,7 @@ a, b = mystery 10, 20
1953 1953
1954### 粗箭头 1954### 粗箭头
1955 1955
1956因为在Lua中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含self参数的函数。 1956因为在 Lua 中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含 self 参数的函数。
1957 1957
1958```moonscript 1958```moonscript
1959func = (num) => @value + num 1959func = (num) => @value + num
@@ -1966,7 +1966,7 @@ func = (num) => @value + num
1966 1966
1967### 参数默认值 1967### 参数默认值
1968 1968
1969可以为函数的参数提供默认值。如果参数的值为nil,则确定该参数为空。任何具有默认值的nil参数在函数体运行之前都会被替换。 1969可以为函数的参数提供默认值。如果参数的值为 nil,则确定该参数为空。任何具有默认值的 nil 参数在函数体运行之前都会被替换。
1970 1970
1971```moonscript 1971```moonscript
1972my_function = (name = "某物", height = 100) -> 1972my_function = (name = "某物", height = 100) ->
@@ -2038,7 +2038,7 @@ my_func 5, 6, 7,
2038</pre> 2038</pre>
2039</YueDisplay> 2039</YueDisplay>
2040 2040
2041因为Lua表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是Lua表的一部分。 2041因为 Lua 表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是 Lua 表的一部分。
2042 2042
2043```moonscript 2043```moonscript
2044x = [ 2044x = [
@@ -2252,7 +2252,7 @@ print result, msg
2252 2252
2253## 表格字面量 2253## 表格字面量
2254 2254
2255和Lua一样,表格可以通过花括号进行定义。 2255 Lua 一样,表格可以通过花括号进行定义。
2256 2256
2257```moonscript 2257```moonscript
2258some_values = [1, 2, 3, 4] 2258some_values = [1, 2, 3, 4]
@@ -2335,7 +2335,7 @@ y = type: "狗", legs: 4, tails: 1
2335</pre> 2335</pre>
2336</YueDisplay> 2336</YueDisplay>
2337 2337
2338表格字面量的键可以使用Lua语言的关键字,而无需转义: 2338表格字面量的键可以使用 Lua 语言的关键字,而无需转义:
2339 2339
2340```moonscript 2340```moonscript
2341tbl = { 2341tbl = {
@@ -2371,7 +2371,7 @@ print_table :hair, :height
2371</pre> 2371</pre>
2372</YueDisplay> 2372</YueDisplay>
2373 2373
2374如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在Lua中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。 2374如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在 Lua 中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。
2375 2375
2376```moonscript 2376```moonscript
2377t = { 2377t = {
@@ -2388,7 +2388,7 @@ t = {
2388</pre> 2388</pre>
2389</YueDisplay> 2389</YueDisplay>
2390 2390
2391Lua的表同时具有数组部分和哈希部分,但有时候你会希望在书写Lua表时,对Lua表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。 2391Lua 的表同时具有数组部分和哈希部分,但有时候你会希望在书写 Lua 表时,对 Lua 表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。
2392 2392
2393```moonscript 2393```moonscript
2394some_values = [ 1, 2, 3, 4 ] 2394some_values = [ 1, 2, 3, 4 ]
@@ -2403,11 +2403,11 @@ list_with_one_element = [ 1, ]
2403 2403
2404## 推导式 2404## 推导式
2405 2405
2406推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生Lua表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。 2406推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生 Lua 表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。
2407 2407
2408### 列表推导式 2408### 列表推导式
2409 2409
2410以下操作创建了一个items表的副本,但所有包含的值都翻倍了。 2410以下操作创建了一个 items 表的副本,但所有包含的值都翻倍了。
2411 2411
2412```moonscript 2412```moonscript
2413items = [1, 2, 3, 4] 2413items = [1, 2, 3, 4]
@@ -2420,7 +2420,7 @@ doubled = [item * 2 for i, item in ipairs items]
2420</pre> 2420</pre>
2421</YueDisplay> 2421</YueDisplay>
2422 2422
2423可以使用when子句筛选新表中包含的项目: 2423可以使用 `when` 子句筛选新表中包含的项目:
2424 2424
2425```moonscript 2425```moonscript
2426slice = [item for i, item in ipairs items when i > 1 and i < 3] 2426slice = [item for i, item in ipairs items when i > 1 and i < 3]
@@ -2431,7 +2431,7 @@ slice = [item for i, item in ipairs items when i > 1 and i < 3]
2431</pre> 2431</pre>
2432</YueDisplay> 2432</YueDisplay>
2433 2433
2434因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled示例可以重写为: 2434因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled 示例可以重写为:
2435 2435
2436```moonscript 2436```moonscript
2437doubled = [item * 2 for item in *items] 2437doubled = [item * 2 for item in *items]
@@ -2463,9 +2463,9 @@ flat = [...v for k,v in pairs data]
2463</pre> 2463</pre>
2464</YueDisplay> 2464</YueDisplay>
2465 2465
2466for和when子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个for子句。 2466for when 子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个 for 子句。
2467 2467
2468使用多个for子句与使用多重循环的效果相同: 2468使用多个 for 子句与使用多重循环的效果相同:
2469 2469
2470```moonscript 2470```moonscript
2471x_coords = [4, 5, 6, 7] 2471x_coords = [4, 5, 6, 7]
@@ -2484,7 +2484,7 @@ for y in *y_coords]
2484</pre> 2484</pre>
2485</YueDisplay> 2485</YueDisplay>
2486 2486
2487在推导式中也可以使用简单的数值for循环: 2487在推导式中也可以使用简单的数值 for 循环:
2488 2488
2489```moonscript 2489```moonscript
2490evens = [i for i = 1, 100 when i % 2 == 0] 2490evens = [i for i = 1, 100 when i % 2 == 0]
@@ -2499,7 +2499,7 @@ evens = [i for i = 1, 100 when i % 2 == 0]
2499 2499
2500表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。 2500表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。
2501 2501
2502以下示例生成了表格thing的副本: 2502以下示例生成了表格 thing 的副本:
2503 2503
2504```moonscript 2504```moonscript
2505thing = { 2505thing = {
@@ -2561,9 +2561,9 @@ tbl = {unpack tuple for tuple in *tuples}
2561 2561
2562### 切片 2562### 切片
2563 2563
2564当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在for循环中设置迭代边界和步长。 2564当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在 for 循环中设置迭代边界和步长。
2565 2565
2566下面的案例中,我们在切片中设置最小和最大边界,取索引在1到5之间(包括1和5)的所有项目: 2566下面的案例中,我们在切片中设置最小和最大边界,取索引在 1 到 5 之间(包括 1 和 5)的所有项目:
2567 2567
2568```moonscript 2568```moonscript
2569slice = [item for item in *items[1, 5]] 2569slice = [item for item in *items[1, 5]]
@@ -2585,7 +2585,7 @@ slice = [item for item in *items[2,]]
2585</pre> 2585</pre>
2586</YueDisplay> 2586</YueDisplay>
2587 2587
2588如果省略了最小边界,便默认会设置为1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …) 2588如果省略了最小边界,便默认会设置为 1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …)
2589 2589
2590```moonscript 2590```moonscript
2591slice = [item for item in *items[,,2]] 2591slice = [item for item in *items[,,2]]
@@ -2638,7 +2638,7 @@ sub_list = items[2, 4]
2638 2638
2639## for 循环 2639## for 循环
2640 2640
2641Lua中有两种for循环形式,数字型和通用型: 2641Lua 中有两种 for 循环形式,数字型和通用型:
2642 2642
2643```moonscript 2643```moonscript
2644for i = 10, 20 2644for i = 10, 20
@@ -2691,7 +2691,7 @@ for j = 1, 10, 3 do print j
2691</pre> 2691</pre>
2692</YueDisplay> 2692</YueDisplay>
2693 2693
2694for循环也可以用作表达式。for循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。 2694for 循环也可以用作表达式。for 循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。
2695 2695
2696将每个偶数加倍: 2696将每个偶数加倍:
2697 2697
@@ -2712,9 +2712,9 @@ doubled_evens = for i = 1, 20
2712</pre> 2712</pre>
2713</YueDisplay> 2713</YueDisplay>
2714 2714
2715此外,for循环还支持带返回值的break语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。 2715此外,for 循环还支持带返回值的 break 语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。
2716 2716
2717例如,查找第一个大于10的数字: 2717例如,查找第一个大于 10 的数字:
2718 2718
2719```moonscript 2719```moonscript
2720first_large = for n in *numbers 2720first_large = for n in *numbers
@@ -2727,9 +2727,9 @@ first_large = for n in *numbers
2727</pre> 2727</pre>
2728</YueDisplay> 2728</YueDisplay>
2729 2729
2730你还可以结合for循环表达式与continue语句来过滤值。 2730你还可以结合 for 循环表达式与 continue 语句来过滤值。
2731 2731
2732注意出现在函数体末尾的for循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加for循环表达式。 2732注意出现在函数体末尾的 for 循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回 nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加 for 循环表达式。
2733 2733
2734```moonscript 2734```moonscript
2735func_a = -> for i = 1, 10 do print i 2735func_a = -> for i = 1, 10 do print i
@@ -2752,7 +2752,7 @@ print func_b! -- 打印 table 对象
2752 2752
2753## repeat 循环 2753## repeat 循环
2754 2754
2755repeat循环是从Lua语言中搬过来的相似语法: 2755repeat 循环是从 Lua 语言中搬过来的相似语法:
2756 2756
2757```moonscript 2757```moonscript
2758i = 10 2758i = 10
@@ -2773,7 +2773,7 @@ until i == 0
2773 2773
2774## while 循环 2774## while 循环
2775 2775
2776在月之脚本中的while循环有四种写法: 2776在月之脚本中的 while 循环有四种写法:
2777 2777
2778```moonscript 2778```moonscript
2779i = 10 2779i = 10
@@ -2812,7 +2812,7 @@ until running == false do my_function!
2812</pre> 2812</pre>
2813</YueDisplay> 2813</YueDisplay>
2814 2814
2815像for循环的语法一样,while循环也可以作为一个表达式使用。为了使函数返回while循环的累积列表值,必须明确使用返回语句返回while循环表达式。 2815像 for 循环的语法一样,while 循环也可以作为一个表达式使用。为了使函数返回 while 循环的累积列表值,必须明确使用返回语句返回 while 循环表达式。
2816 2816
2817## 继续 2817## 继续
2818 2818
@@ -2930,13 +2930,14 @@ print message -- 打印: 我很高
2930</pre> 2930</pre>
2931</YueDisplay> 2931</YueDisplay>
2932 2932
2933if的反义词是unless(相当于if not,如果 vs 除非): 2933if 的反义词是 unless(相当于 if not,“如”对应“除非):
2934 2934
2935```moonscript 2935```moonscript
2936unless os.date("%A") == "Monday" 2936unless os.date("%A") == "Monday"
2937 print "今天不是星期一!" 2937 print "今天不是星期一!"
2938``` 2938```
2939<YueDisplay> 2939<YueDisplay>
2940
2940<pre> 2941<pre>
2941unless os.date("%A") == "Monday" 2942unless os.date("%A") == "Monday"
2942 print "今天不是星期一!" 2943 print "今天不是星期一!"
@@ -2988,7 +2989,7 @@ print "你很幸运!" unless math.random! > 0.1
2988 2989
2989## 代码行修饰符 2990## 代码行修饰符
2990 2991
2991为了方便编写代码,循环语句和if语句可以应用于单行代码语句的末尾: 2992为了方便编写代码,循环语句和 if 语句可以应用于单行代码语句的末尾:
2992 2993
2993```moonscript 2994```moonscript
2994print "你好,世界" if name == "Rob" 2995print "你好,世界" if name == "Rob"
@@ -2999,7 +3000,7 @@ print "你好,世界" if name == "Rob"
2999</pre> 3000</pre>
3000</YueDisplay> 3001</YueDisplay>
3001 3002
3002修饰for循环的示例: 3003修饰 for 循环的示例:
3003 3004
3004```moonscript 3005```moonscript
3005print "项目: ", item for item in *items 3006print "项目: ", item for item in *items
@@ -3010,7 +3011,7 @@ print "项目: ", item for item in *items
3010</pre> 3011</pre>
3011</YueDisplay> 3012</YueDisplay>
3012 3013
3013修饰while循环的示例: 3014修饰 while 循环的示例:
3014 3015
3015```moonscript 3016```moonscript
3016game\update! while game\isRunning! 3017game\update! while game\isRunning!
@@ -3027,7 +3028,7 @@ reader\parse_line! until reader\eof!
3027 3028
3028## switch 语句 3029## switch 语句
3029 3030
3030switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。switch语句中也可以使用赋值表达式来储存临时变量值。 3031switch 语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和 if 语句一样,switch 语句在最后可以接一个 else 代码块来处理没有匹配的情况。在生成的 Lua 代码中,进行比较是使用 == 操作符完成的。switch 语句中也可以使用赋值表达式来储存临时变量值。
3031 3032
3032```moonscript 3033```moonscript
3033switch name := "Dan" 3034switch name := "Dan"
@@ -3050,9 +3051,9 @@ switch name := "Dan"
3050</pre> 3051</pre>
3051</YueDisplay> 3052</YueDisplay>
3052 3053
3053switch语句的when子句中可以通过使用逗号分隔的列表来匹配多个值。 3054switch 语句的 when 子句中可以通过使用逗号分隔的列表来匹配多个值。
3054 3055
3055switch语句也可以作为表达式使用,下面我们可以将switch语句返回的结果分配给一个变量: 3056switch 语句也可以作为表达式使用,下面我们可以将 switch 语句返回的结果分配给一个变量:
3056 3057
3057```moonscript 3058```moonscript
3058b = 1 3059b = 1
@@ -3077,7 +3078,7 @@ next_number = switch b
3077</pre> 3078</pre>
3078</YueDisplay> 3079</YueDisplay>
3079 3080
3080我们可以使用then关键字在when子句的同一行上编写处理代码。else代码块的后续代码中要写在同一行上不需要额外的关键字。 3081我们可以使用 then 关键字在 when 子句的同一行上编写处理代码。else 代码块的后续代码中要写在同一行上不需要额外的关键字。
3081 3082
3082```moonscript 3083```moonscript
3083msg = switch math.random(1, 5) 3084msg = switch math.random(1, 5)
@@ -3094,7 +3095,7 @@ msg = switch math.random(1, 5)
3094</pre> 3095</pre>
3095</YueDisplay> 3096</YueDisplay>
3096 3097
3097如果在编写switch语句时希望少写一个缩进,那么你可以把第一个when子句放在switch开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。 3098如果在编写 switch 语句时希望少写一个缩进,那么你可以把第一个 when 子句放在 switch 开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。
3098 3099
3099```moonscript 3100```moonscript
3100switch math.random(1, 5) 3101switch math.random(1, 5)
@@ -3123,11 +3124,11 @@ else
3123</pre> 3124</pre>
3124</YueDisplay> 3125</YueDisplay>
3125 3126
3126值得注意的是,在生成Lua代码时,我们要做检查的目标变量会放在==表达式的右侧。当你希望给when子句的比较对象定义一个\_\_eq元方法来重载判断逻辑时,可能会有用。 3127值得注意的是,在生成 Lua 代码时,我们要做检查的目标变量会放在 == 表达式的右侧。当你希望给 when 子句的比较对象定义一个 \_\_eq 元方法来重载判断逻辑时,可能会有用。
3127 3128
3128### 表格匹配 3129### 表格匹配
3129 3130
3130在switch的when子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非nil值,那么你可以尝试使用表格匹配的语法。 3131在 switch 的 when 子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非 nil 值,那么你可以尝试使用表格匹配的语法。
3131 3132
3132```moonscript 3133```moonscript
3133items = 3134items =
@@ -3302,7 +3303,7 @@ switch segments
3302 3303
3303## 面向对象编程 3304## 面向对象编程
3304 3305
3305在以下的示例中,月之脚本生成的Lua代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看Lua代码。 3306在以下的示例中,月之脚本生成的 Lua 代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看 Lua 代码。
3306 3307
3307一个简单的类: 3308一个简单的类:
3308 3309
@@ -3331,11 +3332,11 @@ class Inventory
3331</pre> 3332</pre>
3332</YueDisplay> 3333</YueDisplay>
3333 3334
3334在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合Lua表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为“new”的成员扮演了一个重要的角色,是作为构造函数来使用。 3335在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合 Lua 表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为 “new” 的成员扮演了一个重要的角色,是作为构造函数来使用。
3335 3336
3336值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为“self”的参数。 3337值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为 “self” 的参数。
3337 3338
3338此外,“@”前缀在变量名上起到了简化作用,代表“self”。例如,`@items` 就等同于 `self.items`。 3339此外,“@” 前缀在变量名上起到了简化作用,代表 “self”。例如,`@items` 就等同于 `self.items`。
3339 3340
3340为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。 3341为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。
3341 3342
@@ -3357,7 +3358,7 @@ inv\add_item "pants"
3357 3358
3358需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 3359需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。
3359 3360
3360例如,在下面的示例中,clothes属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。 3361例如,在下面的示例中,clothes 属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。
3361 3362
3362```moonscript 3363```moonscript
3363class Person 3364class Person
@@ -3409,7 +3410,7 @@ class Person
3409 3410
3410### 继承 3411### 继承
3411 3412
3412`extends`关键字可以在类声明中使用,以继承另一个类的属性和方法。 3413`extends` 关键字可以在类声明中使用,以继承另一个类的属性和方法。
3413 3414
3414```moonscript 3415```moonscript
3415class BackPack extends Inventory 3416class BackPack extends Inventory
@@ -3429,11 +3430,11 @@ class BackPack extends Inventory
3429</YueDisplay> 3430</YueDisplay>
3430 3431
3431 3432
3432在这一部分,我们对月之脚本中的`Inventory`类进行了扩展,加入了对可以携带物品数量的限制。 3433在这一部分,我们对月之脚本中的 `Inventory` 类进行了扩展,加入了对可以携带物品数量的限制。
3433 3434
3434在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用`super`方法来调用并执行父类的构造函数。 3435在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用 `super` 方法来调用并执行父类的构造函数。
3435 3436
3436此外,当一个类继承自另一个类时,它会尝试调用父类上的`__inherited`方法(如果这个方法存在的话),以此来向父类发送通知。这个`__inherited`函数接受两个参数:被继承的父类和继承的子类。 3437此外,当一个类继承自另一个类时,它会尝试调用父类上的 `__inherited` 方法(如果这个方法存在的话),以此来向父类发送通知。这个 `__inherited` 函数接受两个参数:被继承的父类和继承的子类。
3437 3438
3438```moonscript 3439```moonscript
3439class Shelf 3440class Shelf
@@ -3456,15 +3457,15 @@ class Cupboard extends Shelf
3456 3457
3457### super 关键字 3458### super 关键字
3458 3459
3459`super`是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 3460`super` 是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。
3460 3461
3461当`super`被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的`self`会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。 3462当 `super` 被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的 `self` 会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。
3462 3463
3463在将`super`当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。 3464在将 `super` 当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。
3464 3465
3465此外,当使用`\`操作符与`super`一起使用时,`self`将被插入为第一个参数,而不是使用`super`本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。 3466此外,当使用 `\` 操作符与 `super` 一起使用时,`self`将被插入为第一个参数,而不是使用 `super` 本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。
3466 3467
3467下面是一些使用`super`的不同方法的示例: 3468下面是一些使用 `super` 的不同方法的示例:
3468 3469
3469```moonscript 3470```moonscript
3470class MyClass extends ParentClass 3471class MyClass extends ParentClass
@@ -3523,9 +3524,9 @@ print BackPack.size -- 打印 10
3523 3524
3524如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。 3525如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。
3525 3526
3526需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的“__base”字段。 3527需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的 “__base” 字段。
3527 3528
3528此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的“__name”字段中。 3529此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的 “__name” 字段中。
3529 3530
3530```moonscript 3531```moonscript
3531print BackPack.__name -- 打印 Backpack 3532print BackPack.__name -- 打印 Backpack
@@ -3607,7 +3608,7 @@ print Counter.count -- 输出 2
3607 3608
3608### 类声明语句 3609### 类声明语句
3609 3610
3610在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self等于类对象,而不是实例对象。 3611在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self 等于类对象,而不是实例对象。
3611 3612
3612以下是创建类变量的另一种方法: 3613以下是创建类变量的另一种方法:
3613 3614
@@ -3647,9 +3648,9 @@ class MoreThings
3647 3648
3648### @ 和 @@ 值 3649### @ 和 @@ 值
3649 3650
3650当@和@@前缀在一个名字前时,它们分别代表在self和self.\_\_class中访问的那个名字。 3651 @ @@ 前缀在一个名字前时,它们分别代表在 self self.\_\_class 中访问的那个名字。
3651 3652
3652如果它们单独使用,它们是self和self.\_\_class的别名。 3653如果它们单独使用,它们是 self self.\_\_class 的别名。
3653 3654
3654```moonscript 3655```moonscript
3655assert @ == self 3656assert @ == self
@@ -3662,7 +3663,7 @@ assert @@ == self.__class
3662</pre> 3663</pre>
3663</YueDisplay> 3664</YueDisplay>
3664 3665
3665例如,使用@@从实例方法快速创建同一类的新实例的方法: 3666例如,使用 @@ 从实例方法快速创建同一类的新实例的方法:
3666 3667
3667```moonscript 3668```moonscript
3668some_instance_method = (...) => @@ ... 3669some_instance_method = (...) => @@ ...
@@ -3740,7 +3741,7 @@ x = class Bucket
3740 3741
3741### 匿名类 3742### 匿名类
3742 3743
3743声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name属性将为nil。如果出现在赋值语句中,赋值操作左侧的名称将代替nil。 3744声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name 属性将为 nil。如果出现在赋值语句中,赋值操作左侧的名称将代替 nil。
3744 3745
3745```moonscript 3746```moonscript
3746BigBucket = class extends Bucket 3747BigBucket = class extends Bucket
@@ -3811,11 +3812,11 @@ assert y.__class.__parent ~= X -- X 不是 Y 的父类
3811 3812
3812## with 语句 3813## with 语句
3813 3814
3814在编写Lua代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。 3815在编写 Lua 代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。
3815 3816
3816这导致在代码中多次重复引用对象的名称,增加了不必要的文本噪音。一个常见的解决方案是在创建对象时,在构造函数传入一个表,该表包含要覆盖设置的键和值的集合。这样做的缺点是该对象的构造函数必须支持这种初始化形式。 3817这导致在代码中多次重复引用对象的名称,增加了不必要的文本噪音。一个常见的解决方案是在创建对象时,在构造函数传入一个表,该表包含要覆盖设置的键和值的集合。这样做的缺点是该对象的构造函数必须支持这种初始化形式。
3817 3818
3818with块有助于简化编写这样的代码。在with块内,我们可以使用以.或\开头的特殊语句,这些语句代表我们正在使用的对象的操作。 3819with 块有助于简化编写这样的代码。在 with 块内,我们可以使用以 . 或 \ 开头的特殊语句,这些语句代表我们正在使用的对象的操作。
3819 3820
3820例如,我们可以这样处理一个新创建的对象: 3821例如,我们可以这样处理一个新创建的对象:
3821 3822
@@ -3836,7 +3837,7 @@ with Person!
3836</pre> 3837</pre>
3837</YueDisplay> 3838</YueDisplay>
3838 3839
3839with语句也可以用作一个表达式,并返回它的代码块正在处理的对象。 3840with 语句也可以用作一个表达式,并返回它的代码块正在处理的对象。
3840 3841
3841```moonscript 3842```moonscript
3842file = with File "favorite_foods.txt" 3843file = with File "favorite_foods.txt"
@@ -3870,9 +3871,9 @@ me = create_person "Leaf", [dad, mother, sister]
3870</pre> 3871</pre>
3871</YueDisplay> 3872</YueDisplay>
3872 3873
3873在此用法中,with可以被视为K组合子(k-combinator)的一种特殊形式。 3874在此用法中,with 可以被视为K组合子(k-combinator)的一种特殊形式。
3874 3875
3875如果你想给表达式另外起一个名称的话,with语句中的表达式也可以是一个赋值语句。 3876如果你想给表达式另外起一个名称的话,with 语句中的表达式也可以是一个赋值语句。
3876 3877
3877```moonscript 3878```moonscript
3878with str := "你好" 3879with str := "你好"
@@ -3925,7 +3926,7 @@ with? obj
3925 3926
3926## do 语句 3927## do 语句
3927 3928
3928当用作语句时,do语句的作用就像在Lua中差不多。 3929当用作语句时,do 语句的作用就像在 Lua 中差不多。
3929 3930
3930```moonscript 3931```moonscript
3931do 3932do
@@ -3942,7 +3943,7 @@ print var -- 这里是nil
3942</pre> 3943</pre>
3943</YueDisplay> 3944</YueDisplay>
3944 3945
3945月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将do语句代码块的最后一个语句作为表达式返回的结果。 3946月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将 do 语句代码块的最后一个语句作为表达式返回的结果。
3946 3947
3947```moonscript 3948```moonscript
3948counter = do 3949counter = do
@@ -4126,7 +4127,7 @@ print i, k -- 这些已经被更新
4126 4127
4127## 月之脚本语言库 4128## 月之脚本语言库
4128 4129
4129使用`require("yue")`来访问。 4130使用 `require("yue")` 来访问。
4130 4131
4131### yue 4132### yue
4132 4133