diff options
Diffstat (limited to 'doc/docs/zh/doc/README.md')
-rwxr-xr-x | doc/docs/zh/doc/README.md | 608 |
1 files changed, 526 insertions, 82 deletions
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md index 1a2da96..15f4768 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
@@ -16,19 +16,29 @@ Yue(月)是中文中“月亮”的名称。 | |||
16 | ### 月之脚本概览 | 16 | ### 月之脚本概览 |
17 | ```moonscript | 17 | ```moonscript |
18 | -- 导入语法 | 18 | -- 导入语法 |
19 | import "yue" as :p, :to_lua | 19 | import p, to_lua from "yue" |
20 | 20 | ||
21 | -- 隐式对象 | 21 | -- 隐式对象 |
22 | inventory = | 22 | inventory = |
23 | equipment: | 23 | equipment: |
24 | * "sword" | 24 | - "sword" |
25 | * "shield" | 25 | - "shield" |
26 | items: | 26 | items: |
27 | * name: "potion" | 27 | - name: "potion" |
28 | count: 10 | 28 | count: 10 |
29 | * name: "bread" | 29 | - name: "bread" |
30 | count: 3 | 30 | count: 3 |
31 | 31 | ||
32 | -- 列表推导 | ||
33 | map = (arr, action) -> | ||
34 | [action item for item in *arr] | ||
35 | |||
36 | filter = (arr, cond) -> | ||
37 | [item for item in *arr when cond item] | ||
38 | |||
39 | reduce = (arr, init, action): init -> | ||
40 | init = action init, item for item in *arr | ||
41 | |||
32 | -- 管道操作符 | 42 | -- 管道操作符 |
33 | [1, 2, 3] | 43 | [1, 2, 3] |
34 | |> map (x) -> x * 2 | 44 | |> map (x) -> x * 2 |
@@ -51,19 +61,29 @@ export 🌛 = "月之脚本" | |||
51 | <YueDisplay> | 61 | <YueDisplay> |
52 | <pre> | 62 | <pre> |
53 | -- 导入语法 | 63 | -- 导入语法 |
54 | import "yue" as :p, :to_lua | 64 | import p, to_lua from "yue" |
55 | 65 | ||
56 | -- 隐式对象 | 66 | -- 隐式对象 |
57 | inventory = | 67 | inventory = |
58 | equipment: | 68 | equipment: |
59 | * "sword" | 69 | - "sword" |
60 | * "shield" | 70 | - "shield" |
61 | items: | 71 | items: |
62 | * name: "potion" | 72 | - name: "potion" |
63 | count: 10 | 73 | count: 10 |
64 | * name: "bread" | 74 | - name: "bread" |
65 | count: 3 | 75 | count: 3 |
66 | 76 | ||
77 | -- 列表推导 | ||
78 | map = (arr, action) -> | ||
79 | [action item for item in *arr] | ||
80 | |||
81 | filter = (arr, cond) -> | ||
82 | [item for item in *arr when cond item] | ||
83 | |||
84 | reduce = (arr, init, action): init -> | ||
85 | init = action init, item for item in *arr | ||
86 | |||
67 | -- 管道操作符 | 87 | -- 管道操作符 |
68 | [1, 2, 3] | 88 | [1, 2, 3] |
69 | |> map (x) -> x * 2 | 89 | |> map (x) -> x * 2 |
@@ -122,7 +142,7 @@ export 🌛 = "月之脚本" | |||
122 | 142 | ||
123 | * **下载预编译的二进制程序** | 143 | * **下载预编译的二进制程序** |
124 | 144 | ||
125 |  您可以下载预编译的二进制程序,包括兼容不同 Lua 版本的二进制可执行文件和库文件。 | 145 |  你可以下载预编译的二进制程序,包括兼容不同 Lua 版本的二进制可执行文件和库文件。 |
126 | 146 | ||
127 |  在[这里](https://github.com/IppClub/YueScript/releases)下载预编译的二进制程序。 | 147 |  在[这里](https://github.com/IppClub/YueScript/releases)下载预编译的二进制程序。 |
128 | 148 | ||
@@ -132,14 +152,14 @@ export 🌛 = "月之脚本" | |||
132 | 152 | ||
133 | 在Lua中使用月之脚本模块: | 153 | 在Lua中使用月之脚本模块: |
134 | 154 | ||
135 | * **用法 1** | 155 | * **用法 1** |
136 | 在Lua中引入 "你的脚本入口文件.yue"。 | 156 | 在Lua中引入 "你的脚本入口文件.yue"。 |
137 | ```Lua | 157 | ```Lua |
138 | require("yue")("你的脚本入口文件") | 158 | require("yue")("你的脚本入口文件") |
139 | ``` | 159 | ``` |
140 | 当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import**进行脚本引用即可。错误消息中的代码行号也会被正确处理。 | 160 | 当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import**进行脚本引用即可。错误消息中的代码行号也会被正确处理。 |
141 | 161 | ||
142 | * **用法 2** | 162 | * **用法 2** |
143 | 手动引入月之脚本模块并重写错误消息来帮助调试。 | 163 | 手动引入月之脚本模块并重写错误消息来帮助调试。 |
144 | ```lua | 164 | ```lua |
145 | local yue = require("yue") | 165 | local yue = require("yue") |
@@ -151,7 +171,7 @@ end, function(err) | |||
151 | end) | 171 | end) |
152 | ``` | 172 | ``` |
153 | 173 | ||
154 | * **用法 3** | 174 | * **用法 3** |
155 | 在Lua中使用月之脚本编译器功能。 | 175 | 在Lua中使用月之脚本编译器功能。 |
156 | ```lua | 176 | ```lua |
157 | local yue = require("yue") | 177 | local yue = require("yue") |
@@ -202,12 +222,12 @@ f! | |||
202 | 不添加任何选项执行命令可以进入REPL模式, | 222 | 不添加任何选项执行命令可以进入REPL模式, |
203 | 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式 | 223 | 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式 |
204 | ``` | 224 | ``` |
205 |   使用案例: | 225 |   使用案例: |
206 |   递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .** | 226 |   递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .** |
207 |   编译并将结果保存到目标路径: **yue -t /target/path/ .** | 227 |   编译并将结果保存到目标路径: **yue -t /target/path/ .** |
208 |   编译并保留调试信息: **yue -l .** | 228 |   编译并保留调试信息: **yue -l .** |
209 |   编译并生成压缩代码: **yue -m .** | 229 |   编译并生成压缩代码: **yue -m .** |
210 |   直接执行代码: **yue -e 'print 123'** | 230 |   直接执行代码: **yue -e 'print 123'** |
211 |   执行一个月之脚本文件: **yue -e main.yue** | 231 |   执行一个月之脚本文件: **yue -e main.yue** |
212 | 232 | ||
213 | ## 宏 | 233 | ## 宏 |
@@ -333,7 +353,7 @@ end | |||
333 | 353 | ||
334 | ### 导出宏 | 354 | ### 导出宏 |
335 | 355 | ||
336 | 宏函数可以从一个模块中导出,并在另一个模块中导入。您必须将导出的宏函数放在一个单独的文件中使用,而且只有宏定义、宏导入和宏展开可以放入这个宏导出模块中。 | 356 | 宏函数可以从一个模块中导出,并在另一个模块中导入。你必须将导出的宏函数放在一个单独的文件中使用,而且只有宏定义、宏导入和宏展开可以放入这个宏导出模块中。 |
337 | ```moonscript | 357 | ```moonscript |
338 | -- 文件: utils.yue | 358 | -- 文件: utils.yue |
339 | export macro map = (items, action) -> "[#{action} for _ in *#{items}]" | 359 | export macro map = (items, action) -> "[#{action} for _ in *#{items}]" |
@@ -422,6 +442,54 @@ print "有效的枚举类型:", $BodyType Static | |||
422 | </pre> | 442 | </pre> |
423 | </YueDisplay> | 443 | </YueDisplay> |
424 | 444 | ||
445 | ### 宏参数检查 | ||
446 | |||
447 | 可以直接在参数列表中声明期望的 AST 节点类型,并在编译时检查传入的宏参数是否符合预期。 | ||
448 | |||
449 | ```moonscript | ||
450 | macro printNumAndStr = (num `Num, str `String) -> | | ||
451 | print( | ||
452 | #{num} | ||
453 | #{str} | ||
454 | ) | ||
455 | |||
456 | $printNumAndStr 123, "hello" | ||
457 | ``` | ||
458 | <YueDisplay> | ||
459 | <pre> | ||
460 | macro printNumAndStr = (num `Num, str `String) -> | | ||
461 | print( | ||
462 | #{num} | ||
463 | #{str} | ||
464 | ) | ||
465 | |||
466 | $printNumAndStr 123, "hello" | ||
467 | </pre> | ||
468 | </YueDisplay> | ||
469 | |||
470 | 如果需要做更加灵活的参数检查操作,可以使用内置的 `$is_ast` 宏函数在合适的位置进行手动检查。 | ||
471 | |||
472 | ```moonscript | ||
473 | macro printNumAndStr = (num, str) -> | ||
474 | error "expected Num as first argument" unless $is_ast Num, num | ||
475 | error "expected String as second argument" unless $is_ast String, str | ||
476 | "print(#{num}, #{str})" | ||
477 | |||
478 | $printNumAndStr 123, "hello" | ||
479 | ``` | ||
480 | <YueDisplay> | ||
481 | <pre> | ||
482 | macro printNumAndStr = (num, str) -> | ||
483 | error "expected Num as first argument" unless $is_ast Num, num | ||
484 | error "expected String as second argument" unless $is_ast String, str | ||
485 | "print(#{num}, #{str})" | ||
486 | |||
487 | $printNumAndStr 123, "hello" | ||
488 | </pre> | ||
489 | </YueDisplay> | ||
490 | |||
491 | 更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。 | ||
492 | |||
425 | ## 操作符 | 493 | ## 操作符 |
426 | 494 | ||
427 | Lua的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 | 495 | Lua的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 |
@@ -439,7 +507,7 @@ tb::func! if tb != nil | |||
439 | 507 | ||
440 | ### 链式比较 | 508 | ### 链式比较 |
441 | 509 | ||
442 | 您可以在月之脚本中进行比较表达式的链式书写: | 510 | 你可以在月之脚本中进行比较表达式的链式书写: |
443 | 511 | ||
444 | ```moonscript | 512 | ```moonscript |
445 | print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 | 513 | print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 |
@@ -528,7 +596,7 @@ tab[] = "Value" | |||
528 | 596 | ||
529 | ### 表扩展 | 597 | ### 表扩展 |
530 | 598 | ||
531 | 您可以使用前置 `...` 操作符在Lua表中插入数组表或哈希表。 | 599 | 你可以使用前置 `...` 操作符在Lua表中插入数组表或哈希表。 |
532 | 600 | ||
533 | ```moonscript | 601 | ```moonscript |
534 | parts = | 602 | parts = |
@@ -565,11 +633,26 @@ merge = {...a, ...b} | |||
565 | </pre> | 633 | </pre> |
566 | </YueDisplay> | 634 | </YueDisplay> |
567 | 635 | ||
636 | ### 表反向索引 | ||
637 | |||
638 | 你可以使用 **#** 操作符来反向索引表中的元素。 | ||
639 | |||
640 | ```moonscript | ||
641 | last = data.items[#] | ||
642 | second_last = data.items[#-1] | ||
643 | ``` | ||
644 | <YueDisplay> | ||
645 | <pre> | ||
646 | last = data.items[#] | ||
647 | second_last = data.items[#-1] | ||
648 | </pre> | ||
649 | </YueDisplay> | ||
650 | |||
568 | ### 元表 | 651 | ### 元表 |
569 | 652 | ||
570 | **<>** 操作符可提供元表操作的快捷方式。 | 653 | **<>** 操作符可提供元表操作的快捷方式。 |
571 | 654 | ||
572 | * **元表创建** | 655 | * **元表创建** |
573 | 使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的Lua表。 | 656 | 使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的Lua表。 |
574 | 657 | ||
575 | ```moonscript | 658 | ```moonscript |
@@ -605,7 +688,7 @@ close _ = <close>: -> print "超出范围" | |||
605 | </pre> | 688 | </pre> |
606 | </YueDisplay> | 689 | </YueDisplay> |
607 | 690 | ||
608 | * **元表访问** | 691 | * **元表访问** |
609 | 使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。 | 692 | 使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。 |
610 | 693 | ||
611 | ```moonscript | 694 | ```moonscript |
@@ -629,7 +712,7 @@ print tb.item | |||
629 | </pre> | 712 | </pre> |
630 | </YueDisplay> | 713 | </YueDisplay> |
631 | 714 | ||
632 | * **元表解构** | 715 | * **元表解构** |
633 | 使用被 **<>** 包围的元方法键解构元表。 | 716 | 使用被 **<>** 包围的元方法键解构元表。 |
634 | 717 | ||
635 | ```moonscript | 718 | ```moonscript |
@@ -680,7 +763,7 @@ with? io.open "test.txt", "w" | |||
680 | 763 | ||
681 | ### 管道 | 764 | ### 管道 |
682 | 765 | ||
683 | 与其使用一系列嵌套的函数调用,您还可以考虑使用运算符 **|>** 来传递值。 | 766 | 与其使用一系列嵌套的函数调用,你还可以考虑使用运算符 **|>** 来传递值。 |
684 | 767 | ||
685 | ```moonscript | 768 | ```moonscript |
686 | "你好" |> print | 769 | "你好" |> print |
@@ -731,67 +814,87 @@ a ??= false | |||
731 | 814 | ||
732 | ### 隐式对象 | 815 | ### 隐式对象 |
733 | 816 | ||
734 | 您可以在表格块内使用符号 **\*** 开始编写一系列隐式结构。如果您正在创建隐式对象,对象的字段必须具有相同的缩进。 | 817 | 你可以在表格块内使用符号 **\*** 或是 **-** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。 |
818 | |||
735 | ```moonscript | 819 | ```moonscript |
820 | -- 赋值时使用隐式对象 | ||
736 | list = | 821 | list = |
737 | * 1 | 822 | * 1 |
738 | * 2 | 823 | * 2 |
739 | * 3 | 824 | * 3 |
740 | 825 | ||
826 | -- 函数调用时使用隐式对象 | ||
741 | func | 827 | func |
742 | * 1 | 828 | * 1 |
743 | * 2 | 829 | * 2 |
744 | * 3 | 830 | * 3 |
745 | 831 | ||
832 | -- 返回时使用隐式对象 | ||
833 | f = -> | ||
834 | return | ||
835 | * 1 | ||
836 | * 2 | ||
837 | * 3 | ||
838 | |||
839 | -- 表格时使用隐式对象 | ||
746 | tb = | 840 | tb = |
747 | name: "abc" | 841 | name: "abc" |
748 | 842 | ||
749 | values: | 843 | values: |
750 | * "a" | 844 | - "a" |
751 | * "b" | 845 | - "b" |
752 | * "c" | 846 | - "c" |
753 | 847 | ||
754 | objects: | 848 | objects: |
755 | * name: "a" | 849 | - name: "a" |
756 | value: 1 | 850 | value: 1 |
757 | func: => @value + 1 | 851 | func: => @value + 1 |
758 | tb: | 852 | tb: |
759 | fieldA: 1 | 853 | fieldA: 1 |
760 | 854 | ||
761 | * name: "b" | 855 | - name: "b" |
762 | value: 2 | 856 | value: 2 |
763 | func: => @value + 2 | 857 | func: => @value + 2 |
764 | tb: { } | 858 | tb: { } |
765 | |||
766 | ``` | 859 | ``` |
767 | <YueDisplay> | 860 | <YueDisplay> |
768 | <pre> | 861 | <pre> |
862 | -- 赋值时使用隐式对象 | ||
769 | list = | 863 | list = |
770 | * 1 | 864 | * 1 |
771 | * 2 | 865 | * 2 |
772 | * 3 | 866 | * 3 |
773 | 867 | ||
868 | -- 函数调用时使用隐式对象 | ||
774 | func | 869 | func |
775 | * 1 | 870 | * 1 |
776 | * 2 | 871 | * 2 |
777 | * 3 | 872 | * 3 |
778 | 873 | ||
874 | -- 返回时使用隐式对象 | ||
875 | f = -> | ||
876 | return | ||
877 | * 1 | ||
878 | * 2 | ||
879 | * 3 | ||
880 | |||
881 | -- 表格时使用隐式对象 | ||
779 | tb = | 882 | tb = |
780 | name: "abc" | 883 | name: "abc" |
781 | 884 | ||
782 | values: | 885 | values: |
783 | * "a" | 886 | - "a" |
784 | * "b" | 887 | - "b" |
785 | * "c" | 888 | - "c" |
786 | 889 | ||
787 | objects: | 890 | objects: |
788 | * name: "a" | 891 | - name: "a" |
789 | value: 1 | 892 | value: 1 |
790 | func: => @value + 1 | 893 | func: => @value + 1 |
791 | tb: | 894 | tb: |
792 | fieldA: 1 | 895 | fieldA: 1 |
793 | 896 | ||
794 | * name: "b" | 897 | - name: "b" |
795 | value: 2 | 898 | value: 2 |
796 | func: => @value + 2 | 899 | func: => @value + 2 |
797 | tb: { } | 900 | tb: { } |
@@ -859,7 +962,7 @@ do | |||
859 | 962 | ||
860 | 导出语句提供了一种简洁的方式来定义当前的模块。 | 963 | 导出语句提供了一种简洁的方式来定义当前的模块。 |
861 | 964 | ||
862 | * **命名导出** | 965 | * **命名导出** |
863 | 带命名的导出将定义一个局部变量,并在导出的表中添加一个同名的字段。 | 966 | 带命名的导出将定义一个局部变量,并在导出的表中添加一个同名的字段。 |
864 | 967 | ||
865 | ```moonscript | 968 | ```moonscript |
@@ -923,7 +1026,7 @@ export["a-b-c"] = 123 | |||
923 | </pre> | 1026 | </pre> |
924 | </YueDisplay> | 1027 | </YueDisplay> |
925 | 1028 | ||
926 | * **未命名导出** | 1029 | * **未命名导出** |
927 | 未命名导出会将要导出的目标项目添加到导出表的数组部分。 | 1030 | 未命名导出会将要导出的目标项目添加到导出表的数组部分。 |
928 | 1031 | ||
929 | ```moonscript | 1032 | ```moonscript |
@@ -953,7 +1056,7 @@ export with tmp | |||
953 | </pre> | 1056 | </pre> |
954 | </YueDisplay> | 1057 | </YueDisplay> |
955 | 1058 | ||
956 | * **默认导出** | 1059 | * **默认导出** |
957 | 在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。 | 1060 | 在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。 |
958 | 1061 | ||
959 | ```moonscript | 1062 | ```moonscript |
@@ -1223,7 +1326,7 @@ print first, second, color | |||
1223 | </pre> | 1326 | </pre> |
1224 | </YueDisplay> | 1327 | </YueDisplay> |
1225 | 1328 | ||
1226 | 在进行解构时,您可以指定默认值,如: | 1329 | 在进行解构时,你可以指定默认值,如: |
1227 | 1330 | ||
1228 | ```moonscript | 1331 | ```moonscript |
1229 | {:name = "nameless", :job = "jobless"} = person | 1332 | {:name = "nameless", :job = "jobless"} = person |
@@ -1234,7 +1337,7 @@ print first, second, color | |||
1234 | </pre> | 1337 | </pre> |
1235 | </YueDisplay> | 1338 | </YueDisplay> |
1236 | 1339 | ||
1237 | 在进行列表解构时,您可以使用`_`作为占位符: | 1340 | 在进行列表解构时,你可以使用`_`作为占位符: |
1238 | 1341 | ||
1239 | ```moonscript | 1342 | ```moonscript |
1240 | [_, two, _, four] = items | 1343 | [_, two, _, four] = items |
@@ -1245,9 +1348,55 @@ print first, second, color | |||
1245 | </pre> | 1348 | </pre> |
1246 | </YueDisplay> | 1349 | </YueDisplay> |
1247 | 1350 | ||
1248 | ### 在其它地方的解构 | 1351 | ### 范围解构 |
1352 | |||
1353 | 你可以使用展开运算符 `...` 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。 | ||
1354 | |||
1355 | ```moonscript | ||
1356 | orders = ["first", "second", "third", "fourth", "last"] | ||
1357 | [first, ...bulk, last] = orders | ||
1358 | print first -- 打印: first | ||
1359 | print bulk -- 打印: {"second", "third", "fourth"} | ||
1360 | print last -- 打印: last | ||
1361 | ``` | ||
1362 | <YueDisplay> | ||
1363 | <pre> | ||
1364 | orders = ["first", "second", "third", "fourth", "last"] | ||
1365 | [first, ...bulk, last] = orders | ||
1366 | print first -- 打印: first | ||
1367 | print bulk -- 打印: {"second", "third", "fourth"} | ||
1368 | print last -- 打印: last | ||
1369 | </pre> | ||
1370 | </YueDisplay> | ||
1371 | |||
1372 | 展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 `_` 作为占位符来表示你想跳过对应范围的捕获: | ||
1373 | |||
1374 | ```moonscript | ||
1375 | -- 捕获第一个元素之后的所有元素 | ||
1376 | [first, ...rest] = orders | ||
1377 | |||
1378 | -- 捕获最后一个元素之前的所有元素 | ||
1379 | [...start, last] = orders | ||
1380 | |||
1381 | -- 跳过中间的元素,只捕获第一个和最后一个元素 | ||
1382 | [first, ..._, last] = orders | ||
1383 | ``` | ||
1384 | <YueDisplay> | ||
1385 | <pre> | ||
1386 | -- 捕获第一个元素之后的所有元素 | ||
1387 | [first, ...rest] = orders | ||
1388 | |||
1389 | -- 捕获最后一个元素之前的所有元素 | ||
1390 | [...start, last] = orders | ||
1391 | |||
1392 | -- 跳过中间的元素,只捕获第一个和最后一个元素 | ||
1393 | [first, ..._, last] = orders | ||
1394 | </pre> | ||
1395 | </YueDisplay> | ||
1396 | |||
1397 | ### 在其它地方的解构赋值 | ||
1249 | 1398 | ||
1250 | 解构也可以出现在其它隐式进行赋值的地方。一个例子是用在for循环: | 1399 | 解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在for循环中: |
1251 | 1400 | ||
1252 | ```moonscript | 1401 | ```moonscript |
1253 | tuples = [ | 1402 | tuples = [ |
@@ -1322,7 +1471,7 @@ print "好的" | |||
1322 | 1471 | ||
1323 | ### While 赋值 | 1472 | ### While 赋值 |
1324 | 1473 | ||
1325 | 您可以在 while 循环中同样使用赋值来获取循环条件的值。 | 1474 | 你可以在 while 循环中同样使用赋值来获取循环条件的值。 |
1326 | ```moonscript | 1475 | ```moonscript |
1327 | while byte := stream\read_one! | 1476 | while byte := stream\read_one! |
1328 | -- 对 byte 做一些操作 | 1477 | -- 对 byte 做一些操作 |
@@ -1338,7 +1487,7 @@ while byte := stream\read_one! | |||
1338 | 1487 | ||
1339 | ## 可变参数赋值 | 1488 | ## 可变参数赋值 |
1340 | 1489 | ||
1341 | 您可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用Lua的方式访问其内容。 | 1490 | 你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用Lua的方式访问其内容。 |
1342 | ```moonscript | 1491 | ```moonscript |
1343 | list = [1, 2, 3, 4, 5] | 1492 | list = [1, 2, 3, 4, 5] |
1344 | fn = (ok) -> ok, table.unpack list | 1493 | fn = (ok) -> ok, table.unpack list |
@@ -1360,7 +1509,7 @@ print ok, count, first | |||
1360 | 1509 | ||
1361 | ## 空白 | 1510 | ## 空白 |
1362 | 1511 | ||
1363 | 月之脚本是一个对空白敏感的语言。您必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 | 1512 | 月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 |
1364 | 1513 | ||
1365 | ### 多行链式调用 | 1514 | ### 多行链式调用 |
1366 | 1515 | ||
@@ -1474,6 +1623,47 @@ catch err | |||
1474 | </pre> | 1623 | </pre> |
1475 | </YueDisplay> | 1624 | </YueDisplay> |
1476 | 1625 | ||
1626 | ### 错误处理简化 | ||
1627 | |||
1628 | `try?` 是 `try` 的功能简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。 | ||
1629 | |||
1630 | ```moonscript | ||
1631 | a, b, c = try? func! | ||
1632 | |||
1633 | -- 与空值合并运算符一起使用 | ||
1634 | a = (try? func!) ?? "default" | ||
1635 | |||
1636 | -- 作为函数参数 | ||
1637 | f try? func! | ||
1638 | |||
1639 | -- 带 catch 块的 try! | ||
1640 | f try? | ||
1641 | print 123 | ||
1642 | func! | ||
1643 | catch e | ||
1644 | print e | ||
1645 | e | ||
1646 | ``` | ||
1647 | <YueDisplay> | ||
1648 | <pre> | ||
1649 | a, b, c = try? func! | ||
1650 | |||
1651 | -- 与空值合并运算符一起使用 | ||
1652 | a = (try? func!) ?? "default" | ||
1653 | |||
1654 | -- 作为函数参数 | ||
1655 | f try? func! | ||
1656 | |||
1657 | -- 带 catch 块的 try! | ||
1658 | f try? | ||
1659 | print 123 | ||
1660 | func! | ||
1661 | catch e | ||
1662 | print e | ||
1663 | e | ||
1664 | </pre> | ||
1665 | </YueDisplay> | ||
1666 | |||
1477 | ## 属性 | 1667 | ## 属性 |
1478 | 1668 | ||
1479 | 月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。 | 1669 | 月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。 |
@@ -1502,6 +1692,19 @@ const {:a, :b, c, d} = tb | |||
1502 | </pre> | 1692 | </pre> |
1503 | </YueDisplay> | 1693 | </YueDisplay> |
1504 | 1694 | ||
1695 | 你也可以声明全局变量为常量。 | ||
1696 | |||
1697 | ```moonscript | ||
1698 | global const Constant = 123 | ||
1699 | -- Constant = 1 | ||
1700 | ``` | ||
1701 | <YueDisplay> | ||
1702 | <pre> | ||
1703 | global const Constant = 123 | ||
1704 | -- Constant = 1 | ||
1705 | </pre> | ||
1706 | </YueDisplay> | ||
1707 | |||
1505 | ## 字面量 | 1708 | ## 字面量 |
1506 | 1709 | ||
1507 | Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 | 1710 | Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 |
@@ -1529,17 +1732,78 @@ print "我有#{math.random! * 100}%的把握。" | |||
1529 | 1732 | ||
1530 | ### 数字字面量 | 1733 | ### 数字字面量 |
1531 | 1734 | ||
1532 | 您可以在数字字面量中使用下划线来增加可读性。 | 1735 | 你可以在数字字面量中使用下划线来增加可读性。 |
1533 | 1736 | ||
1534 | ```moonscript | 1737 | ```moonscript |
1535 | integer = 1_000_000 | 1738 | integer = 1_000_000 |
1536 | hex = 0xEF_BB_BF | 1739 | hex = 0xEF_BB_BF |
1740 | binary = 0B10011 | ||
1537 | ``` | 1741 | ``` |
1538 | <YueDisplay> | 1742 | <YueDisplay> |
1539 | 1743 | ||
1540 | <pre> | 1744 | <pre> |
1541 | integer = 1_000_000 | 1745 | integer = 1_000_000 |
1542 | hex = 0xEF_BB_BF | 1746 | hex = 0xEF_BB_BF |
1747 | binary = 0B10011 | ||
1748 | </pre> | ||
1749 | </YueDisplay> | ||
1750 | |||
1751 | ### YAML 风格字符串 | ||
1752 | |||
1753 | 使用 `|` 前缀标记一个多行 YAML 风格字符串: | ||
1754 | |||
1755 | ```moonscript | ||
1756 | str = | | ||
1757 | key: value | ||
1758 | list: | ||
1759 | - item1 | ||
1760 | - #{expr} | ||
1761 | ``` | ||
1762 | <YueDisplay> | ||
1763 | <pre> | ||
1764 | str = | | ||
1765 | key: value | ||
1766 | list: | ||
1767 | - item1 | ||
1768 | - #{expr} | ||
1769 | </pre> | ||
1770 | </YueDisplay> | ||
1771 | |||
1772 | 其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。 | ||
1773 | |||
1774 | YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。 | ||
1775 | |||
1776 | ```moonscript | ||
1777 | fn = -> | ||
1778 | str = | | ||
1779 | foo: | ||
1780 | bar: baz | ||
1781 | return str | ||
1782 | ``` | ||
1783 | <YueDisplay> | ||
1784 | <pre> | ||
1785 | fn = -> | ||
1786 | str = | | ||
1787 | foo: | ||
1788 | bar: baz | ||
1789 | return str | ||
1790 | </pre> | ||
1791 | </YueDisplay> | ||
1792 | |||
1793 | 输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。 | ||
1794 | |||
1795 | 支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义: | ||
1796 | |||
1797 | ```moonscript | ||
1798 | str = | | ||
1799 | path: "C:\Program Files\App" | ||
1800 | note: 'He said: "#{Hello}!"' | ||
1801 | ``` | ||
1802 | <YueDisplay> | ||
1803 | <pre> | ||
1804 | str = | | ||
1805 | path: "C:\Program Files\App" | ||
1806 | note: 'He said: "#{Hello}!"' | ||
1543 | </pre> | 1807 | </pre> |
1544 | </YueDisplay> | 1808 | </YueDisplay> |
1545 | 1809 | ||
@@ -1644,7 +1908,7 @@ print "数字的和是", sum 10, 20 | |||
1644 | </pre> | 1908 | </pre> |
1645 | </YueDisplay> | 1909 | </YueDisplay> |
1646 | 1910 | ||
1647 | 如果您需要做显式返回,可以使用return关键字: | 1911 | 如果你需要做显式返回,可以使用return关键字: |
1648 | 1912 | ||
1649 | ```moonscript | 1913 | ```moonscript |
1650 | sum = (x, y) -> return x + y | 1914 | sum = (x, y) -> return x + y |
@@ -1850,7 +2114,7 @@ print @value | |||
1850 | </pre> | 2114 | </pre> |
1851 | </YueDisplay> | 2115 | </YueDisplay> |
1852 | 2116 | ||
1853 | 您可以通过一个占位符指定回调函数的传参位置。 | 2117 | 你可以通过一个占位符指定回调函数的传参位置。 |
1854 | 2118 | ||
1855 | ```moonscript | 2119 | ```moonscript |
1856 | (x) <- map _, [1, 2, 3] | 2120 | (x) <- map _, [1, 2, 3] |
@@ -1863,22 +2127,22 @@ x * 2 | |||
1863 | </pre> | 2127 | </pre> |
1864 | </YueDisplay> | 2128 | </YueDisplay> |
1865 | 2129 | ||
1866 | 如果您希望在反向回调处理后继续编写更多其它的代码,您可以使用do语句将不归属反向回调的代码分开。 | 2130 | 如果你希望在反向回调处理后继续编写更多其它的代码,可以使用 do 语句将不属于反向回调的代码分隔开。对于非粗箭头函数的反向回调,回调返回值的括号也是可以省略的。 |
1867 | 2131 | ||
1868 | ```moonscript | 2132 | ```moonscript |
1869 | result, msg = do | 2133 | result, msg = do |
1870 | (data) <- readAsync "文件名.txt" | 2134 | data <- readAsync "文件名.txt" |
1871 | print data | 2135 | print data |
1872 | (info) <- processAsync data | 2136 | info <- processAsync data |
1873 | check info | 2137 | check info |
1874 | print result, msg | 2138 | print result, msg |
1875 | ``` | 2139 | ``` |
1876 | <YueDisplay> | 2140 | <YueDisplay> |
1877 | <pre> | 2141 | <pre> |
1878 | result, msg = do | 2142 | result, msg = do |
1879 | (data) <- readAsync "文件名.txt" | 2143 | data <- readAsync "文件名.txt" |
1880 | print data | 2144 | print data |
1881 | (info) <- processAsync data | 2145 | info <- processAsync data |
1882 | check info | 2146 | check info |
1883 | print result, msg | 2147 | print result, msg |
1884 | </pre> | 2148 | </pre> |
@@ -2037,7 +2301,7 @@ list_with_one_element = [ 1, ] | |||
2037 | 2301 | ||
2038 | ## 推导式 | 2302 | ## 推导式 |
2039 | 2303 | ||
2040 | 推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生Lua表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许您在每次遍历时设置新表格的键和值。 | 2304 | 推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生Lua表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。 |
2041 | 2305 | ||
2042 | ### 列表推导式 | 2306 | ### 列表推导式 |
2043 | 2307 | ||
@@ -2057,13 +2321,11 @@ doubled = [item * 2 for i, item in ipairs items] | |||
2057 | 可以使用when子句筛选新表中包含的项目: | 2321 | 可以使用when子句筛选新表中包含的项目: |
2058 | 2322 | ||
2059 | ```moonscript | 2323 | ```moonscript |
2060 | iter = ipairs items | 2324 | slice = [item for i, item in ipairs items when i > 1 and i < 3] |
2061 | slice = [item for i, item in iter when i > 1 and i < 3] | ||
2062 | ``` | 2325 | ``` |
2063 | <YueDisplay> | 2326 | <YueDisplay> |
2064 | <pre> | 2327 | <pre> |
2065 | iter = ipairs items | 2328 | slice = [item for i, item in ipairs items when i > 1 and i < 3] |
2066 | slice = [item for i, item in iter when i > 1 and i < 3] | ||
2067 | </pre> | 2329 | </pre> |
2068 | </YueDisplay> | 2330 | </YueDisplay> |
2069 | 2331 | ||
@@ -2212,6 +2474,45 @@ slice = [item for item in *items[,,2]] | |||
2212 | </pre> | 2474 | </pre> |
2213 | </YueDisplay> | 2475 | </YueDisplay> |
2214 | 2476 | ||
2477 | 最小和最大边界都可以是负数,使用负数意味着边界是从表的末尾开始计算的。 | ||
2478 | |||
2479 | ```moonscript | ||
2480 | -- 取最后4个元素 | ||
2481 | slice = [item for item in *items[-4,-1]] | ||
2482 | ``` | ||
2483 | <YueDisplay> | ||
2484 | <pre> | ||
2485 | -- 取最后4个元素 | ||
2486 | slice = [item for item in *items[-4,-1]] | ||
2487 | </pre> | ||
2488 | </YueDisplay> | ||
2489 | |||
2490 | 切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。 | ||
2491 | |||
2492 | ```moonscript | ||
2493 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
2494 | ``` | ||
2495 | <YueDisplay> | ||
2496 | <pre> | ||
2497 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
2498 | </pre> | ||
2499 | </YueDisplay> | ||
2500 | |||
2501 | #### 切片表达式 | ||
2502 | |||
2503 | 切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。 | ||
2504 | |||
2505 | ```moonscript | ||
2506 | -- 取第2和第4个元素作为新的列表 | ||
2507 | sub_list = items[2, 4] | ||
2508 | ``` | ||
2509 | <YueDisplay> | ||
2510 | <pre> | ||
2511 | -- 取第2和第4个元素作为新的列表 | ||
2512 | sub_list = items[2, 4] | ||
2513 | </pre> | ||
2514 | </YueDisplay> | ||
2515 | |||
2215 | ## for 循环 | 2516 | ## for 循环 |
2216 | 2517 | ||
2217 | Lua中有两种for循环形式,数字型和通用型: | 2518 | Lua中有两种for循环形式,数字型和通用型: |
@@ -2288,9 +2589,24 @@ doubled_evens = for i = 1, 20 | |||
2288 | </pre> | 2589 | </pre> |
2289 | </YueDisplay> | 2590 | </YueDisplay> |
2290 | 2591 | ||
2291 | 您还可以结合for循环表达式与continue语句来过滤值。 | 2592 | 此外,for循环还支持带返回值的break语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。 |
2292 | 2593 | ||
2293 | 注意出现在函数体末尾的for循环,不会被当作是一个表达式,并将循环结果累积到一个列表中作为返回值(相反,函数将返回nil)。如果要函数末尾的循环转换为列表表达式,可以使用返回语句加for循环表达式。 | 2594 | 例如,查找第一个大于10的数字: |
2595 | |||
2596 | ```moonscript | ||
2597 | first_large = for n in *numbers | ||
2598 | break n if n > 10 | ||
2599 | ``` | ||
2600 | <YueDisplay> | ||
2601 | <pre> | ||
2602 | first_large = for n in *numbers | ||
2603 | break n if n > 10 | ||
2604 | </pre> | ||
2605 | </YueDisplay> | ||
2606 | |||
2607 | 你还可以结合for循环表达式与continue语句来过滤值。 | ||
2608 | |||
2609 | 注意出现在函数体末尾的for循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加for循环表达式。 | ||
2294 | 2610 | ||
2295 | ```moonscript | 2611 | ```moonscript |
2296 | func_a = -> for i = 1, 10 do print i | 2612 | func_a = -> for i = 1, 10 do print i |
@@ -2515,7 +2831,7 @@ print "你真幸运!" unless math.random! > 0.1 | |||
2515 | 2831 | ||
2516 | ### 范围表达式 | 2832 | ### 范围表达式 |
2517 | 2833 | ||
2518 | 您可以使用范围表达式来编写进行范围检查的代码。 | 2834 | 你可以使用范围表达式来编写进行范围检查的代码。 |
2519 | 2835 | ||
2520 | ```moonscript | 2836 | ```moonscript |
2521 | a = 5 | 2837 | a = 5 |
@@ -2588,28 +2904,26 @@ reader\parse_line! until reader\eof! | |||
2588 | 2904 | ||
2589 | ## switch 语句 | 2905 | ## switch 语句 |
2590 | 2906 | ||
2591 | switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。 | 2907 | switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。switch语句中也可以使用赋值表达式来储存临时变量值。 |
2592 | 2908 | ||
2593 | ```moonscript | 2909 | ```moonscript |
2594 | name = "Dan" | 2910 | switch name := "Dan" |
2595 | switch name | ||
2596 | when "Robert" | 2911 | when "Robert" |
2597 | print "你是Robert" | 2912 | print "你是Robert" |
2598 | when "Dan", "Daniel" | 2913 | when "Dan", "Daniel" |
2599 | print "你的名字是Dan" | 2914 | print "你的名字是Dan" |
2600 | else | 2915 | else |
2601 | print "我不知道你的名字" | 2916 | print "我不认识你,你的名字是#{name}" |
2602 | ``` | 2917 | ``` |
2603 | <YueDisplay> | 2918 | <YueDisplay> |
2604 | <pre> | 2919 | <pre> |
2605 | name = "Dan" | 2920 | switch name := "Dan" |
2606 | switch name | ||
2607 | when "Robert" | 2921 | when "Robert" |
2608 | print "你是Robert" | 2922 | print "你是Robert" |
2609 | when "Dan", "Daniel" | 2923 | when "Dan", "Daniel" |
2610 | print "你的名字是Dan" | 2924 | print "你的名字是Dan" |
2611 | else | 2925 | else |
2612 | print "我不知道你的名字" | 2926 | print "我不认识你,你的名字是#{name}" |
2613 | </pre> | 2927 | </pre> |
2614 | </YueDisplay> | 2928 | </YueDisplay> |
2615 | 2929 | ||
@@ -2686,7 +3000,7 @@ else | |||
2686 | </pre> | 3000 | </pre> |
2687 | </YueDisplay> | 3001 | </YueDisplay> |
2688 | 3002 | ||
2689 | 值得注意的是,在生成Lua代码时,我们要做检查的目标变量会放在==表达式的右侧。当您希望给when子句的比较对象定义一个\_\_eq元方法来重载判断逻辑时,可能会有用。 | 3003 | 值得注意的是,在生成Lua代码时,我们要做检查的目标变量会放在==表达式的右侧。当你希望给when子句的比较对象定义一个\_\_eq元方法来重载判断逻辑时,可能会有用。 |
2690 | 3004 | ||
2691 | ### 表格匹配 | 3005 | ### 表格匹配 |
2692 | 3006 | ||
@@ -2746,9 +3060,126 @@ switch item | |||
2746 | </pre> | 3060 | </pre> |
2747 | </YueDisplay> | 3061 | </YueDisplay> |
2748 | 3062 | ||
3063 | 你也可以匹配数组元素、表格字段,甚至使用数组或表格字面量来匹配嵌套的结构。 | ||
3064 | |||
3065 | 匹配数组元素。 | ||
3066 | |||
3067 | ```moonscript | ||
3068 | switch tb | ||
3069 | when [1, 2, 3] | ||
3070 | print "1, 2, 3" | ||
3071 | when [1, b, 3] | ||
3072 | print "1, #{b}, 3" | ||
3073 | when [1, 2, b = 3] -- 变量b有默认值 | ||
3074 | print "1, 2, #{b}" | ||
3075 | ``` | ||
3076 | <YueDisplay> | ||
3077 | <pre> | ||
3078 | switch tb | ||
3079 | when [1, 2, 3] | ||
3080 | print "1, 2, 3" | ||
3081 | when [1, b, 3] | ||
3082 | print "1, #{b}, 3" | ||
3083 | when [1, 2, b = 3] -- 变量b有默认值 | ||
3084 | print "1, 2, #{b}" | ||
3085 | </pre> | ||
3086 | </YueDisplay> | ||
3087 | |||
3088 | 匹配表格字段。 | ||
3089 | |||
3090 | ```moonscript | ||
3091 | switch tb | ||
3092 | when success: true, :result | ||
3093 | print "成功", result | ||
3094 | when success: false | ||
3095 | print "失败", result | ||
3096 | else | ||
3097 | print "无效值" | ||
3098 | ``` | ||
3099 | <YueDisplay> | ||
3100 | <pre> | ||
3101 | switch tb | ||
3102 | when success: true, :result | ||
3103 | print "成功", result | ||
3104 | when success: false | ||
3105 | print "失败", result | ||
3106 | else | ||
3107 | print "无效值" | ||
3108 | </pre> | ||
3109 | </YueDisplay> | ||
3110 | |||
3111 | 匹配嵌套的表格结构。 | ||
3112 | |||
3113 | ```moonscript | ||
3114 | switch tb | ||
3115 | when data: {type: "success", :content} | ||
3116 | print "成功", content | ||
3117 | when data: {type: "error", :content} | ||
3118 | print "失败", content | ||
3119 | else | ||
3120 | print "无效值" | ||
3121 | ``` | ||
3122 | <YueDisplay> | ||
3123 | <pre> | ||
3124 | switch tb | ||
3125 | when data: {type: "success", :content} | ||
3126 | print "成功", content | ||
3127 | when data: {type: "error", :content} | ||
3128 | print "失败", content | ||
3129 | else | ||
3130 | print "无效值" | ||
3131 | </pre> | ||
3132 | </YueDisplay> | ||
3133 | |||
3134 | 匹配表格数组。 | ||
3135 | |||
3136 | ```moonscript | ||
3137 | switch tb | ||
3138 | when [ | ||
3139 | {a: 1, b: 2} | ||
3140 | {a: 3, b: 4} | ||
3141 | {a: 5, b: 6} | ||
3142 | fourth | ||
3143 | ] | ||
3144 | print "匹配成功", fourth | ||
3145 | ``` | ||
3146 | <YueDisplay> | ||
3147 | <pre> | ||
3148 | switch tb | ||
3149 | when [ | ||
3150 | {a: 1, b: 2} | ||
3151 | {a: 3, b: 4} | ||
3152 | {a: 5, b: 6} | ||
3153 | fourth | ||
3154 | ] | ||
3155 | print "匹配成功", fourth | ||
3156 | </pre> | ||
3157 | </YueDisplay> | ||
3158 | |||
3159 | 匹配一个列表并捕获特定范围内的元素。 | ||
3160 | |||
3161 | ```moonscript | ||
3162 | segments = ["admin", "users", "logs", "view"] | ||
3163 | switch segments | ||
3164 | when [...groups, resource, action] | ||
3165 | print "Group:", groups -- 打印: {"admin", "users"} | ||
3166 | print "Resource:", resource -- 打印: "logs" | ||
3167 | print "Action:", action -- 打印: "view" | ||
3168 | ``` | ||
3169 | <YueDisplay> | ||
3170 | <pre> | ||
3171 | segments = ["admin", "users", "logs", "view"] | ||
3172 | switch segments | ||
3173 | when [...groups, resource, action] | ||
3174 | print "Group:", groups -- 打印: {"admin", "users"} | ||
3175 | print "Resource:", resource -- 打印: "logs" | ||
3176 | print "Action:", action -- 打印: "view" | ||
3177 | </pre> | ||
3178 | </YueDisplay> | ||
3179 | |||
2749 | ## 面向对象编程 | 3180 | ## 面向对象编程 |
2750 | 3181 | ||
2751 | 在以下的示例中,月之脚本生成的Lua代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果您想知道关于面向对象功能的实现细节,再查看Lua代码。 | 3182 | 在以下的示例中,月之脚本生成的Lua代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看Lua代码。 |
2752 | 3183 | ||
2753 | 一个简单的类: | 3184 | 一个简单的类: |
2754 | 3185 | ||
@@ -3216,7 +3647,7 @@ x = class | |||
3216 | 3647 | ||
3217 | ### 类混合 | 3648 | ### 类混合 |
3218 | 3649 | ||
3219 | 您可以通过使用 `using` 关键字来实现类混合。这意味着您可以从一个普通 Lua 表格或已定义的类对象中,复制函数到您创建的新类中。当您使用普通 Lua 表格进行类混合时,您有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当您从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 | 3650 | 你可以通过使用 `using` 关键字来实现类混合。这意味着你可以从一个普通 Lua 表格或已定义的类对象中,复制函数到你创建的新类中。当你使用普通 Lua 表格进行类混合时,你有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当你从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 |
3220 | 3651 | ||
3221 | ```moonscript | 3652 | ```moonscript |
3222 | MyIndex = __index: var: 1 | 3653 | MyIndex = __index: var: 1 |
@@ -3318,22 +3749,22 @@ me = create_person "Leaf", [dad, mother, sister] | |||
3318 | 3749 | ||
3319 | 在此用法中,with可以被视为K组合子(k-combinator)的一种特殊形式。 | 3750 | 在此用法中,with可以被视为K组合子(k-combinator)的一种特殊形式。 |
3320 | 3751 | ||
3321 | 如果给表达式另外起一个名称的话,with语句中的表达式也可以是一个赋值语句。 | 3752 | 如果你想给表达式另外起一个名称的话,with语句中的表达式也可以是一个赋值语句。 |
3322 | 3753 | ||
3323 | ```moonscript | 3754 | ```moonscript |
3324 | with str = "你好" | 3755 | with str := "你好" |
3325 | print "原始:", str | 3756 | print "原始:", str |
3326 | print "大写:", \upper! | 3757 | print "大写:", \upper! |
3327 | ``` | 3758 | ``` |
3328 | <YueDisplay> | 3759 | <YueDisplay> |
3329 | <pre> | 3760 | <pre> |
3330 | with str = "你好" | 3761 | with str := "你好" |
3331 | print "原始:", str | 3762 | print "原始:", str |
3332 | print "大写:", \upper! | 3763 | print "大写:", \upper! |
3333 | </pre> | 3764 | </pre> |
3334 | </YueDisplay> | 3765 | </YueDisplay> |
3335 | 3766 | ||
3336 | 在with语句中可用`[]`访问特殊键。 | 3767 | 你以 `with` 语句中使用 `[]` 访问特殊键。 |
3337 | 3768 | ||
3338 | ```moonscript | 3769 | ```moonscript |
3339 | with tb | 3770 | with tb |
@@ -3356,6 +3787,19 @@ with tb | |||
3356 | </pre> | 3787 | </pre> |
3357 | </YueDisplay> | 3788 | </YueDisplay> |
3358 | 3789 | ||
3790 | `with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。 | ||
3791 | |||
3792 | ```moonscript | ||
3793 | with? obj | ||
3794 | print obj.name | ||
3795 | ``` | ||
3796 | <YueDisplay> | ||
3797 | <pre> | ||
3798 | with? obj | ||
3799 | print obj.name | ||
3800 | </pre> | ||
3801 | </YueDisplay> | ||
3802 | |||
3359 | ## do 语句 | 3803 | ## do 语句 |
3360 | 3804 | ||
3361 | 当用作语句时,do语句的作用就像在Lua中差不多。 | 3805 | 当用作语句时,do语句的作用就像在Lua中差不多。 |
@@ -3375,7 +3819,7 @@ print var -- 这里是nil | |||
3375 | </pre> | 3819 | </pre> |
3376 | </YueDisplay> | 3820 | </YueDisplay> |
3377 | 3821 | ||
3378 | 月之脚本的 **do** 也可以用作表达式。允许您将多行代码的处理合并为一个表达式,并将do语句代码块的最后一个语句作为表达式返回的结果。 | 3822 | 月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将do语句代码块的最后一个语句作为表达式返回的结果。 |
3379 | 3823 | ||
3380 | ```moonscript | 3824 | ```moonscript |
3381 | counter = do | 3825 | counter = do |
@@ -4334,8 +4778,8 @@ simplified: boolean | |||
4334 | 4778 | ||
4335 | 版权 (c) 2017-2025 李瑾 \<dragon-fly@qq.com\> | 4779 | 版权 (c) 2017-2025 李瑾 \<dragon-fly@qq.com\> |
4336 | 4780 | ||
4337 | 特此免费授予任何获得本软件副本和相关文档文件(下称“软件”)的人不受限制地处置该软件的权利,包括不受限制地使用、复制、修改、合并、发布、分发、转授许可和/或出售该软件副本,以及再授权被配发了本软件的人如上的权利,须在下列条件下: | 4781 | 特此免费授予任何获得本软件副本和相关文档文件(下称“软件”)的人不受限制地处置该软件的权利,包括不受限制地使用、复制、修改、合并、发布、分发、转授许可和/或出售该软件副本,以及再授权被配发了本软件的人如上的权利,须在下列条件下: |
4338 | 上述版权声明和本许可声明应包含在该软件的所有副本或实质成分中。 | 4782 | 上述版权声明和本许可声明应包含在该软件的所有副本或实质成分中。 |
4339 | 本软件是“如此”提供的,没有任何形式的明示或暗示的保证,包括但不限于对适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有人都不对任何索赔、损害或其他责任负责,无论这些追责来自合同、侵权或其它行为中,还是产生于、源于或有关于本软件以及本软件的使用或其它处置。 | 4783 | 本软件是“如此”提供的,没有任何形式的明示或暗示的保证,包括但不限于对适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有人都不对任何索赔、损害或其他责任负责,无论这些追责来自合同、侵权或其它行为中,还是产生于、源于或有关于本软件以及本软件的使用或其它处置。 |
4340 | 4784 | ||
4341 | <CompilerModal /> | 4785 | <CompilerModal /> |