diff options
Diffstat (limited to 'doc/docs/zh')
| -rwxr-xr-x | doc/docs/zh/README.md | 2 | ||||
| -rwxr-xr-x | doc/docs/zh/doc/README.md | 1177 |
2 files changed, 958 insertions, 221 deletions
diff --git a/doc/docs/zh/README.md b/doc/docs/zh/README.md index f5c9811..05b2069 100755 --- a/doc/docs/zh/README.md +++ b/doc/docs/zh/README.md | |||
| @@ -3,6 +3,6 @@ home: true | |||
| 3 | heroImage: /image/yuescript.svg | 3 | heroImage: /image/yuescript.svg |
| 4 | actionText: 快速上手 → | 4 | actionText: 快速上手 → |
| 5 | actionLink: /zh/doc/ | 5 | actionLink: /zh/doc/ |
| 6 | footer: MIT Licensed | Copyright © 2017-2025 Li Jin | 6 | footer: MIT Licensed | Copyright © 2017-2026 Li Jin |
| 7 | --- | 7 | --- |
| 8 | 8 | ||
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md index 754566c..43713fe 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
| @@ -9,26 +9,36 @@ 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 | ||
| 14 | Yue(月)是中文中“月亮”的名称。 | 14 | Yue(月)是中文中“月亮”的名称。 |
| 15 | 15 | ||
| 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 |
| @@ -89,7 +109,7 @@ export 🌛 = "月之脚本" | |||
| 89 | 109 | ||
| 90 | * **Lua 模块** | 110 | * **Lua 模块** |
| 91 | 111 | ||
| 92 |  安装 [luarocks](https://luarocks.org),一个Lua模块的包管理器。然后作为Lua模块和可执行文件安装它: | 112 |  安装 [luarocks](https://luarocks.org),一个 Lua 模块的包管理器。然后作为 Lua 模块和可执行文件安装它: |
| 93 | 113 | ||
| 94 | ``` | 114 | ``` |
| 95 | > luarocks install yuescript | 115 | > luarocks install yuescript |
| @@ -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 | ||
| @@ -130,16 +150,16 @@ export 🌛 = "月之脚本" | |||
| 130 | 150 | ||
| 131 | ### Lua 模块 | 151 | ### Lua 模块 |
| 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,8 +171,8 @@ 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") |
| 158 | local codes, err, globals = yue.to_lua([[ | 178 | local codes, err, globals = yue.to_lua([[ |
| @@ -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}]" |
| @@ -387,16 +407,16 @@ print $LINE -- 获取当前代码行数:2 | |||
| 387 | 407 | ||
| 388 | ```moonscript | 408 | ```moonscript |
| 389 | macro Enum = (...) -> | 409 | macro Enum = (...) -> |
| 390 | items = {...} | 410 | items = {...} |
| 391 | itemSet = {item, true for item in *items} | 411 | itemSet = {item, true for item in *items} |
| 392 | (item) -> | 412 | (item) -> |
| 393 | error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item] | 413 | error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item] |
| 394 | "\"#{item}\"" | 414 | "\"#{item}\"" |
| 395 | 415 | ||
| 396 | macro BodyType = $Enum( | 416 | macro BodyType = $Enum( |
| 397 | Static | 417 | Static |
| 398 | Dynamic | 418 | Dynamic |
| 399 | Kinematic | 419 | Kinematic |
| 400 | ) | 420 | ) |
| 401 | 421 | ||
| 402 | print "有效的枚举类型:", $BodyType Static | 422 | print "有效的枚举类型:", $BodyType Static |
| @@ -405,16 +425,16 @@ print "有效的枚举类型:", $BodyType Static | |||
| 405 | <YueDisplay> | 425 | <YueDisplay> |
| 406 | <pre> | 426 | <pre> |
| 407 | macro Enum = (...) -> | 427 | macro Enum = (...) -> |
| 408 | items = {...} | 428 | items = {...} |
| 409 | itemSet = {item, true for item in *items} | 429 | itemSet = {item, true for item in *items} |
| 410 | (item) -> | 430 | (item) -> |
| 411 | error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item] | 431 | error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item] |
| 412 | "\"#{item}\"" | 432 | "\"#{item}\"" |
| 413 | 433 | ||
| 414 | macro BodyType = $Enum( | 434 | macro BodyType = $Enum( |
| 415 | Static | 435 | Static |
| 416 | Dynamic | 436 | Dynamic |
| 417 | Kinematic | 437 | Kinematic |
| 418 | ) | 438 | ) |
| 419 | 439 | ||
| 420 | print "有效的枚举类型:", $BodyType Static | 440 | print "有效的枚举类型:", $BodyType Static |
| @@ -422,9 +442,57 @@ 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!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 |
| 428 | 496 | ||
| 429 | ```moonscript | 497 | ```moonscript |
| 430 | tb\func! if tb ~= nil | 498 | tb\func! if tb ~= nil |
| @@ -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 |
| @@ -464,56 +532,56 @@ print 1 <= a <= 10 | |||
| 464 | 532 | ||
| 465 | ```moonscript | 533 | ```moonscript |
| 466 | v = (x) -> | 534 | v = (x) -> |
| 467 | print x | 535 | print x |
| 468 | x | 536 | x |
| 469 | 537 | ||
| 470 | print v(1) < v(2) <= v(3) | 538 | print v(1) < v(2) <= v(3) |
| 471 | --[[ | 539 | --[[ |
| 472 | 输出: | 540 | 输出: |
| 473 | 2 | 541 | 2 |
| 474 | 1 | 542 | 1 |
| 475 | 3 | 543 | 3 |
| 476 | true | 544 | true |
| 477 | ]] | 545 | ]] |
| 478 | 546 | ||
| 479 | print v(1) > v(2) <= v(3) | 547 | print v(1) > v(2) <= v(3) |
| 480 | --[[ | 548 | --[[ |
| 481 | 输出: | 549 | 输出: |
| 482 | 2 | 550 | 2 |
| 483 | 1 | 551 | 1 |
| 484 | false | 552 | false |
| 485 | ]] | 553 | ]] |
| 486 | ``` | 554 | ``` |
| 487 | <YueDisplay> | 555 | <YueDisplay> |
| 488 | <pre> | 556 | <pre> |
| 489 | v = (x) -> | 557 | v = (x) -> |
| 490 | print x | 558 | print x |
| 491 | x | 559 | x |
| 492 | 560 | ||
| 493 | print v(1) < v(2) <= v(3) | 561 | print v(1) < v(2) <= v(3) |
| 494 | --[[ | 562 | --[[ |
| 495 | 输出: | 563 | 输出: |
| 496 | 2 | 564 | 2 |
| 497 | 1 | 565 | 1 |
| 498 | 3 | 566 | 3 |
| 499 | true | 567 | true |
| 500 | ]] | 568 | ]] |
| 501 | 569 | ||
| 502 | print v(1) > v(2) <= v(3) | 570 | print v(1) > v(2) <= v(3) |
| 503 | --[[ | 571 | --[[ |
| 504 | 输出: | 572 | 输出: |
| 505 | 2 | 573 | 2 |
| 506 | 1 | 574 | 1 |
| 507 | false | 575 | false |
| 508 | ]] | 576 | ]] |
| 509 | </pre> | 577 | </pre> |
| 510 | </YueDisplay> | 578 | </YueDisplay> |
| 511 | 579 | ||
| 512 | 在上面的例子里,中间的表达式`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` 运算符来做连接。 |
| 513 | 581 | ||
| 514 | ### 表追加 | 582 | ### 表追加 |
| 515 | 583 | ||
| 516 | **[] =** 操作符用于向Lua表的最后插入值。 | 584 | **[] =** 操作符用于向 Lua 表的最后插入值。 |
| 517 | 585 | ||
| 518 | ```moonscript | 586 | ```moonscript |
| 519 | tab = [] | 587 | tab = [] |
| @@ -526,19 +594,36 @@ tab[] = "Value" | |||
| 526 | </pre> | 594 | </pre> |
| 527 | </YueDisplay> | 595 | </YueDisplay> |
| 528 | 596 | ||
| 597 | 你还可以使用展开操作符 `...` 来将一个列表中的所有元素追加到另一个列表中: | ||
| 598 | |||
| 599 | ```moonscript | ||
| 600 | tbA = [1, 2, 3] | ||
| 601 | tbB = [4, 5, 6] | ||
| 602 | tbA[] = ...tbB | ||
| 603 | -- tbA 现在为 [1, 2, 3, 4, 5, 6] | ||
| 604 | ``` | ||
| 605 | <YueDisplay> | ||
| 606 | <pre> | ||
| 607 | tbA = [1, 2, 3] | ||
| 608 | tbB = [4, 5, 6] | ||
| 609 | tbA[] = ...tbB | ||
| 610 | -- tbA 现在为 [1, 2, 3, 4, 5, 6] | ||
| 611 | </pre> | ||
| 612 | </YueDisplay> | ||
| 613 | |||
| 529 | ### 表扩展 | 614 | ### 表扩展 |
| 530 | 615 | ||
| 531 | 您可以使用前置 `...` 操作符在Lua表中插入数组表或哈希表。 | 616 | 你可以使用前置 `...` 操作符在 Lua 表中插入数组表或哈希表。 |
| 532 | 617 | ||
| 533 | ```moonscript | 618 | ```moonscript |
| 534 | parts = | 619 | parts = |
| 535 | * "shoulders" | 620 | * "shoulders" |
| 536 | * "knees" | 621 | * "knees" |
| 537 | lyrics = | 622 | lyrics = |
| 538 | * "head" | 623 | * "head" |
| 539 | * ...parts | 624 | * ...parts |
| 540 | * "and" | 625 | * "and" |
| 541 | * "toes" | 626 | * "toes" |
| 542 | 627 | ||
| 543 | copy = {...other} | 628 | copy = {...other} |
| 544 | 629 | ||
| @@ -549,13 +634,13 @@ merge = {...a, ...b} | |||
| 549 | <YueDisplay> | 634 | <YueDisplay> |
| 550 | <pre> | 635 | <pre> |
| 551 | parts = | 636 | parts = |
| 552 | * "shoulders" | 637 | * "shoulders" |
| 553 | * "knees" | 638 | * "knees" |
| 554 | lyrics = | 639 | lyrics = |
| 555 | * "head" | 640 | * "head" |
| 556 | * ...parts | 641 | * ...parts |
| 557 | * "and" | 642 | * "and" |
| 558 | * "toes" | 643 | * "toes" |
| 559 | 644 | ||
| 560 | copy = {...other} | 645 | copy = {...other} |
| 561 | 646 | ||
| @@ -565,12 +650,29 @@ merge = {...a, ...b} | |||
| 565 | </pre> | 650 | </pre> |
| 566 | </YueDisplay> | 651 | </YueDisplay> |
| 567 | 652 | ||
| 653 | ### 表反向索引 | ||
| 654 | |||
| 655 | 你可以使用 **#** 操作符来反向索引表中的元素。 | ||
| 656 | |||
| 657 | ```moonscript | ||
| 658 | last = data.items[#] | ||
| 659 | second_last = data.items[#-1] | ||
| 660 | data.items[#] = 1 | ||
| 661 | ``` | ||
| 662 | <YueDisplay> | ||
| 663 | <pre> | ||
| 664 | last = data.items[#] | ||
| 665 | second_last = data.items[#-1] | ||
| 666 | data.items[#] = 1 | ||
| 667 | </pre> | ||
| 668 | </YueDisplay> | ||
| 669 | |||
| 568 | ### 元表 | 670 | ### 元表 |
| 569 | 671 | ||
| 570 | **<>** 操作符可提供元表操作的快捷方式。 | 672 | **<>** 操作符可提供元表操作的快捷方式。 |
| 571 | 673 | ||
| 572 | * **元表创建** | 674 | * **元表创建** |
| 573 | 使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的Lua表。 | 675 | 使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的 Lua 表。 |
| 574 | 676 | ||
| 575 | ```moonscript | 677 | ```moonscript |
| 576 | mt = {} | 678 | mt = {} |
| @@ -605,7 +707,7 @@ close _ = <close>: -> print "超出范围" | |||
| 605 | </pre> | 707 | </pre> |
| 606 | </YueDisplay> | 708 | </YueDisplay> |
| 607 | 709 | ||
| 608 | * **元表访问** | 710 | * **元表访问** |
| 609 | 使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。 | 711 | 使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。 |
| 610 | 712 | ||
| 611 | ```moonscript | 713 | ```moonscript |
| @@ -629,7 +731,7 @@ print tb.item | |||
| 629 | </pre> | 731 | </pre> |
| 630 | </YueDisplay> | 732 | </YueDisplay> |
| 631 | 733 | ||
| 632 | * **元表解构** | 734 | * **元表解构** |
| 633 | 使用被 **<>** 包围的元方法键解构元表。 | 735 | 使用被 **<>** 包围的元方法键解构元表。 |
| 634 | 736 | ||
| 635 | ```moonscript | 737 | ```moonscript |
| @@ -680,7 +782,7 @@ with? io.open "test.txt", "w" | |||
| 680 | 782 | ||
| 681 | ### 管道 | 783 | ### 管道 |
| 682 | 784 | ||
| 683 | 与其使用一系列嵌套的函数调用,您还可以考虑使用运算符 **|>** 来传递值。 | 785 | 与其使用一系列嵌套的函数调用,你还可以考虑使用运算符 **|>** 来传递值。 |
| 684 | 786 | ||
| 685 | ```moonscript | 787 | ```moonscript |
| 686 | "你好" |> print | 788 | "你好" |> print |
| @@ -712,7 +814,7 @@ readFile "example.txt" | |||
| 712 | 814 | ||
| 713 | ### 空值合并 | 815 | ### 空值合并 |
| 714 | 816 | ||
| 715 | 如果其左操作数不是**nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非nil的值,**??** 运算符将不再计算其右操作数。 | 817 | 如果其左操作数不是 **nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非 nil 的值,**??** 运算符将不再计算其右操作数。 |
| 716 | ```moonscript | 818 | ```moonscript |
| 717 | local a, b, c, d | 819 | local a, b, c, d |
| 718 | a = b ?? c ?? d | 820 | a = b ?? c ?? d |
| @@ -731,67 +833,87 @@ a ??= false | |||
| 731 | 833 | ||
| 732 | ### 隐式对象 | 834 | ### 隐式对象 |
| 733 | 835 | ||
| 734 | 您可以在表格块内使用符号 **\*** 开始编写一系列隐式结构。如果您正在创建隐式对象,对象的字段必须具有相同的缩进。 | 836 | 你可以在表格块内使用符号 **\*** 或是 **-** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。 |
| 837 | |||
| 735 | ```moonscript | 838 | ```moonscript |
| 839 | -- 赋值时使用隐式对象 | ||
| 736 | list = | 840 | list = |
| 737 | * 1 | 841 | * 1 |
| 738 | * 2 | 842 | * 2 |
| 739 | * 3 | 843 | * 3 |
| 740 | 844 | ||
| 845 | -- 函数调用时使用隐式对象 | ||
| 741 | func | 846 | func |
| 742 | * 1 | 847 | * 1 |
| 743 | * 2 | 848 | * 2 |
| 744 | * 3 | 849 | * 3 |
| 745 | 850 | ||
| 851 | -- 返回时使用隐式对象 | ||
| 852 | f = -> | ||
| 853 | return | ||
| 854 | * 1 | ||
| 855 | * 2 | ||
| 856 | * 3 | ||
| 857 | |||
| 858 | -- 表格时使用隐式对象 | ||
| 746 | tb = | 859 | tb = |
| 747 | name: "abc" | 860 | name: "abc" |
| 748 | 861 | ||
| 749 | values: | 862 | values: |
| 750 | * "a" | 863 | - "a" |
| 751 | * "b" | 864 | - "b" |
| 752 | * "c" | 865 | - "c" |
| 753 | 866 | ||
| 754 | objects: | 867 | objects: |
| 755 | * name: "a" | 868 | - name: "a" |
| 756 | value: 1 | 869 | value: 1 |
| 757 | func: => @value + 1 | 870 | func: => @value + 1 |
| 758 | tb: | 871 | tb: |
| 759 | fieldA: 1 | 872 | fieldA: 1 |
| 760 | 873 | ||
| 761 | * name: "b" | 874 | - name: "b" |
| 762 | value: 2 | 875 | value: 2 |
| 763 | func: => @value + 2 | 876 | func: => @value + 2 |
| 764 | tb: { } | 877 | tb: { } |
| 765 | |||
| 766 | ``` | 878 | ``` |
| 767 | <YueDisplay> | 879 | <YueDisplay> |
| 768 | <pre> | 880 | <pre> |
| 881 | -- 赋值时使用隐式对象 | ||
| 769 | list = | 882 | list = |
| 770 | * 1 | 883 | * 1 |
| 771 | * 2 | 884 | * 2 |
| 772 | * 3 | 885 | * 3 |
| 773 | 886 | ||
| 887 | -- 函数调用时使用隐式对象 | ||
| 774 | func | 888 | func |
| 775 | * 1 | 889 | * 1 |
| 776 | * 2 | 890 | * 2 |
| 777 | * 3 | 891 | * 3 |
| 778 | 892 | ||
| 893 | -- 返回时使用隐式对象 | ||
| 894 | f = -> | ||
| 895 | return | ||
| 896 | * 1 | ||
| 897 | * 2 | ||
| 898 | * 3 | ||
| 899 | |||
| 900 | -- 表格时使用隐式对象 | ||
| 779 | tb = | 901 | tb = |
| 780 | name: "abc" | 902 | name: "abc" |
| 781 | 903 | ||
| 782 | values: | 904 | values: |
| 783 | * "a" | 905 | - "a" |
| 784 | * "b" | 906 | - "b" |
| 785 | * "c" | 907 | - "c" |
| 786 | 908 | ||
| 787 | objects: | 909 | objects: |
| 788 | * name: "a" | 910 | - name: "a" |
| 789 | value: 1 | 911 | value: 1 |
| 790 | func: => @value + 1 | 912 | func: => @value + 1 |
| 791 | tb: | 913 | tb: |
| 792 | fieldA: 1 | 914 | fieldA: 1 |
| 793 | 915 | ||
| 794 | * name: "b" | 916 | - name: "b" |
| 795 | value: 2 | 917 | value: 2 |
| 796 | func: => @value + 2 | 918 | func: => @value + 2 |
| 797 | tb: { } | 919 | tb: { } |
| @@ -855,11 +977,67 @@ do | |||
| 855 | </pre> | 977 | </pre> |
| 856 | </YueDisplay> | 978 | </YueDisplay> |
| 857 | 979 | ||
| 980 | ### 导入全局变量 | ||
| 981 | |||
| 982 | 你可以使用 `import` 将指定的全局变量导入到本地变量中。当导入一系列对全局变量的链式访问时,最后一个访问的字段将被赋值给本地变量。 | ||
| 983 | |||
| 984 | ```moonscript | ||
| 985 | do | ||
| 986 | import tostring | ||
| 987 | import table.concat | ||
| 988 | print concat ["a", tostring 1] | ||
| 989 | ``` | ||
| 990 | <YueDisplay> | ||
| 991 | <pre> | ||
| 992 | do | ||
| 993 | import tostring | ||
| 994 | import table.concat | ||
| 995 | print concat ["a", tostring 1] | ||
| 996 | </pre> | ||
| 997 | </YueDisplay> | ||
| 998 | |||
| 999 | #### 自动导入 | ||
| 1000 | |||
| 1001 | 在一个代码块的顶部写 `import global`,会将当前作用域中尚未显式声明或赋值过的变量名,自动导入为本地常量,并在该语句的位置绑定到同名的全局变量。 | ||
| 1002 | |||
| 1003 | 但是在同一作用域中被显式声明为全局的变量不会被自动导入,因此可以继续进行赋值操作。 | ||
| 1004 | |||
| 1005 | ```moonscript | ||
| 1006 | do | ||
| 1007 | import global | ||
| 1008 | print "hello" | ||
| 1009 | math.random 3 | ||
| 1010 | -- print = nil -- 报错:自动导入的全局变量为常量 | ||
| 1011 | |||
| 1012 | do | ||
| 1013 | -- 被显式声明为全局的变量不会被自动导入 | ||
| 1014 | import global | ||
| 1015 | global FLAG | ||
| 1016 | print FLAG | ||
| 1017 | FLAG = 123 | ||
| 1018 | ``` | ||
| 1019 | <YueDisplay> | ||
| 1020 | <pre> | ||
| 1021 | do | ||
| 1022 | import global | ||
| 1023 | print "hello" | ||
| 1024 | math.random 3 | ||
| 1025 | -- print = nil -- 报错:自动导入的全局变量是常量 | ||
| 1026 | |||
| 1027 | do | ||
| 1028 | -- 被显式声明为全局的变量不会被自动导入 | ||
| 1029 | import global | ||
| 1030 | global FLAG | ||
| 1031 | print FLAG | ||
| 1032 | FLAG = 123 | ||
| 1033 | </pre> | ||
| 1034 | </YueDisplay> | ||
| 1035 | |||
| 858 | ### 导出 | 1036 | ### 导出 |
| 859 | 1037 | ||
| 860 | 导出语句提供了一种简洁的方式来定义当前的模块。 | 1038 | 导出语句提供了一种简洁的方式来定义当前的模块。 |
| 861 | 1039 | ||
| 862 | * **命名导出** | 1040 | * **命名导出** |
| 863 | 带命名的导出将定义一个局部变量,并在导出的表中添加一个同名的字段。 | 1041 | 带命名的导出将定义一个局部变量,并在导出的表中添加一个同名的字段。 |
| 864 | 1042 | ||
| 865 | ```moonscript | 1043 | ```moonscript |
| @@ -923,7 +1101,7 @@ export["a-b-c"] = 123 | |||
| 923 | </pre> | 1101 | </pre> |
| 924 | </YueDisplay> | 1102 | </YueDisplay> |
| 925 | 1103 | ||
| 926 | * **未命名导出** | 1104 | * **未命名导出** |
| 927 | 未命名导出会将要导出的目标项目添加到导出表的数组部分。 | 1105 | 未命名导出会将要导出的目标项目添加到导出表的数组部分。 |
| 928 | 1106 | ||
| 929 | ```moonscript | 1107 | ```moonscript |
| @@ -953,7 +1131,7 @@ export with tmp | |||
| 953 | </pre> | 1131 | </pre> |
| 954 | </YueDisplay> | 1132 | </YueDisplay> |
| 955 | 1133 | ||
| 956 | * **默认导出** | 1134 | * **默认导出** |
| 957 | 在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。 | 1135 | 在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。 |
| 958 | 1136 | ||
| 959 | ```moonscript | 1137 | ```moonscript |
| @@ -971,7 +1149,7 @@ export default -> | |||
| 971 | 1149 | ||
| 972 | ## 赋值 | 1150 | ## 赋值 |
| 973 | 1151 | ||
| 974 | 月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过**local**和**global**声明来改变声明变量的作用范围。 | 1152 | 月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过 **local** 和 **global** 声明来改变声明变量的作用范围。 |
| 975 | 1153 | ||
| 976 | ```moonscript | 1154 | ```moonscript |
| 977 | hello = "world" | 1155 | hello = "world" |
| @@ -1100,9 +1278,9 @@ do | |||
| 1100 | 1278 | ||
| 1101 | ## 解构赋值 | 1279 | ## 解构赋值 |
| 1102 | 1280 | ||
| 1103 | 解构赋值是一种快速从Lua表中按名称或基于数组中的位置提取值的方法。 | 1281 | 解构赋值是一种快速从 Lua 表中按名称或基于数组中的位置提取值的方法。 |
| 1104 | 1282 | ||
| 1105 | 通常当你看到一个字面量的Lua表,比如{1,2,3},它位于赋值的右侧,因为它是一个值。解构赋值语句的写法就是交换了字面量Lua表的角色,并将其放在赋值语句的左侧。 | 1283 | 通常当你看到一个字面量的 Lua 表,比如 `{1,2,3}`,它位于赋值的右侧,因为它是一个值。解构赋值语句的写法就是交换了字面量 Lua 表的角色,并将其放在赋值语句的左侧。 |
| 1106 | 1284 | ||
| 1107 | 最好是通过示例来解释。以下是如何从表格中解包前两个值的方法: | 1285 | 最好是通过示例来解释。以下是如何从表格中解包前两个值的方法: |
| 1108 | 1286 | ||
| @@ -1201,7 +1379,7 @@ print first, second, color | |||
| 1201 | </pre> | 1379 | </pre> |
| 1202 | </YueDisplay> | 1380 | </YueDisplay> |
| 1203 | 1381 | ||
| 1204 | 有时候我们会需要从Lua表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: | 1382 | 有时候我们会需要从 Lua 表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: |
| 1205 | 1383 | ||
| 1206 | ```moonscript | 1384 | ```moonscript |
| 1207 | {:concat, :insert} = table | 1385 | {:concat, :insert} = table |
| @@ -1223,7 +1401,7 @@ print first, second, color | |||
| 1223 | </pre> | 1401 | </pre> |
| 1224 | </YueDisplay> | 1402 | </YueDisplay> |
| 1225 | 1403 | ||
| 1226 | 在进行解构时,您可以指定默认值,如: | 1404 | 在进行解构时,你可以指定默认值,如: |
| 1227 | 1405 | ||
| 1228 | ```moonscript | 1406 | ```moonscript |
| 1229 | {:name = "nameless", :job = "jobless"} = person | 1407 | {:name = "nameless", :job = "jobless"} = person |
| @@ -1234,7 +1412,7 @@ print first, second, color | |||
| 1234 | </pre> | 1412 | </pre> |
| 1235 | </YueDisplay> | 1413 | </YueDisplay> |
| 1236 | 1414 | ||
| 1237 | 在进行列表解构时,您可以使用`_`作为占位符: | 1415 | 在进行列表解构时,你可以使用`_`作为占位符: |
| 1238 | 1416 | ||
| 1239 | ```moonscript | 1417 | ```moonscript |
| 1240 | [_, two, _, four] = items | 1418 | [_, two, _, four] = items |
| @@ -1245,9 +1423,55 @@ print first, second, color | |||
| 1245 | </pre> | 1423 | </pre> |
| 1246 | </YueDisplay> | 1424 | </YueDisplay> |
| 1247 | 1425 | ||
| 1248 | ### 在其方的解构 | 1426 | ### 解构 |
| 1249 | 1427 | ||
| 1250 | 解构也可以出现在其它隐式进行赋值的地方。一个例子是用在for循环: | 1428 | 你可以使用展开运算符 `...` 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。 |
| 1429 | |||
| 1430 | ```moonscript | ||
| 1431 | orders = ["first", "second", "third", "fourth", "last"] | ||
| 1432 | [first, ...bulk, last] = orders | ||
| 1433 | print first -- 打印: first | ||
| 1434 | print bulk -- 打印: {"second", "third", "fourth"} | ||
| 1435 | print last -- 打印: last | ||
| 1436 | ``` | ||
| 1437 | <YueDisplay> | ||
| 1438 | <pre> | ||
| 1439 | orders = ["first", "second", "third", "fourth", "last"] | ||
| 1440 | [first, ...bulk, last] = orders | ||
| 1441 | print first -- 打印: first | ||
| 1442 | print bulk -- 打印: {"second", "third", "fourth"} | ||
| 1443 | print last -- 打印: last | ||
| 1444 | </pre> | ||
| 1445 | </YueDisplay> | ||
| 1446 | |||
| 1447 | 展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 `_` 作为占位符来表示你想跳过对应范围的捕获: | ||
| 1448 | |||
| 1449 | ```moonscript | ||
| 1450 | -- 捕获第一个元素之后的所有元素 | ||
| 1451 | [first, ...rest] = orders | ||
| 1452 | |||
| 1453 | -- 捕获最后一个元素之前的所有元素 | ||
| 1454 | [...start, last] = orders | ||
| 1455 | |||
| 1456 | -- 跳过中间的元素,只捕获第一个和最后一个元素 | ||
| 1457 | [first, ..._, last] = orders | ||
| 1458 | ``` | ||
| 1459 | <YueDisplay> | ||
| 1460 | <pre> | ||
| 1461 | -- 捕获第一个元素之后的所有元素 | ||
| 1462 | [first, ...rest] = orders | ||
| 1463 | |||
| 1464 | -- 捕获最后一个元素之前的所有元素 | ||
| 1465 | [...start, last] = orders | ||
| 1466 | |||
| 1467 | -- 跳过中间的元素,只捕获第一个和最后一个元素 | ||
| 1468 | [first, ..._, last] = orders | ||
| 1469 | </pre> | ||
| 1470 | </YueDisplay> | ||
| 1471 | |||
| 1472 | ### 在其它地方的解构赋值 | ||
| 1473 | |||
| 1474 | 解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在 for 循环中: | ||
| 1251 | 1475 | ||
| 1252 | ```moonscript | 1476 | ```moonscript |
| 1253 | tuples = [ | 1477 | tuples = [ |
| @@ -1270,7 +1494,7 @@ for [left, right] in *tuples | |||
| 1270 | </pre> | 1494 | </pre> |
| 1271 | </YueDisplay> | 1495 | </YueDisplay> |
| 1272 | 1496 | ||
| 1273 | 我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在for语句的名称子句中使用解构来解包它。 | 1497 | 我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在 for 语句的名称子句中使用解构来解包它。 |
| 1274 | 1498 | ||
| 1275 | ## If 赋值 | 1499 | ## If 赋值 |
| 1276 | 1500 | ||
| @@ -1322,7 +1546,7 @@ print "好的" | |||
| 1322 | 1546 | ||
| 1323 | ### While 赋值 | 1547 | ### While 赋值 |
| 1324 | 1548 | ||
| 1325 | 您可以在 while 循环中同样使用赋值来获取循环条件的值。 | 1549 | 你可以在 while 循环中同样使用赋值来获取循环条件的值。 |
| 1326 | ```moonscript | 1550 | ```moonscript |
| 1327 | while byte := stream\read_one! | 1551 | while byte := stream\read_one! |
| 1328 | -- 对 byte 做一些操作 | 1552 | -- 对 byte 做一些操作 |
| @@ -1338,7 +1562,7 @@ while byte := stream\read_one! | |||
| 1338 | 1562 | ||
| 1339 | ## 可变参数赋值 | 1563 | ## 可变参数赋值 |
| 1340 | 1564 | ||
| 1341 | 您可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用Lua的方式访问其内容。 | 1565 | 你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用 Lua 的方式访问其内容。 |
| 1342 | ```moonscript | 1566 | ```moonscript |
| 1343 | list = [1, 2, 3, 4, 5] | 1567 | list = [1, 2, 3, 4, 5] |
| 1344 | fn = (ok) -> ok, table.unpack list | 1568 | fn = (ok) -> ok, table.unpack list |
| @@ -1360,7 +1584,20 @@ print ok, count, first | |||
| 1360 | 1584 | ||
| 1361 | ## 空白 | 1585 | ## 空白 |
| 1362 | 1586 | ||
| 1363 | 月之脚本是一个对空白敏感的语言。您必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 | 1587 | 月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 |
| 1588 | |||
| 1589 | ### 语句分隔符 | ||
| 1590 | |||
| 1591 | 一条语句通常以换行结束。你也可以使用分号 `;` 显式结束一条语句,从而在同一行中编写多条语句: | ||
| 1592 | |||
| 1593 | ```moonscript | ||
| 1594 | a = 1; b = 2; print a + b | ||
| 1595 | ``` | ||
| 1596 | <YueDisplay> | ||
| 1597 | <pre> | ||
| 1598 | a = 1; b = 2; print a + b | ||
| 1599 | </pre> | ||
| 1600 | </YueDisplay> | ||
| 1364 | 1601 | ||
| 1365 | ### 多行链式调用 | 1602 | ### 多行链式调用 |
| 1366 | 1603 | ||
| @@ -1415,7 +1652,7 @@ func --[[端口]] 3000, --[[ip]] "192.168.1.1" | |||
| 1415 | 1652 | ||
| 1416 | ## 错误处理 | 1653 | ## 错误处理 |
| 1417 | 1654 | ||
| 1418 | 用于统一进行Lua错误处理的便捷语法。 | 1655 | 用于统一进行 Lua 错误处理的便捷语法。 |
| 1419 | 1656 | ||
| 1420 | ```moonscript | 1657 | ```moonscript |
| 1421 | try | 1658 | try |
| @@ -1474,9 +1711,50 @@ catch err | |||
| 1474 | </pre> | 1711 | </pre> |
| 1475 | </YueDisplay> | 1712 | </YueDisplay> |
| 1476 | 1713 | ||
| 1714 | ### 错误处理简化 | ||
| 1715 | |||
| 1716 | `try?` 是 `try` 的功能简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。 | ||
| 1717 | |||
| 1718 | ```moonscript | ||
| 1719 | a, b, c = try? func! | ||
| 1720 | |||
| 1721 | -- 与空值合并运算符一起使用 | ||
| 1722 | a = (try? func!) ?? "default" | ||
| 1723 | |||
| 1724 | -- 作为函数参数 | ||
| 1725 | f try? func! | ||
| 1726 | |||
| 1727 | -- 带 catch 块的 try! | ||
| 1728 | f try? | ||
| 1729 | print 123 | ||
| 1730 | func! | ||
| 1731 | catch e | ||
| 1732 | print e | ||
| 1733 | e | ||
| 1734 | ``` | ||
| 1735 | <YueDisplay> | ||
| 1736 | <pre> | ||
| 1737 | a, b, c = try? func! | ||
| 1738 | |||
| 1739 | -- 与空值合并运算符一起使用 | ||
| 1740 | a = (try? func!) ?? "default" | ||
| 1741 | |||
| 1742 | -- 作为函数参数 | ||
| 1743 | f try? func! | ||
| 1744 | |||
| 1745 | -- 带 catch 块的 try! | ||
| 1746 | f try? | ||
| 1747 | print 123 | ||
| 1748 | func! | ||
| 1749 | catch e | ||
| 1750 | print e | ||
| 1751 | e | ||
| 1752 | </pre> | ||
| 1753 | </YueDisplay> | ||
| 1754 | |||
| 1477 | ## 属性 | 1755 | ## 属性 |
| 1478 | 1756 | ||
| 1479 | 月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。 | 1757 | 月之脚本现在提供了 Lua 5.4 新增的叫做属性的语法支持。在月之脚本编译到的 Lua 目标版本低于 5.4 时,你仍然可以同时使用`const` 和 `close` 的属性声明语法,并获得常量检查和作用域回调的功能。 |
| 1480 | 1758 | ||
| 1481 | ```moonscript | 1759 | ```moonscript |
| 1482 | const a = 123 | 1760 | const a = 123 |
| @@ -1502,11 +1780,24 @@ const {:a, :b, c, d} = tb | |||
| 1502 | </pre> | 1780 | </pre> |
| 1503 | </YueDisplay> | 1781 | </YueDisplay> |
| 1504 | 1782 | ||
| 1783 | 你也可以声明全局变量为常量。 | ||
| 1784 | |||
| 1785 | ```moonscript | ||
| 1786 | global const Constant = 123 | ||
| 1787 | -- Constant = 1 | ||
| 1788 | ``` | ||
| 1789 | <YueDisplay> | ||
| 1790 | <pre> | ||
| 1791 | global const Constant = 123 | ||
| 1792 | -- Constant = 1 | ||
| 1793 | </pre> | ||
| 1794 | </YueDisplay> | ||
| 1795 | |||
| 1505 | ## 字面量 | 1796 | ## 字面量 |
| 1506 | 1797 | ||
| 1507 | Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 | 1798 | Lua 中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和 **nil**。 |
| 1508 | 1799 | ||
| 1509 | 但与Lua不同的是,单引号和双引号字符串内部允许有换行: | 1800 | 但与 Lua 不同的是,单引号和双引号字符串内部允许有换行: |
| 1510 | 1801 | ||
| 1511 | ```moonscript | 1802 | ```moonscript |
| 1512 | some_string = "这是一个字符串 | 1803 | some_string = "这是一个字符串 |
| @@ -1529,17 +1820,78 @@ print "我有#{math.random! * 100}%的把握。" | |||
| 1529 | 1820 | ||
| 1530 | ### 数字字面量 | 1821 | ### 数字字面量 |
| 1531 | 1822 | ||
| 1532 | 您可以在数字字面量中使用下划线来增加可读性。 | 1823 | 你可以在数字字面量中使用下划线来增加可读性。 |
| 1533 | 1824 | ||
| 1534 | ```moonscript | 1825 | ```moonscript |
| 1535 | integer = 1_000_000 | 1826 | integer = 1_000_000 |
| 1536 | hex = 0xEF_BB_BF | 1827 | hex = 0xEF_BB_BF |
| 1828 | binary = 0B10011 | ||
| 1537 | ``` | 1829 | ``` |
| 1538 | <YueDisplay> | 1830 | <YueDisplay> |
| 1539 | 1831 | ||
| 1540 | <pre> | 1832 | <pre> |
| 1541 | integer = 1_000_000 | 1833 | integer = 1_000_000 |
| 1542 | hex = 0xEF_BB_BF | 1834 | hex = 0xEF_BB_BF |
| 1835 | binary = 0B10011 | ||
| 1836 | </pre> | ||
| 1837 | </YueDisplay> | ||
| 1838 | |||
| 1839 | ### YAML 风格字符串 | ||
| 1840 | |||
| 1841 | 使用 `|` 前缀标记一个多行 YAML 风格字符串: | ||
| 1842 | |||
| 1843 | ```moonscript | ||
| 1844 | str = | | ||
| 1845 | key: value | ||
| 1846 | list: | ||
| 1847 | - item1 | ||
| 1848 | - #{expr} | ||
| 1849 | ``` | ||
| 1850 | <YueDisplay> | ||
| 1851 | <pre> | ||
| 1852 | str = | | ||
| 1853 | key: value | ||
| 1854 | list: | ||
| 1855 | - item1 | ||
| 1856 | - #{expr} | ||
| 1857 | </pre> | ||
| 1858 | </YueDisplay> | ||
| 1859 | |||
| 1860 | 其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。 | ||
| 1861 | |||
| 1862 | YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。 | ||
| 1863 | |||
| 1864 | ```moonscript | ||
| 1865 | fn = -> | ||
| 1866 | str = | | ||
| 1867 | foo: | ||
| 1868 | bar: baz | ||
| 1869 | return str | ||
| 1870 | ``` | ||
| 1871 | <YueDisplay> | ||
| 1872 | <pre> | ||
| 1873 | fn = -> | ||
| 1874 | str = | | ||
| 1875 | foo: | ||
| 1876 | bar: baz | ||
| 1877 | return str | ||
| 1878 | </pre> | ||
| 1879 | </YueDisplay> | ||
| 1880 | |||
| 1881 | 输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。 | ||
| 1882 | |||
| 1883 | 支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义: | ||
| 1884 | |||
| 1885 | ```moonscript | ||
| 1886 | str = | | ||
| 1887 | path: "C:\Program Files\App" | ||
| 1888 | note: 'He said: "#{Hello}!"' | ||
| 1889 | ``` | ||
| 1890 | <YueDisplay> | ||
| 1891 | <pre> | ||
| 1892 | str = | | ||
| 1893 | path: "C:\Program Files\App" | ||
| 1894 | note: 'He said: "#{Hello}!"' | ||
| 1543 | </pre> | 1895 | </pre> |
| 1544 | </YueDisplay> | 1896 | </YueDisplay> |
| 1545 | 1897 | ||
| @@ -1644,7 +1996,7 @@ print "数字的和是", sum 10, 20 | |||
| 1644 | </pre> | 1996 | </pre> |
| 1645 | </YueDisplay> | 1997 | </YueDisplay> |
| 1646 | 1998 | ||
| 1647 | 如果您需要做显式返回,可以使用return关键字: | 1999 | 如果你需要做显式返回,可以使用 return 关键字: |
| 1648 | 2000 | ||
| 1649 | ```moonscript | 2001 | ```moonscript |
| 1650 | sum = (x, y) -> return x + y | 2002 | sum = (x, y) -> return x + y |
| @@ -1670,7 +2022,7 @@ a, b = mystery 10, 20 | |||
| 1670 | 2022 | ||
| 1671 | ### 粗箭头 | 2023 | ### 粗箭头 |
| 1672 | 2024 | ||
| 1673 | 因为在Lua中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含self参数的函数。 | 2025 | 因为在 Lua 中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含 self 参数的函数。 |
| 1674 | 2026 | ||
| 1675 | ```moonscript | 2027 | ```moonscript |
| 1676 | func = (num) => @value + num | 2028 | func = (num) => @value + num |
| @@ -1683,7 +2035,7 @@ func = (num) => @value + num | |||
| 1683 | 2035 | ||
| 1684 | ### 参数默认值 | 2036 | ### 参数默认值 |
| 1685 | 2037 | ||
| 1686 | 可以为函数的参数提供默认值。如果参数的值为nil,则确定该参数为空。任何具有默认值的nil参数在函数体运行之前都会被替换。 | 2038 | 可以为函数的参数提供默认值。如果参数的值为 nil,则确定该参数为空。任何具有默认值的 nil 参数在函数体运行之前都会被替换。 |
| 1687 | 2039 | ||
| 1688 | ```moonscript | 2040 | ```moonscript |
| 1689 | my_function = (name = "某物", height = 100) -> | 2041 | my_function = (name = "某物", height = 100) -> |
| @@ -1755,7 +2107,7 @@ my_func 5, 6, 7, | |||
| 1755 | </pre> | 2107 | </pre> |
| 1756 | </YueDisplay> | 2108 | </YueDisplay> |
| 1757 | 2109 | ||
| 1758 | 因为Lua表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是Lua表的一部分。 | 2110 | 因为 Lua 表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是 Lua 表的一部分。 |
| 1759 | 2111 | ||
| 1760 | ```moonscript | 2112 | ```moonscript |
| 1761 | x = [ | 2113 | x = [ |
| @@ -1822,6 +2174,138 @@ if func 1, 2, 3, | |||
| 1822 | </pre> | 2174 | </pre> |
| 1823 | </YueDisplay> | 2175 | </YueDisplay> |
| 1824 | 2176 | ||
| 2177 | ### 参数解构 | ||
| 2178 | |||
| 2179 | 月之脚本支持在函数形参位置对传入对象进行解构。适用两类解构表子面量: | ||
| 2180 | |||
| 2181 | - 使用 {} 包裹的字面量/对象形参,支持提供获得空字段时的默认值(例如 {:a, :b}、{a: a1 = 123})。 | ||
| 2182 | |||
| 2183 | - 无 {} 包裹、以键值/简写键序列开头,直至遇到其它表达式终止(例如 :a, b: b1, :c),表示从同一个对象中解构多个字段。 | ||
| 2184 | |||
| 2185 | ```moonscript | ||
| 2186 | f1 = (:a, :b, :c) -> | ||
| 2187 | print a, b, c | ||
| 2188 | |||
| 2189 | f1 a: 1, b: "2", c: {} | ||
| 2190 | |||
| 2191 | f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) -> | ||
| 2192 | print a1, b, c | ||
| 2193 | |||
| 2194 | arg1 = {a: 0} | ||
| 2195 | f2 arg1, arg2 | ||
| 2196 | ``` | ||
| 2197 | <YueDisplay> | ||
| 2198 | <pre> | ||
| 2199 | f1 = (:a, :b, :c) -> | ||
| 2200 | print a, b, c | ||
| 2201 | |||
| 2202 | f1 a: 1, b: "2", c: {} | ||
| 2203 | |||
| 2204 | f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) -> | ||
| 2205 | print a1, b, c | ||
| 2206 | |||
| 2207 | arg1 = {a: 0} | ||
| 2208 | f2 arg1, arg2 | ||
| 2209 | </pre> | ||
| 2210 | </YueDisplay> | ||
| 2211 | |||
| 2212 | ### 前置返回表达式 | ||
| 2213 | |||
| 2214 | 在深度嵌套的函数体中,为了提升返回值的可读性及编写便利性,我们新增了 “前置返回表达式” 语法。其形式如下: | ||
| 2215 | |||
| 2216 | ```moon | ||
| 2217 | findFirstEven = (list): nil -> | ||
| 2218 | for item in *list | ||
| 2219 | if type(item) == "table" | ||
| 2220 | for sub in *item | ||
| 2221 | if sub % 2 == 0 | ||
| 2222 | return sub | ||
| 2223 | ``` | ||
| 2224 | <YueDisplay> | ||
| 2225 | <pre> | ||
| 2226 | findFirstEven = (list): nil -> | ||
| 2227 | for item in *list | ||
| 2228 | if type(item) == "table" | ||
| 2229 | for sub in *item | ||
| 2230 | if sub % 2 == 0 | ||
| 2231 | return sub | ||
| 2232 | </pre> | ||
| 2233 | </YueDisplay> | ||
| 2234 | |||
| 2235 | 这个写法等价于: | ||
| 2236 | |||
| 2237 | ```moon | ||
| 2238 | findFirstEven = (list) -> | ||
| 2239 | for item in *list | ||
| 2240 | if type(item) == "table" | ||
| 2241 | for sub in *item | ||
| 2242 | if sub % 2 == 0 | ||
| 2243 | return sub | ||
| 2244 | nil | ||
| 2245 | ``` | ||
| 2246 | <YueDisplay> | ||
| 2247 | <pre> | ||
| 2248 | findFirstEven = (list) -> | ||
| 2249 | for item in *list | ||
| 2250 | if type(item) == "table" | ||
| 2251 | for sub in *item | ||
| 2252 | if sub % 2 == 0 | ||
| 2253 | return sub | ||
| 2254 | nil | ||
| 2255 | </pre> | ||
| 2256 | </YueDisplay> | ||
| 2257 | |||
| 2258 | 唯一的区别在于:你可以将函数的返回值表达式提前写在 `->` 或 `=>` 前,用以指示该函数应隐式返回该表达式的值。这样即使在多层循环或条件判断的场景下,也无需编写尾行悬挂的返回表达式,逻辑结构会更加直观清晰。 | ||
| 2259 | |||
| 2260 | ### 命名变长参数 | ||
| 2261 | |||
| 2262 | 你可以使用 `(...t) ->` 语法来将变长参数自动存储到一个命名表中。这个表会包含所有传入的参数(包括 `nil` 值),并且会在表的 `n` 字段中存储实际传入的参数个数(包括 `nil` 值在内的个数)。 | ||
| 2263 | |||
| 2264 | ```moonscript | ||
| 2265 | f = (...t) -> | ||
| 2266 | print "参数个数:", t.n | ||
| 2267 | print "表长度:", #t | ||
| 2268 | for i = 1, t.n | ||
| 2269 | print t[i] | ||
| 2270 | |||
| 2271 | f 1, 2, 3 | ||
| 2272 | f "a", "b", "c", "d" | ||
| 2273 | f! | ||
| 2274 | |||
| 2275 | -- 处理包含 nil 的情况 | ||
| 2276 | process = (...args) -> | ||
| 2277 | sum = 0 | ||
| 2278 | for i = 1, args.n | ||
| 2279 | if args[i] != nil and type(args[i]) == "number" | ||
| 2280 | sum += args[i] | ||
| 2281 | sum | ||
| 2282 | |||
| 2283 | process 1, nil, 3, nil, 5 | ||
| 2284 | ``` | ||
| 2285 | <YueDisplay> | ||
| 2286 | <pre> | ||
| 2287 | f = (...t) -> | ||
| 2288 | print "参数个数:", t.n | ||
| 2289 | print "表长度:", #t | ||
| 2290 | for i = 1, t.n | ||
| 2291 | print t[i] | ||
| 2292 | |||
| 2293 | f 1, 2, 3 | ||
| 2294 | f "a", "b", "c", "d" | ||
| 2295 | f! | ||
| 2296 | |||
| 2297 | -- 处理包含 nil 的情况 | ||
| 2298 | process = (...args) -> | ||
| 2299 | sum = 0 | ||
| 2300 | for i = 1, args.n | ||
| 2301 | if args[i] != nil and type(args[i]) == "number" | ||
| 2302 | sum += args[i] | ||
| 2303 | sum | ||
| 2304 | |||
| 2305 | process 1, nil, 3, nil, 5 | ||
| 2306 | </pre> | ||
| 2307 | </YueDisplay> | ||
| 2308 | |||
| 1825 | ## 反向回调 | 2309 | ## 反向回调 |
| 1826 | 2310 | ||
| 1827 | 反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。 | 2311 | 反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。 |
| @@ -1850,7 +2334,7 @@ print @value | |||
| 1850 | </pre> | 2334 | </pre> |
| 1851 | </YueDisplay> | 2335 | </YueDisplay> |
| 1852 | 2336 | ||
| 1853 | 您可以通过一个占位符指定回调函数的传参位置。 | 2337 | 你可以通过一个占位符指定回调函数的传参位置。 |
| 1854 | 2338 | ||
| 1855 | ```moonscript | 2339 | ```moonscript |
| 1856 | (x) <- map _, [1, 2, 3] | 2340 | (x) <- map _, [1, 2, 3] |
| @@ -1863,22 +2347,22 @@ x * 2 | |||
| 1863 | </pre> | 2347 | </pre> |
| 1864 | </YueDisplay> | 2348 | </YueDisplay> |
| 1865 | 2349 | ||
| 1866 | 如果您希望在反向回调处理后继续编写更多其它的代码,您可以使用do语句将不归属反向回调的代码分开。 | 2350 | 如果你希望在反向回调处理后继续编写更多其它的代码,可以使用 do 语句将不属于反向回调的代码分隔开。对于非粗箭头函数的反向回调,回调返回值的括号也是可以省略的。 |
| 1867 | 2351 | ||
| 1868 | ```moonscript | 2352 | ```moonscript |
| 1869 | result, msg = do | 2353 | result, msg = do |
| 1870 | (data) <- readAsync "文件名.txt" | 2354 | data <- readAsync "文件名.txt" |
| 1871 | print data | 2355 | print data |
| 1872 | (info) <- processAsync data | 2356 | info <- processAsync data |
| 1873 | check info | 2357 | check info |
| 1874 | print result, msg | 2358 | print result, msg |
| 1875 | ``` | 2359 | ``` |
| 1876 | <YueDisplay> | 2360 | <YueDisplay> |
| 1877 | <pre> | 2361 | <pre> |
| 1878 | result, msg = do | 2362 | result, msg = do |
| 1879 | (data) <- readAsync "文件名.txt" | 2363 | data <- readAsync "文件名.txt" |
| 1880 | print data | 2364 | print data |
| 1881 | (info) <- processAsync data | 2365 | info <- processAsync data |
| 1882 | check info | 2366 | check info |
| 1883 | print result, msg | 2367 | print result, msg |
| 1884 | </pre> | 2368 | </pre> |
| @@ -1886,7 +2370,7 @@ print result, msg | |||
| 1886 | 2370 | ||
| 1887 | ## 表格字面量 | 2371 | ## 表格字面量 |
| 1888 | 2372 | ||
| 1889 | 和Lua一样,表格可以通过花括号进行定义。 | 2373 | 和 Lua 一样,表格可以通过花括号进行定义。 |
| 1890 | 2374 | ||
| 1891 | ```moonscript | 2375 | ```moonscript |
| 1892 | some_values = [1, 2, 3, 4] | 2376 | some_values = [1, 2, 3, 4] |
| @@ -1969,7 +2453,7 @@ y = type: "狗", legs: 4, tails: 1 | |||
| 1969 | </pre> | 2453 | </pre> |
| 1970 | </YueDisplay> | 2454 | </YueDisplay> |
| 1971 | 2455 | ||
| 1972 | 表格字面量的键可以使用Lua语言的关键字,而无需转义: | 2456 | 表格字面量的键可以使用 Lua 语言的关键字,而无需转义: |
| 1973 | 2457 | ||
| 1974 | ```moonscript | 2458 | ```moonscript |
| 1975 | tbl = { | 2459 | tbl = { |
| @@ -2005,7 +2489,7 @@ print_table :hair, :height | |||
| 2005 | </pre> | 2489 | </pre> |
| 2006 | </YueDisplay> | 2490 | </YueDisplay> |
| 2007 | 2491 | ||
| 2008 | 如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在Lua中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。 | 2492 | 如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在 Lua 中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。 |
| 2009 | 2493 | ||
| 2010 | ```moonscript | 2494 | ```moonscript |
| 2011 | t = { | 2495 | t = { |
| @@ -2022,7 +2506,7 @@ t = { | |||
| 2022 | </pre> | 2506 | </pre> |
| 2023 | </YueDisplay> | 2507 | </YueDisplay> |
| 2024 | 2508 | ||
| 2025 | Lua的表同时具有数组部分和哈希部分,但有时候你会希望在书写Lua表时,对Lua表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。 | 2509 | Lua 的表同时具有数组部分和哈希部分,但有时候你会希望在书写 Lua 表时,对 Lua 表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。 |
| 2026 | 2510 | ||
| 2027 | ```moonscript | 2511 | ```moonscript |
| 2028 | some_values = [ 1, 2, 3, 4 ] | 2512 | some_values = [ 1, 2, 3, 4 ] |
| @@ -2037,11 +2521,11 @@ list_with_one_element = [ 1, ] | |||
| 2037 | 2521 | ||
| 2038 | ## 推导式 | 2522 | ## 推导式 |
| 2039 | 2523 | ||
| 2040 | 推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生Lua表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许您在每次遍历时设置新表格的键和值。 | 2524 | 推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生 Lua 表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。 |
| 2041 | 2525 | ||
| 2042 | ### 列表推导式 | 2526 | ### 列表推导式 |
| 2043 | 2527 | ||
| 2044 | 以下操作创建了一个items表的副本,但所有包含的值都翻倍了。 | 2528 | 以下操作创建了一个 items 表的副本,但所有包含的值都翻倍了。 |
| 2045 | 2529 | ||
| 2046 | ```moonscript | 2530 | ```moonscript |
| 2047 | items = [1, 2, 3, 4] | 2531 | items = [1, 2, 3, 4] |
| @@ -2054,7 +2538,7 @@ doubled = [item * 2 for i, item in ipairs items] | |||
| 2054 | </pre> | 2538 | </pre> |
| 2055 | </YueDisplay> | 2539 | </YueDisplay> |
| 2056 | 2540 | ||
| 2057 | 可以使用when子句筛选新表中包含的项目: | 2541 | 可以使用 `when` 子句筛选新表中包含的项目: |
| 2058 | 2542 | ||
| 2059 | ```moonscript | 2543 | ```moonscript |
| 2060 | slice = [item for i, item in ipairs items when i > 1 and i < 3] | 2544 | slice = [item for i, item in ipairs items when i > 1 and i < 3] |
| @@ -2065,7 +2549,7 @@ slice = [item for i, item in ipairs items when i > 1 and i < 3] | |||
| 2065 | </pre> | 2549 | </pre> |
| 2066 | </YueDisplay> | 2550 | </YueDisplay> |
| 2067 | 2551 | ||
| 2068 | 因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled示例可以重写为: | 2552 | 因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled 示例可以重写为: |
| 2069 | 2553 | ||
| 2070 | ```moonscript | 2554 | ```moonscript |
| 2071 | doubled = [item * 2 for item in *items] | 2555 | doubled = [item * 2 for item in *items] |
| @@ -2076,9 +2560,30 @@ doubled = [item * 2 for item in *items] | |||
| 2076 | </pre> | 2560 | </pre> |
| 2077 | </YueDisplay> | 2561 | </YueDisplay> |
| 2078 | 2562 | ||
| 2079 | for和when子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个for子句。 | 2563 | 在列表推导式中,你还可以使用展开操作符 `...` 来实现对列表嵌套层级进行扁平化的处理: |
| 2564 | |||
| 2565 | ```moonscript | ||
| 2566 | data = | ||
| 2567 | a: [1, 2, 3] | ||
| 2568 | b: [4, 5, 6] | ||
| 2569 | |||
| 2570 | flat = [...v for k,v in pairs data] | ||
| 2571 | -- flat 现在为 [1, 2, 3, 4, 5, 6] | ||
| 2572 | ``` | ||
| 2573 | <YueDisplay> | ||
| 2574 | <pre> | ||
| 2575 | data = | ||
| 2576 | a: [1, 2, 3] | ||
| 2577 | b: [4, 5, 6] | ||
| 2578 | |||
| 2579 | flat = [...v for k,v in pairs data] | ||
| 2580 | -- flat 现在为 [1, 2, 3, 4, 5, 6] | ||
| 2581 | </pre> | ||
| 2582 | </YueDisplay> | ||
| 2583 | |||
| 2584 | for 和 when 子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个 for 子句。 | ||
| 2080 | 2585 | ||
| 2081 | 使用多个for子句与使用多重循环的效果相同: | 2586 | 使用多个 for 子句与使用多重循环的效果相同: |
| 2082 | 2587 | ||
| 2083 | ```moonscript | 2588 | ```moonscript |
| 2084 | x_coords = [4, 5, 6, 7] | 2589 | x_coords = [4, 5, 6, 7] |
| @@ -2097,7 +2602,7 @@ for y in *y_coords] | |||
| 2097 | </pre> | 2602 | </pre> |
| 2098 | </YueDisplay> | 2603 | </YueDisplay> |
| 2099 | 2604 | ||
| 2100 | 在推导式中也可以使用简单的数值for循环: | 2605 | 在推导式中也可以使用简单的数值 for 循环: |
| 2101 | 2606 | ||
| 2102 | ```moonscript | 2607 | ```moonscript |
| 2103 | evens = [i for i = 1, 100 when i % 2 == 0] | 2608 | evens = [i for i = 1, 100 when i % 2 == 0] |
| @@ -2112,7 +2617,7 @@ evens = [i for i = 1, 100 when i % 2 == 0] | |||
| 2112 | 2617 | ||
| 2113 | 表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。 | 2618 | 表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。 |
| 2114 | 2619 | ||
| 2115 | 以下示例生成了表格thing的副本: | 2620 | 以下示例生成了表格 thing 的副本: |
| 2116 | 2621 | ||
| 2117 | ```moonscript | 2622 | ```moonscript |
| 2118 | thing = { | 2623 | thing = { |
| @@ -2174,9 +2679,9 @@ tbl = {unpack tuple for tuple in *tuples} | |||
| 2174 | 2679 | ||
| 2175 | ### 切片 | 2680 | ### 切片 |
| 2176 | 2681 | ||
| 2177 | 当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在for循环中设置迭代边界和步长。 | 2682 | 当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在 for 循环中设置迭代边界和步长。 |
| 2178 | 2683 | ||
| 2179 | 下面的案例中,我们在切片中设置最小和最大边界,取索引在1到5之间(包括1和5)的所有项目: | 2684 | 下面的案例中,我们在切片中设置最小和最大边界,取索引在 1 到 5 之间(包括 1 和 5)的所有项目: |
| 2180 | 2685 | ||
| 2181 | ```moonscript | 2686 | ```moonscript |
| 2182 | slice = [item for item in *items[1, 5]] | 2687 | slice = [item for item in *items[1, 5]] |
| @@ -2198,7 +2703,7 @@ slice = [item for item in *items[2,]] | |||
| 2198 | </pre> | 2703 | </pre> |
| 2199 | </YueDisplay> | 2704 | </YueDisplay> |
| 2200 | 2705 | ||
| 2201 | 如果省略了最小边界,便默认会设置为1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …) | 2706 | 如果省略了最小边界,便默认会设置为 1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …) |
| 2202 | 2707 | ||
| 2203 | ```moonscript | 2708 | ```moonscript |
| 2204 | slice = [item for item in *items[,,2]] | 2709 | slice = [item for item in *items[,,2]] |
| @@ -2210,9 +2715,48 @@ slice = [item for item in *items[,,2]] | |||
| 2210 | </pre> | 2715 | </pre> |
| 2211 | </YueDisplay> | 2716 | </YueDisplay> |
| 2212 | 2717 | ||
| 2718 | 最小和最大边界都可以是负数,使用负数意味着边界是从表的末尾开始计算的。 | ||
| 2719 | |||
| 2720 | ```moonscript | ||
| 2721 | -- 取最后4个元素 | ||
| 2722 | slice = [item for item in *items[-4,-1]] | ||
| 2723 | ``` | ||
| 2724 | <YueDisplay> | ||
| 2725 | <pre> | ||
| 2726 | -- 取最后4个元素 | ||
| 2727 | slice = [item for item in *items[-4,-1]] | ||
| 2728 | </pre> | ||
| 2729 | </YueDisplay> | ||
| 2730 | |||
| 2731 | 切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。 | ||
| 2732 | |||
| 2733 | ```moonscript | ||
| 2734 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
| 2735 | ``` | ||
| 2736 | <YueDisplay> | ||
| 2737 | <pre> | ||
| 2738 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
| 2739 | </pre> | ||
| 2740 | </YueDisplay> | ||
| 2741 | |||
| 2742 | #### 切片表达式 | ||
| 2743 | |||
| 2744 | 切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。 | ||
| 2745 | |||
| 2746 | ```moonscript | ||
| 2747 | -- 取第2和第4个元素作为新的列表 | ||
| 2748 | sub_list = items[2, 4] | ||
| 2749 | ``` | ||
| 2750 | <YueDisplay> | ||
| 2751 | <pre> | ||
| 2752 | -- 取第2和第4个元素作为新的列表 | ||
| 2753 | sub_list = items[2, 4] | ||
| 2754 | </pre> | ||
| 2755 | </YueDisplay> | ||
| 2756 | |||
| 2213 | ## for 循环 | 2757 | ## for 循环 |
| 2214 | 2758 | ||
| 2215 | Lua中有两种for循环形式,数字型和通用型: | 2759 | Lua 中有两种 for 循环形式,数字型和通用型: |
| 2216 | 2760 | ||
| 2217 | ```moonscript | 2761 | ```moonscript |
| 2218 | for i = 10, 20 | 2762 | for i = 10, 20 |
| @@ -2265,7 +2809,7 @@ for j = 1, 10, 3 do print j | |||
| 2265 | </pre> | 2809 | </pre> |
| 2266 | </YueDisplay> | 2810 | </YueDisplay> |
| 2267 | 2811 | ||
| 2268 | for循环也可以用作表达式。for循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。 | 2812 | for 循环也可以用作表达式。for 循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。 |
| 2269 | 2813 | ||
| 2270 | 将每个偶数加倍: | 2814 | 将每个偶数加倍: |
| 2271 | 2815 | ||
| @@ -2286,9 +2830,24 @@ doubled_evens = for i = 1, 20 | |||
| 2286 | </pre> | 2830 | </pre> |
| 2287 | </YueDisplay> | 2831 | </YueDisplay> |
| 2288 | 2832 | ||
| 2289 | 您还可以结合for循环表达式与continue语句来过滤值。 | 2833 | 此外,for 循环还支持带返回值的 break 语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。 |
| 2834 | |||
| 2835 | 例如,查找第一个大于 10 的数字: | ||
| 2836 | |||
| 2837 | ```moonscript | ||
| 2838 | first_large = for n in *numbers | ||
| 2839 | break n if n > 10 | ||
| 2840 | ``` | ||
| 2841 | <YueDisplay> | ||
| 2842 | <pre> | ||
| 2843 | first_large = for n in *numbers | ||
| 2844 | break n if n > 10 | ||
| 2845 | </pre> | ||
| 2846 | </YueDisplay> | ||
| 2847 | |||
| 2848 | 你还可以结合 for 循环表达式与 continue 语句来过滤值。 | ||
| 2290 | 2849 | ||
| 2291 | 注意出现在函数体末尾的for循环,不会被当作是一个表达式,并将循环结果累积到一个列表中作为返回值(相反,函数将返回nil)。如果要函数末尾的循环转换为列表表达式,可以使用返回语句加for循环表达式。 | 2850 | 注意出现在函数体末尾的 for 循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回 nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加 for 循环表达式。 |
| 2292 | 2851 | ||
| 2293 | ```moonscript | 2852 | ```moonscript |
| 2294 | func_a = -> for i = 1, 10 do print i | 2853 | func_a = -> for i = 1, 10 do print i |
| @@ -2311,7 +2870,7 @@ print func_b! -- 打印 table 对象 | |||
| 2311 | 2870 | ||
| 2312 | ## repeat 循环 | 2871 | ## repeat 循环 |
| 2313 | 2872 | ||
| 2314 | repeat循环是从Lua语言中搬过来的相似语法: | 2873 | repeat 循环是从 Lua 语言中搬过来的相似语法: |
| 2315 | 2874 | ||
| 2316 | ```moonscript | 2875 | ```moonscript |
| 2317 | i = 10 | 2876 | i = 10 |
| @@ -2332,7 +2891,7 @@ until i == 0 | |||
| 2332 | 2891 | ||
| 2333 | ## while 循环 | 2892 | ## while 循环 |
| 2334 | 2893 | ||
| 2335 | 在月之脚本中的while循环有四种写法: | 2894 | 在月之脚本中的 while 循环有四种写法: |
| 2336 | 2895 | ||
| 2337 | ```moonscript | 2896 | ```moonscript |
| 2338 | i = 10 | 2897 | i = 10 |
| @@ -2371,7 +2930,7 @@ until running == false do my_function! | |||
| 2371 | </pre> | 2930 | </pre> |
| 2372 | </YueDisplay> | 2931 | </YueDisplay> |
| 2373 | 2932 | ||
| 2374 | 像for循环的语法一样,while循环也可以作为一个表达式使用。为了使函数返回while循环的累积列表值,必须明确使用返回语句返回while循环表达式。 | 2933 | 像 for 循环的语法一样,while 循环也可以作为一个表达式使用。为了使函数返回 while 循环的累积列表值,必须明确使用返回语句返回 while 循环表达式。 |
| 2375 | 2934 | ||
| 2376 | ## 继续 | 2935 | ## 继续 |
| 2377 | 2936 | ||
| @@ -2489,13 +3048,14 @@ print message -- 打印: 我很高 | |||
| 2489 | </pre> | 3048 | </pre> |
| 2490 | </YueDisplay> | 3049 | </YueDisplay> |
| 2491 | 3050 | ||
| 2492 | if的反义词是unless(相当于if not,如果 vs 除非): | 3051 | if 的反义词是 unless(相当于 if not,正如“如果”对应“除非”): |
| 2493 | 3052 | ||
| 2494 | ```moonscript | 3053 | ```moonscript |
| 2495 | unless os.date("%A") == "Monday" | 3054 | unless os.date("%A") == "Monday" |
| 2496 | print "今天不是星期一!" | 3055 | print "今天不是星期一!" |
| 2497 | ``` | 3056 | ``` |
| 2498 | <YueDisplay> | 3057 | <YueDisplay> |
| 3058 | |||
| 2499 | <pre> | 3059 | <pre> |
| 2500 | unless os.date("%A") == "Monday" | 3060 | unless os.date("%A") == "Monday" |
| 2501 | print "今天不是星期一!" | 3061 | print "今天不是星期一!" |
| @@ -2513,7 +3073,7 @@ print "你真幸运!" unless math.random! > 0.1 | |||
| 2513 | 3073 | ||
| 2514 | ### 范围表达式 | 3074 | ### 范围表达式 |
| 2515 | 3075 | ||
| 2516 | 您可以使用范围表达式来编写进行范围检查的代码。 | 3076 | 你可以使用范围表达式来编写进行范围检查的代码。 |
| 2517 | 3077 | ||
| 2518 | ```moonscript | 3078 | ```moonscript |
| 2519 | a = 5 | 3079 | a = 5 |
| @@ -2547,7 +3107,7 @@ print "你很幸运!" unless math.random! > 0.1 | |||
| 2547 | 3107 | ||
| 2548 | ## 代码行修饰符 | 3108 | ## 代码行修饰符 |
| 2549 | 3109 | ||
| 2550 | 为了方便编写代码,循环语句和if语句可以应用于单行代码语句的末尾: | 3110 | 为了方便编写代码,循环语句和 if 语句可以应用于单行代码语句的末尾: |
| 2551 | 3111 | ||
| 2552 | ```moonscript | 3112 | ```moonscript |
| 2553 | print "你好,世界" if name == "Rob" | 3113 | print "你好,世界" if name == "Rob" |
| @@ -2558,7 +3118,7 @@ print "你好,世界" if name == "Rob" | |||
| 2558 | </pre> | 3118 | </pre> |
| 2559 | </YueDisplay> | 3119 | </YueDisplay> |
| 2560 | 3120 | ||
| 2561 | 修饰for循环的示例: | 3121 | 修饰 for 循环的示例: |
| 2562 | 3122 | ||
| 2563 | ```moonscript | 3123 | ```moonscript |
| 2564 | print "项目: ", item for item in *items | 3124 | print "项目: ", item for item in *items |
| @@ -2569,7 +3129,7 @@ print "项目: ", item for item in *items | |||
| 2569 | </pre> | 3129 | </pre> |
| 2570 | </YueDisplay> | 3130 | </YueDisplay> |
| 2571 | 3131 | ||
| 2572 | 修饰while循环的示例: | 3132 | 修饰 while 循环的示例: |
| 2573 | 3133 | ||
| 2574 | ```moonscript | 3134 | ```moonscript |
| 2575 | game\update! while game\isRunning! | 3135 | game\update! while game\isRunning! |
| @@ -2586,34 +3146,32 @@ reader\parse_line! until reader\eof! | |||
| 2586 | 3146 | ||
| 2587 | ## switch 语句 | 3147 | ## switch 语句 |
| 2588 | 3148 | ||
| 2589 | switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。 | 3149 | switch 语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和 if 语句一样,switch 语句在最后可以接一个 else 代码块来处理没有匹配的情况。在生成的 Lua 代码中,进行比较是使用 == 操作符完成的。switch 语句中也可以使用赋值表达式来储存临时变量值。 |
| 2590 | 3150 | ||
| 2591 | ```moonscript | 3151 | ```moonscript |
| 2592 | name = "Dan" | 3152 | switch name := "Dan" |
| 2593 | switch name | ||
| 2594 | when "Robert" | 3153 | when "Robert" |
| 2595 | print "你是Robert" | 3154 | print "你是Robert" |
| 2596 | when "Dan", "Daniel" | 3155 | when "Dan", "Daniel" |
| 2597 | print "你的名字是Dan" | 3156 | print "你的名字是Dan" |
| 2598 | else | 3157 | else |
| 2599 | print "我不知道你的名字" | 3158 | print "我不认识你,你的名字是#{name}" |
| 2600 | ``` | 3159 | ``` |
| 2601 | <YueDisplay> | 3160 | <YueDisplay> |
| 2602 | <pre> | 3161 | <pre> |
| 2603 | name = "Dan" | 3162 | switch name := "Dan" |
| 2604 | switch name | ||
| 2605 | when "Robert" | 3163 | when "Robert" |
| 2606 | print "你是Robert" | 3164 | print "你是Robert" |
| 2607 | when "Dan", "Daniel" | 3165 | when "Dan", "Daniel" |
| 2608 | print "你的名字是Dan" | 3166 | print "你的名字是Dan" |
| 2609 | else | 3167 | else |
| 2610 | print "我不知道你的名字" | 3168 | print "我不认识你,你的名字是#{name}" |
| 2611 | </pre> | 3169 | </pre> |
| 2612 | </YueDisplay> | 3170 | </YueDisplay> |
| 2613 | 3171 | ||
| 2614 | switch语句的when子句中可以通过使用逗号分隔的列表来匹配多个值。 | 3172 | switch 语句的 when 子句中可以通过使用逗号分隔的列表来匹配多个值。 |
| 2615 | 3173 | ||
| 2616 | switch语句也可以作为表达式使用,下面我们可以将switch语句返回的结果分配给一个变量: | 3174 | switch 语句也可以作为表达式使用,下面我们可以将 switch 语句返回的结果分配给一个变量: |
| 2617 | 3175 | ||
| 2618 | ```moonscript | 3176 | ```moonscript |
| 2619 | b = 1 | 3177 | b = 1 |
| @@ -2638,7 +3196,7 @@ next_number = switch b | |||
| 2638 | </pre> | 3196 | </pre> |
| 2639 | </YueDisplay> | 3197 | </YueDisplay> |
| 2640 | 3198 | ||
| 2641 | 我们可以使用then关键字在when子句的同一行上编写处理代码。else代码块的后续代码中要写在同一行上不需要额外的关键字。 | 3199 | 我们可以使用 then 关键字在 when 子句的同一行上编写处理代码。else 代码块的后续代码中要写在同一行上不需要额外的关键字。 |
| 2642 | 3200 | ||
| 2643 | ```moonscript | 3201 | ```moonscript |
| 2644 | msg = switch math.random(1, 5) | 3202 | msg = switch math.random(1, 5) |
| @@ -2655,7 +3213,7 @@ msg = switch math.random(1, 5) | |||
| 2655 | </pre> | 3213 | </pre> |
| 2656 | </YueDisplay> | 3214 | </YueDisplay> |
| 2657 | 3215 | ||
| 2658 | 如果在编写switch语句时希望少写一个缩进,那么你可以把第一个when子句放在switch开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。 | 3216 | 如果在编写 switch 语句时希望少写一个缩进,那么你可以把第一个 when 子句放在 switch 开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。 |
| 2659 | 3217 | ||
| 2660 | ```moonscript | 3218 | ```moonscript |
| 2661 | switch math.random(1, 5) | 3219 | switch math.random(1, 5) |
| @@ -2684,11 +3242,11 @@ else | |||
| 2684 | </pre> | 3242 | </pre> |
| 2685 | </YueDisplay> | 3243 | </YueDisplay> |
| 2686 | 3244 | ||
| 2687 | 值得注意的是,在生成Lua代码时,我们要做检查的目标变量会放在==表达式的右侧。当您希望给when子句的比较对象定义一个\_\_eq元方法来重载判断逻辑时,可能会有用。 | 3245 | 值得注意的是,在生成 Lua 代码时,我们要做检查的目标变量会放在 == 表达式的右侧。当你希望给 when 子句的比较对象定义一个 \_\_eq 元方法来重载判断逻辑时,可能会有用。 |
| 2688 | 3246 | ||
| 2689 | ### 表格匹配 | 3247 | ### 表格匹配 |
| 2690 | 3248 | ||
| 2691 | 在switch的when子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非nil值,那么你可以尝试使用表格匹配的语法。 | 3249 | 在 switch 的 when 子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非 nil 值,那么你可以尝试使用表格匹配的语法。 |
| 2692 | 3250 | ||
| 2693 | ```moonscript | 3251 | ```moonscript |
| 2694 | items = | 3252 | items = |
| @@ -2744,9 +3302,126 @@ switch item | |||
| 2744 | </pre> | 3302 | </pre> |
| 2745 | </YueDisplay> | 3303 | </YueDisplay> |
| 2746 | 3304 | ||
| 3305 | 你也可以匹配数组元素、表格字段,甚至使用数组或表格字面量来匹配嵌套的结构。 | ||
| 3306 | |||
| 3307 | 匹配数组元素。 | ||
| 3308 | |||
| 3309 | ```moonscript | ||
| 3310 | switch tb | ||
| 3311 | when [1, 2, 3] | ||
| 3312 | print "1, 2, 3" | ||
| 3313 | when [1, b, 3] | ||
| 3314 | print "1, #{b}, 3" | ||
| 3315 | when [1, 2, b = 3] -- 变量b有默认值 | ||
| 3316 | print "1, 2, #{b}" | ||
| 3317 | ``` | ||
| 3318 | <YueDisplay> | ||
| 3319 | <pre> | ||
| 3320 | switch tb | ||
| 3321 | when [1, 2, 3] | ||
| 3322 | print "1, 2, 3" | ||
| 3323 | when [1, b, 3] | ||
| 3324 | print "1, #{b}, 3" | ||
| 3325 | when [1, 2, b = 3] -- 变量b有默认值 | ||
| 3326 | print "1, 2, #{b}" | ||
| 3327 | </pre> | ||
| 3328 | </YueDisplay> | ||
| 3329 | |||
| 3330 | 匹配表格字段。 | ||
| 3331 | |||
| 3332 | ```moonscript | ||
| 3333 | switch tb | ||
| 3334 | when success: true, :result | ||
| 3335 | print "成功", result | ||
| 3336 | when success: false | ||
| 3337 | print "失败", result | ||
| 3338 | else | ||
| 3339 | print "无效值" | ||
| 3340 | ``` | ||
| 3341 | <YueDisplay> | ||
| 3342 | <pre> | ||
| 3343 | switch tb | ||
| 3344 | when success: true, :result | ||
| 3345 | print "成功", result | ||
| 3346 | when success: false | ||
| 3347 | print "失败", result | ||
| 3348 | else | ||
| 3349 | print "无效值" | ||
| 3350 | </pre> | ||
| 3351 | </YueDisplay> | ||
| 3352 | |||
| 3353 | 匹配嵌套的表格结构。 | ||
| 3354 | |||
| 3355 | ```moonscript | ||
| 3356 | switch tb | ||
| 3357 | when data: {type: "success", :content} | ||
| 3358 | print "成功", content | ||
| 3359 | when data: {type: "error", :content} | ||
| 3360 | print "失败", content | ||
| 3361 | else | ||
| 3362 | print "无效值" | ||
| 3363 | ``` | ||
| 3364 | <YueDisplay> | ||
| 3365 | <pre> | ||
| 3366 | switch tb | ||
| 3367 | when data: {type: "success", :content} | ||
| 3368 | print "成功", content | ||
| 3369 | when data: {type: "error", :content} | ||
| 3370 | print "失败", content | ||
| 3371 | else | ||
| 3372 | print "无效值" | ||
| 3373 | </pre> | ||
| 3374 | </YueDisplay> | ||
| 3375 | |||
| 3376 | 匹配表格数组。 | ||
| 3377 | |||
| 3378 | ```moonscript | ||
| 3379 | switch tb | ||
| 3380 | when [ | ||
| 3381 | {a: 1, b: 2} | ||
| 3382 | {a: 3, b: 4} | ||
| 3383 | {a: 5, b: 6} | ||
| 3384 | fourth | ||
| 3385 | ] | ||
| 3386 | print "匹配成功", fourth | ||
| 3387 | ``` | ||
| 3388 | <YueDisplay> | ||
| 3389 | <pre> | ||
| 3390 | switch tb | ||
| 3391 | when [ | ||
| 3392 | {a: 1, b: 2} | ||
| 3393 | {a: 3, b: 4} | ||
| 3394 | {a: 5, b: 6} | ||
| 3395 | fourth | ||
| 3396 | ] | ||
| 3397 | print "匹配成功", fourth | ||
| 3398 | </pre> | ||
| 3399 | </YueDisplay> | ||
| 3400 | |||
| 3401 | 匹配一个列表并捕获特定范围内的元素。 | ||
| 3402 | |||
| 3403 | ```moonscript | ||
| 3404 | segments = ["admin", "users", "logs", "view"] | ||
| 3405 | switch segments | ||
| 3406 | when [...groups, resource, action] | ||
| 3407 | print "Group:", groups -- 打印: {"admin", "users"} | ||
| 3408 | print "Resource:", resource -- 打印: "logs" | ||
| 3409 | print "Action:", action -- 打印: "view" | ||
| 3410 | ``` | ||
| 3411 | <YueDisplay> | ||
| 3412 | <pre> | ||
| 3413 | segments = ["admin", "users", "logs", "view"] | ||
| 3414 | switch segments | ||
| 3415 | when [...groups, resource, action] | ||
| 3416 | print "Group:", groups -- 打印: {"admin", "users"} | ||
| 3417 | print "Resource:", resource -- 打印: "logs" | ||
| 3418 | print "Action:", action -- 打印: "view" | ||
| 3419 | </pre> | ||
| 3420 | </YueDisplay> | ||
| 3421 | |||
| 2747 | ## 面向对象编程 | 3422 | ## 面向对象编程 |
| 2748 | 3423 | ||
| 2749 | 在以下的示例中,月之脚本生成的Lua代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果您想知道关于面向对象功能的实现细节,再查看Lua代码。 | 3424 | 在以下的示例中,月之脚本生成的 Lua 代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看 Lua 代码。 |
| 2750 | 3425 | ||
| 2751 | 一个简单的类: | 3426 | 一个简单的类: |
| 2752 | 3427 | ||
| @@ -2775,11 +3450,11 @@ class Inventory | |||
| 2775 | </pre> | 3450 | </pre> |
| 2776 | </YueDisplay> | 3451 | </YueDisplay> |
| 2777 | 3452 | ||
| 2778 | 在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合Lua表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为“new”的成员扮演了一个重要的角色,是作为构造函数来使用。 | 3453 | 在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合 Lua 表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为 “new” 的成员扮演了一个重要的角色,是作为构造函数来使用。 |
| 2779 | 3454 | ||
| 2780 | 值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为“self”的参数。 | 3455 | 值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为 “self” 的参数。 |
| 2781 | 3456 | ||
| 2782 | 此外,“@”前缀在变量名上起到了简化作用,代表“self”。例如,`@items` 就等同于 `self.items`。 | 3457 | 此外,“@” 前缀在变量名上起到了简化作用,代表 “self”。例如,`@items` 就等同于 `self.items`。 |
| 2783 | 3458 | ||
| 2784 | 为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。 | 3459 | 为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。 |
| 2785 | 3460 | ||
| @@ -2801,7 +3476,7 @@ inv\add_item "pants" | |||
| 2801 | 3476 | ||
| 2802 | 需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 | 3477 | 需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 |
| 2803 | 3478 | ||
| 2804 | 例如,在下面的示例中,clothes属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。 | 3479 | 例如,在下面的示例中,clothes 属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。 |
| 2805 | 3480 | ||
| 2806 | ```moonscript | 3481 | ```moonscript |
| 2807 | class Person | 3482 | class Person |
| @@ -2853,7 +3528,7 @@ class Person | |||
| 2853 | 3528 | ||
| 2854 | ### 继承 | 3529 | ### 继承 |
| 2855 | 3530 | ||
| 2856 | `extends`关键字可以在类声明中使用,以继承另一个类的属性和方法。 | 3531 | `extends` 关键字可以在类声明中使用,以继承另一个类的属性和方法。 |
| 2857 | 3532 | ||
| 2858 | ```moonscript | 3533 | ```moonscript |
| 2859 | class BackPack extends Inventory | 3534 | class BackPack extends Inventory |
| @@ -2873,11 +3548,11 @@ class BackPack extends Inventory | |||
| 2873 | </YueDisplay> | 3548 | </YueDisplay> |
| 2874 | 3549 | ||
| 2875 | 3550 | ||
| 2876 | 在这一部分,我们对月之脚本中的`Inventory`类进行了扩展,加入了对可以携带物品数量的限制。 | 3551 | 在这一部分,我们对月之脚本中的 `Inventory` 类进行了扩展,加入了对可以携带物品数量的限制。 |
| 2877 | 3552 | ||
| 2878 | 在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用`super`方法来调用并执行父类的构造函数。 | 3553 | 在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用 `super` 方法来调用并执行父类的构造函数。 |
| 2879 | 3554 | ||
| 2880 | 此外,当一个类继承自另一个类时,它会尝试调用父类上的`__inherited`方法(如果这个方法存在的话),以此来向父类发送通知。这个`__inherited`函数接受两个参数:被继承的父类和继承的子类。 | 3555 | 此外,当一个类继承自另一个类时,它会尝试调用父类上的 `__inherited` 方法(如果这个方法存在的话),以此来向父类发送通知。这个 `__inherited` 函数接受两个参数:被继承的父类和继承的子类。 |
| 2881 | 3556 | ||
| 2882 | ```moonscript | 3557 | ```moonscript |
| 2883 | class Shelf | 3558 | class Shelf |
| @@ -2900,15 +3575,15 @@ class Cupboard extends Shelf | |||
| 2900 | 3575 | ||
| 2901 | ### super 关键字 | 3576 | ### super 关键字 |
| 2902 | 3577 | ||
| 2903 | `super`是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 | 3578 | `super` 是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 |
| 2904 | 3579 | ||
| 2905 | 当`super`被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的`self`会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。 | 3580 | 当 `super` 被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的 `self` 会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。 |
| 2906 | 3581 | ||
| 2907 | 在将`super`当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。 | 3582 | 在将 `super` 当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。 |
| 2908 | 3583 | ||
| 2909 | 此外,当使用`\`操作符与`super`一起使用时,`self`将被插入为第一个参数,而不是使用`super`本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。 | 3584 | 此外,当使用 `\` 操作符与 `super` 一起使用时,`self`将被插入为第一个参数,而不是使用 `super` 本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。 |
| 2910 | 3585 | ||
| 2911 | 下面是一些使用`super`的不同方法的示例: | 3586 | 下面是一些使用 `super` 的不同方法的示例: |
| 2912 | 3587 | ||
| 2913 | ```moonscript | 3588 | ```moonscript |
| 2914 | class MyClass extends ParentClass | 3589 | class MyClass extends ParentClass |
| @@ -2967,9 +3642,9 @@ print BackPack.size -- 打印 10 | |||
| 2967 | 3642 | ||
| 2968 | 如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。 | 3643 | 如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。 |
| 2969 | 3644 | ||
| 2970 | 需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的“__base”字段。 | 3645 | 需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的 “__base” 字段。 |
| 2971 | 3646 | ||
| 2972 | 此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的“__name”字段中。 | 3647 | 此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的 “__name” 字段中。 |
| 2973 | 3648 | ||
| 2974 | ```moonscript | 3649 | ```moonscript |
| 2975 | print BackPack.__name -- 打印 Backpack | 3650 | print BackPack.__name -- 打印 Backpack |
| @@ -3051,7 +3726,7 @@ print Counter.count -- 输出 2 | |||
| 3051 | 3726 | ||
| 3052 | ### 类声明语句 | 3727 | ### 类声明语句 |
| 3053 | 3728 | ||
| 3054 | 在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self等于类对象,而不是实例对象。 | 3729 | 在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self 等于类对象,而不是实例对象。 |
| 3055 | 3730 | ||
| 3056 | 以下是创建类变量的另一种方法: | 3731 | 以下是创建类变量的另一种方法: |
| 3057 | 3732 | ||
| @@ -3091,9 +3766,9 @@ class MoreThings | |||
| 3091 | 3766 | ||
| 3092 | ### @ 和 @@ 值 | 3767 | ### @ 和 @@ 值 |
| 3093 | 3768 | ||
| 3094 | 当@和@@前缀在一个名字前时,它们分别代表在self和self.\_\_class中访问的那个名字。 | 3769 | 当 @ 和 @@ 前缀在一个名字前时,它们分别代表在 self 和 self.\_\_class 中访问的那个名字。 |
| 3095 | 3770 | ||
| 3096 | 如果它们单独使用,它们是self和self.\_\_class的别名。 | 3771 | 如果它们单独使用,它们是 self 和 self.\_\_class 的别名。 |
| 3097 | 3772 | ||
| 3098 | ```moonscript | 3773 | ```moonscript |
| 3099 | assert @ == self | 3774 | assert @ == self |
| @@ -3106,7 +3781,7 @@ assert @@ == self.__class | |||
| 3106 | </pre> | 3781 | </pre> |
| 3107 | </YueDisplay> | 3782 | </YueDisplay> |
| 3108 | 3783 | ||
| 3109 | 例如,使用@@从实例方法快速创建同一类的新实例的方法: | 3784 | 例如,使用 @@ 从实例方法快速创建同一类的新实例的方法: |
| 3110 | 3785 | ||
| 3111 | ```moonscript | 3786 | ```moonscript |
| 3112 | some_instance_method = (...) => @@ ... | 3787 | some_instance_method = (...) => @@ ... |
| @@ -3184,7 +3859,7 @@ x = class Bucket | |||
| 3184 | 3859 | ||
| 3185 | ### 匿名类 | 3860 | ### 匿名类 |
| 3186 | 3861 | ||
| 3187 | 声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name属性将为nil。如果出现在赋值语句中,赋值操作左侧的名称将代替nil。 | 3862 | 声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name 属性将为 nil。如果出现在赋值语句中,赋值操作左侧的名称将代替 nil。 |
| 3188 | 3863 | ||
| 3189 | ```moonscript | 3864 | ```moonscript |
| 3190 | BigBucket = class extends Bucket | 3865 | BigBucket = class extends Bucket |
| @@ -3214,7 +3889,7 @@ x = class | |||
| 3214 | 3889 | ||
| 3215 | ### 类混合 | 3890 | ### 类混合 |
| 3216 | 3891 | ||
| 3217 | 您可以通过使用 `using` 关键字来实现类混合。这意味着您可以从一个普通 Lua 表格或已定义的类对象中,复制函数到您创建的新类中。当您使用普通 Lua 表格进行类混合时,您有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当您从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 | 3892 | 你可以通过使用 `using` 关键字来实现类混合。这意味着你可以从一个普通 Lua 表格或已定义的类对象中,复制函数到你创建的新类中。当你使用普通 Lua 表格进行类混合时,你有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当你从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 |
| 3218 | 3893 | ||
| 3219 | ```moonscript | 3894 | ```moonscript |
| 3220 | MyIndex = __index: var: 1 | 3895 | MyIndex = __index: var: 1 |
| @@ -3255,11 +3930,11 @@ assert y.__class.__parent ~= X -- X 不是 Y 的父类 | |||
| 3255 | 3930 | ||
| 3256 | ## with 语句 | 3931 | ## with 语句 |
| 3257 | 3932 | ||
| 3258 | 在编写Lua代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。 | 3933 | 在编写 Lua 代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。 |
| 3259 | 3934 | ||
| 3260 | 这导致在代码中多次重复引用对象的名称,增加了不必要的文本噪音。一个常见的解决方案是在创建对象时,在构造函数传入一个表,该表包含要覆盖设置的键和值的集合。这样做的缺点是该对象的构造函数必须支持这种初始化形式。 | 3935 | 这导致在代码中多次重复引用对象的名称,增加了不必要的文本噪音。一个常见的解决方案是在创建对象时,在构造函数传入一个表,该表包含要覆盖设置的键和值的集合。这样做的缺点是该对象的构造函数必须支持这种初始化形式。 |
| 3261 | 3936 | ||
| 3262 | with块有助于简化编写这样的代码。在with块内,我们可以使用以.或\开头的特殊语句,这些语句代表我们正在使用的对象的操作。 | 3937 | with 块有助于简化编写这样的代码。在 with 块内,我们可以使用以 . 或 \ 开头的特殊语句,这些语句代表我们正在使用的对象的操作。 |
| 3263 | 3938 | ||
| 3264 | 例如,我们可以这样处理一个新创建的对象: | 3939 | 例如,我们可以这样处理一个新创建的对象: |
| 3265 | 3940 | ||
| @@ -3280,7 +3955,7 @@ with Person! | |||
| 3280 | </pre> | 3955 | </pre> |
| 3281 | </YueDisplay> | 3956 | </YueDisplay> |
| 3282 | 3957 | ||
| 3283 | with语句也可以用作一个表达式,并返回它的代码块正在处理的对象。 | 3958 | with 语句也可以用作一个表达式,并返回它的代码块正在处理的对象。 |
| 3284 | 3959 | ||
| 3285 | ```moonscript | 3960 | ```moonscript |
| 3286 | file = with File "favorite_foods.txt" | 3961 | file = with File "favorite_foods.txt" |
| @@ -3314,24 +3989,24 @@ me = create_person "Leaf", [dad, mother, sister] | |||
| 3314 | </pre> | 3989 | </pre> |
| 3315 | </YueDisplay> | 3990 | </YueDisplay> |
| 3316 | 3991 | ||
| 3317 | 在此用法中,with可以被视为K组合子(k-combinator)的一种特殊形式。 | 3992 | 在此用法中,with 可以被视为K组合子(k-combinator)的一种特殊形式。 |
| 3318 | 3993 | ||
| 3319 | 如果给表达式另外起一个名称的话,with语句中的表达式也可以是一个赋值语句。 | 3994 | 如果你想给表达式另外起一个名称的话,with 语句中的表达式也可以是一个赋值语句。 |
| 3320 | 3995 | ||
| 3321 | ```moonscript | 3996 | ```moonscript |
| 3322 | with str = "你好" | 3997 | with str := "你好" |
| 3323 | print "原始:", str | 3998 | print "原始:", str |
| 3324 | print "大写:", \upper! | 3999 | print "大写:", \upper! |
| 3325 | ``` | 4000 | ``` |
| 3326 | <YueDisplay> | 4001 | <YueDisplay> |
| 3327 | <pre> | 4002 | <pre> |
| 3328 | with str = "你好" | 4003 | with str := "你好" |
| 3329 | print "原始:", str | 4004 | print "原始:", str |
| 3330 | print "大写:", \upper! | 4005 | print "大写:", \upper! |
| 3331 | </pre> | 4006 | </pre> |
| 3332 | </YueDisplay> | 4007 | </YueDisplay> |
| 3333 | 4008 | ||
| 3334 | 在with语句中可用`[]`访问特殊键。 | 4009 | 你以 `with` 语句中使用 `[]` 访问特殊键。 |
| 3335 | 4010 | ||
| 3336 | ```moonscript | 4011 | ```moonscript |
| 3337 | with tb | 4012 | with tb |
| @@ -3354,9 +4029,22 @@ with tb | |||
| 3354 | </pre> | 4029 | </pre> |
| 3355 | </YueDisplay> | 4030 | </YueDisplay> |
| 3356 | 4031 | ||
| 4032 | `with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。 | ||
| 4033 | |||
| 4034 | ```moonscript | ||
| 4035 | with? obj | ||
| 4036 | print obj.name | ||
| 4037 | ``` | ||
| 4038 | <YueDisplay> | ||
| 4039 | <pre> | ||
| 4040 | with? obj | ||
| 4041 | print obj.name | ||
| 4042 | </pre> | ||
| 4043 | </YueDisplay> | ||
| 4044 | |||
| 3357 | ## do 语句 | 4045 | ## do 语句 |
| 3358 | 4046 | ||
| 3359 | 当用作语句时,do语句的作用就像在Lua中差不多。 | 4047 | 当用作语句时,do 语句的作用就像在 Lua 中差不多。 |
| 3360 | 4048 | ||
| 3361 | ```moonscript | 4049 | ```moonscript |
| 3362 | do | 4050 | do |
| @@ -3373,7 +4061,7 @@ print var -- 这里是nil | |||
| 3373 | </pre> | 4061 | </pre> |
| 3374 | </YueDisplay> | 4062 | </YueDisplay> |
| 3375 | 4063 | ||
| 3376 | 月之脚本的 **do** 也可以用作表达式。允许您将多行代码的处理合并为一个表达式,并将do语句代码块的最后一个语句作为表达式返回的结果。 | 4064 | 月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将 do 语句代码块的最后一个语句作为表达式返回的结果。 |
| 3377 | 4065 | ||
| 3378 | ```moonscript | 4066 | ```moonscript |
| 3379 | counter = do | 4067 | counter = do |
| @@ -3557,7 +4245,7 @@ print i, k -- 这些已经被更新 | |||
| 3557 | 4245 | ||
| 3558 | ## 月之脚本语言库 | 4246 | ## 月之脚本语言库 |
| 3559 | 4247 | ||
| 3560 | 使用`require("yue")`来访问。 | 4248 | 使用 `require("yue")` 来访问。 |
| 3561 | 4249 | ||
| 3562 | ### yue | 4250 | ### yue |
| 3563 | 4251 | ||
| @@ -3615,9 +4303,9 @@ yue_compiled: {string: string} | |||
| 3615 | **签名:** | 4303 | **签名:** |
| 3616 | ```lua | 4304 | ```lua |
| 3617 | to_lua: function(code: string, config?: Config): | 4305 | to_lua: function(code: string, config?: Config): |
| 3618 | --[[codes]] string | nil, | 4306 | --[[codes]] string | nil, |
| 3619 | --[[error]] string | nil, | 4307 | --[[error]] string | nil, |
| 3620 | --[[globals]] {{string, integer, integer}} | nil | 4308 | --[[globals]] {{string, integer, integer}} | nil |
| 3621 | ``` | 4309 | ``` |
| 3622 | 4310 | ||
| 3623 | **参数:** | 4311 | **参数:** |
| @@ -3740,8 +4428,8 @@ remove_loader: function(): boolean | |||
| 3740 | **签名:** | 4428 | **签名:** |
| 3741 | ```lua | 4429 | ```lua |
| 3742 | loadstring: function(input: string, chunkname: string, env: table, config?: Config): | 4430 | loadstring: function(input: string, chunkname: string, env: table, config?: Config): |
| 3743 | --[[loaded function]] nil | function(...: any): (any...), | 4431 | --[[loaded function]] nil | function(...: any): (any...), |
| 3744 | --[[error]] string | nil | 4432 | --[[error]] string | nil |
| 3745 | ``` | 4433 | ``` |
| 3746 | 4434 | ||
| 3747 | **参数:** | 4435 | **参数:** |
| @@ -3771,8 +4459,8 @@ loadstring: function(input: string, chunkname: string, env: table, config?: Conf | |||
| 3771 | **签名:** | 4459 | **签名:** |
| 3772 | ```lua | 4460 | ```lua |
| 3773 | loadstring: function(input: string, chunkname: string, config?: Config): | 4461 | loadstring: function(input: string, chunkname: string, config?: Config): |
| 3774 | --[[loaded function]] nil | function(...: any): (any...), | 4462 | --[[loaded function]] nil | function(...: any): (any...), |
| 3775 | --[[error]] string | nil | 4463 | --[[error]] string | nil |
| 3776 | ``` | 4464 | ``` |
| 3777 | 4465 | ||
| 3778 | **参数:** | 4466 | **参数:** |
| @@ -3801,8 +4489,8 @@ loadstring: function(input: string, chunkname: string, config?: Config): | |||
| 3801 | **签名:** | 4489 | **签名:** |
| 3802 | ```lua | 4490 | ```lua |
| 3803 | loadstring: function(input: string, config?: Config): | 4491 | loadstring: function(input: string, config?: Config): |
| 3804 | --[[loaded function]] nil | function(...: any): (any...), | 4492 | --[[loaded function]] nil | function(...: any): (any...), |
| 3805 | --[[error]] string | nil | 4493 | --[[error]] string | nil |
| 3806 | ``` | 4494 | ``` |
| 3807 | 4495 | ||
| 3808 | **参数:** | 4496 | **参数:** |
| @@ -3830,8 +4518,8 @@ loadstring: function(input: string, config?: Config): | |||
| 3830 | **签名:** | 4518 | **签名:** |
| 3831 | ```lua | 4519 | ```lua |
| 3832 | loadfile: function(filename: string, env: table, config?: Config): | 4520 | loadfile: function(filename: string, env: table, config?: Config): |
| 3833 | nil | function(...: any): (any...), | 4521 | nil | function(...: any): (any...), |
| 3834 | string | nil | 4522 | string | nil |
| 3835 | ``` | 4523 | ``` |
| 3836 | 4524 | ||
| 3837 | **参数:** | 4525 | **参数:** |
| @@ -3860,8 +4548,8 @@ loadfile: function(filename: string, env: table, config?: Config): | |||
| 3860 | **签名:** | 4548 | **签名:** |
| 3861 | ```lua | 4549 | ```lua |
| 3862 | loadfile: function(filename: string, config?: Config): | 4550 | loadfile: function(filename: string, config?: Config): |
| 3863 | nil | function(...: any): (any...), | 4551 | nil | function(...: any): (any...), |
| 3864 | string | nil | 4552 | string | nil |
| 3865 | ``` | 4553 | ``` |
| 3866 | 4554 | ||
| 3867 | **参数:** | 4555 | **参数:** |
| @@ -4116,9 +4804,9 @@ type AST = {string, integer, integer, any} | |||
| 4116 | 4804 | ||
| 4117 | **签名:** | 4805 | **签名:** |
| 4118 | ```lua | 4806 | ```lua |
| 4119 | to_ast: function(code: string, flattenLevel?: number, astName?: string): | 4807 | to_ast: function(code: string, flattenLevel?: number, astName?: string, reserveComment?: boolean): |
| 4120 | --[[AST]] AST | nil, | 4808 | --[[AST]] AST | nil, |
| 4121 | --[[error]] nil | string | 4809 | --[[error]] nil | string |
| 4122 | ``` | 4810 | ``` |
| 4123 | 4811 | ||
| 4124 | **参数:** | 4812 | **参数:** |
| @@ -4127,6 +4815,42 @@ to_ast: function(code: string, flattenLevel?: number, astName?: string): | |||
| 4127 | | --- | --- | --- | | 4815 | | --- | --- | --- | |
| 4128 | | code | string | 代码。 | | 4816 | | code | string | 代码。 | |
| 4129 | | flattenLevel | integer | [可选] 扁平化级别。级别越高,会消除更多的 AST 结构的嵌套。默认为 0。最大为 2。 | | 4817 | | flattenLevel | integer | [可选] 扁平化级别。级别越高,会消除更多的 AST 结构的嵌套。默认为 0。最大为 2。 | |
| 4818 | | astName | string | [可选] AST 名称。默认为 "File"。 | | ||
| 4819 | | reserveComment | boolean | [可选] 是否保留原始注释。默认为 false。 | | ||
| 4820 | |||
| 4821 | **返回值:** | ||
| 4822 | |||
| 4823 | | 返回类型 | 描述 | | ||
| 4824 | | --- | --- | | ||
| 4825 | | AST \| nil | AST,如果转换失败则为 nil。 | | ||
| 4826 | | string \| nil | 错误消息,如果转换成功则为 nil。 | | ||
| 4827 | |||
| 4828 | #### format | ||
| 4829 | |||
| 4830 | **类型:** 函数。 | ||
| 4831 | |||
| 4832 | **描述:** | ||
| 4833 | |||
| 4834 | 格式化 YueScript 代码。 | ||
| 4835 | |||
| 4836 | **签名:** | ||
| 4837 | ```lua | ||
| 4838 | format: function(code: string, tabSize?: number, reserveComment?: boolean): string | ||
| 4839 | ``` | ||
| 4840 | |||
| 4841 | **参数:** | ||
| 4842 | |||
| 4843 | | 参数名 | 类型 | 描述 | | ||
| 4844 | | --- | --- | --- | | ||
| 4845 | | code | string | 代码。 | | ||
| 4846 | | tabSize | integer | [可选] 制表符大小。默认为 4。 | | ||
| 4847 | | reserveComment | boolean | [可选] 是否保留原始注释。默认为 true。 | | ||
| 4848 | |||
| 4849 | **返回值:** | ||
| 4850 | |||
| 4851 | | 返回类型 | 描述 | | ||
| 4852 | | --- | --- | | ||
| 4853 | | string | 格式化后的代码。 | | ||
| 4130 | 4854 | ||
| 4131 | #### __call | 4855 | #### __call |
| 4132 | 4856 | ||
| @@ -4199,6 +4923,19 @@ implicit_return_root: boolean | |||
| 4199 | reserve_line_number: boolean | 4923 | reserve_line_number: boolean |
| 4200 | ``` | 4924 | ``` |
| 4201 | 4925 | ||
| 4926 | #### reserve_comment | ||
| 4927 | |||
| 4928 | **类型:** 成员变量。 | ||
| 4929 | |||
| 4930 | **描述:** | ||
| 4931 | |||
| 4932 | 编译器是否应该在编译后的代码中保留原始注释。 | ||
| 4933 | |||
| 4934 | **签名:** | ||
| 4935 | ```lua | ||
| 4936 | reserve_comment: boolean | ||
| 4937 | ``` | ||
| 4938 | |||
| 4202 | #### space_over_tab | 4939 | #### space_over_tab |
| 4203 | 4940 | ||
| 4204 | **类型:** 成员变量。 | 4941 | **类型:** 成员变量。 |
| @@ -4249,11 +4986,11 @@ line_offset: integer | |||
| 4249 | **签名:** | 4986 | **签名:** |
| 4250 | ```lua | 4987 | ```lua |
| 4251 | enum LuaTarget | 4988 | enum LuaTarget |
| 4252 | "5.1" | 4989 | "5.1" |
| 4253 | "5.2" | 4990 | "5.2" |
| 4254 | "5.3" | 4991 | "5.3" |
| 4255 | "5.4" | 4992 | "5.4" |
| 4256 | "5.5" | 4993 | "5.5" |
| 4257 | end | 4994 | end |
| 4258 | ``` | 4995 | ``` |
| 4259 | 4996 | ||
| @@ -4332,8 +5069,8 @@ simplified: boolean | |||
| 4332 | 5069 | ||
| 4333 | 版权 (c) 2017-2025 李瑾 \<dragon-fly@qq.com\> | 5070 | 版权 (c) 2017-2025 李瑾 \<dragon-fly@qq.com\> |
| 4334 | 5071 | ||
| 4335 | 特此免费授予任何获得本软件副本和相关文档文件(下称“软件”)的人不受限制地处置该软件的权利,包括不受限制地使用、复制、修改、合并、发布、分发、转授许可和/或出售该软件副本,以及再授权被配发了本软件的人如上的权利,须在下列条件下: | 5072 | 特此免费授予任何获得本软件副本和相关文档文件(下称“软件”)的人不受限制地处置该软件的权利,包括不受限制地使用、复制、修改、合并、发布、分发、转授许可和/或出售该软件副本,以及再授权被配发了本软件的人如上的权利,须在下列条件下: |
| 4336 | 上述版权声明和本许可声明应包含在该软件的所有副本或实质成分中。 | 5073 | 上述版权声明和本许可声明应包含在该软件的所有副本或实质成分中。 |
| 4337 | 本软件是“如此”提供的,没有任何形式的明示或暗示的保证,包括但不限于对适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有人都不对任何索赔、损害或其他责任负责,无论这些追责来自合同、侵权或其它行为中,还是产生于、源于或有关于本软件以及本软件的使用或其它处置。 | 5074 | 本软件是“如此”提供的,没有任何形式的明示或暗示的保证,包括但不限于对适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有人都不对任何索赔、损害或其他责任负责,无论这些追责来自合同、侵权或其它行为中,还是产生于、源于或有关于本软件以及本软件的使用或其它处置。 |
| 4338 | 5075 | ||
| 4339 | <CompilerModal /> | 5076 | <CompilerModal /> |
