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 | 923 |
2 files changed, 724 insertions, 201 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 2968f6e..de5dff1 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
| @@ -9,24 +9,24 @@ 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 | -- 列表推导 | 32 | -- 列表推导 |
| @@ -61,17 +61,17 @@ export 🌛 = "月之脚本" | |||
| 61 | <YueDisplay> | 61 | <YueDisplay> |
| 62 | <pre> | 62 | <pre> |
| 63 | -- 导入语法 | 63 | -- 导入语法 |
| 64 | import "yue" as :p, :to_lua | 64 | import p, to_lua from "yue" |
| 65 | 65 | ||
| 66 | -- 隐式对象 | 66 | -- 隐式对象 |
| 67 | inventory = | 67 | inventory = |
| 68 | equipment: | 68 | equipment: |
| 69 | * "sword" | 69 | - "sword" |
| 70 | * "shield" | 70 | - "shield" |
| 71 | items: | 71 | items: |
| 72 | * name: "potion" | 72 | - name: "potion" |
| 73 | count: 10 | 73 | count: 10 |
| 74 | * name: "bread" | 74 | - name: "bread" |
| 75 | count: 3 | 75 | count: 3 |
| 76 | 76 | ||
| 77 | -- 列表推导 | 77 | -- 列表推导 |
| @@ -109,7 +109,7 @@ export 🌛 = "月之脚本" | |||
| 109 | 109 | ||
| 110 | * **Lua 模块** | 110 | * **Lua 模块** |
| 111 | 111 | ||
| 112 |  安装 [luarocks](https://luarocks.org),一个Lua模块的包管理器。然后作为Lua模块和可执行文件安装它: | 112 |  安装 [luarocks](https://luarocks.org),一个 Lua 模块的包管理器。然后作为 Lua 模块和可执行文件安装它: |
| 113 | 113 | ||
| 114 | ``` | 114 | ``` |
| 115 | > luarocks install yuescript | 115 | > luarocks install yuescript |
| @@ -150,14 +150,14 @@ export 🌛 = "月之脚本" | |||
| 150 | 150 | ||
| 151 | ### Lua 模块 | 151 | ### Lua 模块 |
| 152 | 152 | ||
| 153 | 在Lua中使用月之脚本模块: | 153 | 在 Lua 中使用月之脚本模块: |
| 154 | 154 | ||
| 155 | * **用法 1** | 155 | * **用法 1** |
| 156 | 在Lua中引入 "你的脚本入口文件.yue"。 | 156 | 在 Lua 中引入 "你的脚本入口文件.yue"。 |
| 157 | ```Lua | 157 | ```Lua |
| 158 | require("yue")("你的脚本入口文件") | 158 | require("yue")("你的脚本入口文件") |
| 159 | ``` | 159 | ``` |
| 160 | 当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import**进行脚本引用即可。错误消息中的代码行号也会被正确处理。 | 160 | 当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import** 进行脚本引用即可。错误消息中的代码行号也会被正确处理。 |
| 161 | 161 | ||
| 162 | * **用法 2** | 162 | * **用法 2** |
| 163 | 手动引入月之脚本模块并重写错误消息来帮助调试。 | 163 | 手动引入月之脚本模块并重写错误消息来帮助调试。 |
| @@ -172,7 +172,7 @@ end) | |||
| 172 | ``` | 172 | ``` |
| 173 | 173 | ||
| 174 | * **用法 3** | 174 | * **用法 3** |
| 175 | 在Lua中使用月之脚本编译器功能。 | 175 | 在 Lua 中使用月之脚本编译器功能。 |
| 176 | ```lua | 176 | ```lua |
| 177 | local yue = require("yue") | 177 | local yue = require("yue") |
| 178 | local codes, err, globals = yue.to_lua([[ | 178 | local codes, err, globals = yue.to_lua([[ |
| @@ -222,12 +222,12 @@ f! | |||
| 222 | 不添加任何选项执行命令可以进入REPL模式, | 222 | 不添加任何选项执行命令可以进入REPL模式, |
| 223 | 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式 | 223 | 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式 |
| 224 | ``` | 224 | ``` |
| 225 |   使用案例: | 225 |   使用案例: |
| 226 |   递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .** | 226 |   递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .** |
| 227 |   编译并将结果保存到目标路径: **yue -t /target/path/ .** | 227 |   编译并将结果保存到目标路径: **yue -t /target/path/ .** |
| 228 |   编译并保留调试信息: **yue -l .** | 228 |   编译并保留调试信息: **yue -l .** |
| 229 |   编译并生成压缩代码: **yue -m .** | 229 |   编译并生成压缩代码: **yue -m .** |
| 230 |   直接执行代码: **yue -e 'print 123'** | 230 |   直接执行代码: **yue -e 'print 123'** |
| 231 |   执行一个月之脚本文件: **yue -e main.yue** | 231 |   执行一个月之脚本文件: **yue -e main.yue** |
| 232 | 232 | ||
| 233 | ## 宏 | 233 | ## 宏 |
| @@ -407,16 +407,16 @@ print $LINE -- 获取当前代码行数:2 | |||
| 407 | 407 | ||
| 408 | ```moonscript | 408 | ```moonscript |
| 409 | macro Enum = (...) -> | 409 | macro Enum = (...) -> |
| 410 | items = {...} | 410 | items = {...} |
| 411 | itemSet = {item, true for item in *items} | 411 | itemSet = {item, true for item in *items} |
| 412 | (item) -> | 412 | (item) -> |
| 413 | 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] |
| 414 | "\"#{item}\"" | 414 | "\"#{item}\"" |
| 415 | 415 | ||
| 416 | macro BodyType = $Enum( | 416 | macro BodyType = $Enum( |
| 417 | Static | 417 | Static |
| 418 | Dynamic | 418 | Dynamic |
| 419 | Kinematic | 419 | Kinematic |
| 420 | ) | 420 | ) |
| 421 | 421 | ||
| 422 | print "有效的枚举类型:", $BodyType Static | 422 | print "有效的枚举类型:", $BodyType Static |
| @@ -425,16 +425,16 @@ print "有效的枚举类型:", $BodyType Static | |||
| 425 | <YueDisplay> | 425 | <YueDisplay> |
| 426 | <pre> | 426 | <pre> |
| 427 | macro Enum = (...) -> | 427 | macro Enum = (...) -> |
| 428 | items = {...} | 428 | items = {...} |
| 429 | itemSet = {item, true for item in *items} | 429 | itemSet = {item, true for item in *items} |
| 430 | (item) -> | 430 | (item) -> |
| 431 | 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] |
| 432 | "\"#{item}\"" | 432 | "\"#{item}\"" |
| 433 | 433 | ||
| 434 | macro BodyType = $Enum( | 434 | macro BodyType = $Enum( |
| 435 | Static | 435 | Static |
| 436 | Dynamic | 436 | Dynamic |
| 437 | Kinematic | 437 | Kinematic |
| 438 | ) | 438 | ) |
| 439 | 439 | ||
| 440 | print "有效的枚举类型:", $BodyType Static | 440 | print "有效的枚举类型:", $BodyType Static |
| @@ -442,9 +442,57 @@ print "有效的枚举类型:", $BodyType Static | |||
| 442 | </pre> | 442 | </pre> |
| 443 | </YueDisplay> | 443 | </YueDisplay> |
| 444 | 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 | |||
| 445 | ## 操作符 | 493 | ## 操作符 |
| 446 | 494 | ||
| 447 | Lua的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 | 495 | Lua 的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 |
| 448 | 496 | ||
| 449 | ```moonscript | 497 | ```moonscript |
| 450 | tb\func! if tb ~= nil | 498 | tb\func! if tb ~= nil |
| @@ -484,56 +532,56 @@ print 1 <= a <= 10 | |||
| 484 | 532 | ||
| 485 | ```moonscript | 533 | ```moonscript |
| 486 | v = (x) -> | 534 | v = (x) -> |
| 487 | print x | 535 | print x |
| 488 | x | 536 | x |
| 489 | 537 | ||
| 490 | print v(1) < v(2) <= v(3) | 538 | print v(1) < v(2) <= v(3) |
| 491 | --[[ | 539 | --[[ |
| 492 | 输出: | 540 | 输出: |
| 493 | 2 | 541 | 2 |
| 494 | 1 | 542 | 1 |
| 495 | 3 | 543 | 3 |
| 496 | true | 544 | true |
| 497 | ]] | 545 | ]] |
| 498 | 546 | ||
| 499 | print v(1) > v(2) <= v(3) | 547 | print v(1) > v(2) <= v(3) |
| 500 | --[[ | 548 | --[[ |
| 501 | 输出: | 549 | 输出: |
| 502 | 2 | 550 | 2 |
| 503 | 1 | 551 | 1 |
| 504 | false | 552 | false |
| 505 | ]] | 553 | ]] |
| 506 | ``` | 554 | ``` |
| 507 | <YueDisplay> | 555 | <YueDisplay> |
| 508 | <pre> | 556 | <pre> |
| 509 | v = (x) -> | 557 | v = (x) -> |
| 510 | print x | 558 | print x |
| 511 | x | 559 | x |
| 512 | 560 | ||
| 513 | print v(1) < v(2) <= v(3) | 561 | print v(1) < v(2) <= v(3) |
| 514 | --[[ | 562 | --[[ |
| 515 | 输出: | 563 | 输出: |
| 516 | 2 | 564 | 2 |
| 517 | 1 | 565 | 1 |
| 518 | 3 | 566 | 3 |
| 519 | true | 567 | true |
| 520 | ]] | 568 | ]] |
| 521 | 569 | ||
| 522 | print v(1) > v(2) <= v(3) | 570 | print v(1) > v(2) <= v(3) |
| 523 | --[[ | 571 | --[[ |
| 524 | 输出: | 572 | 输出: |
| 525 | 2 | 573 | 2 |
| 526 | 1 | 574 | 1 |
| 527 | false | 575 | false |
| 528 | ]] | 576 | ]] |
| 529 | </pre> | 577 | </pre> |
| 530 | </YueDisplay> | 578 | </YueDisplay> |
| 531 | 579 | ||
| 532 | 在上面的例子里,中间的表达式`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` 运算符来做连接。 |
| 533 | 581 | ||
| 534 | ### 表追加 | 582 | ### 表追加 |
| 535 | 583 | ||
| 536 | **[] =** 操作符用于向Lua表的最后插入值。 | 584 | **[] =** 操作符用于向 Lua 表的最后插入值。 |
| 537 | 585 | ||
| 538 | ```moonscript | 586 | ```moonscript |
| 539 | tab = [] | 587 | tab = [] |
| @@ -546,19 +594,36 @@ tab[] = "Value" | |||
| 546 | </pre> | 594 | </pre> |
| 547 | </YueDisplay> | 595 | </YueDisplay> |
| 548 | 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 | |||
| 549 | ### 表扩展 | 614 | ### 表扩展 |
| 550 | 615 | ||
| 551 | 你可以使用前置 `...` 操作符在Lua表中插入数组表或哈希表。 | 616 | 你可以使用前置 `...` 操作符在 Lua 表中插入数组表或哈希表。 |
| 552 | 617 | ||
| 553 | ```moonscript | 618 | ```moonscript |
| 554 | parts = | 619 | parts = |
| 555 | * "shoulders" | 620 | * "shoulders" |
| 556 | * "knees" | 621 | * "knees" |
| 557 | lyrics = | 622 | lyrics = |
| 558 | * "head" | 623 | * "head" |
| 559 | * ...parts | 624 | * ...parts |
| 560 | * "and" | 625 | * "and" |
| 561 | * "toes" | 626 | * "toes" |
| 562 | 627 | ||
| 563 | copy = {...other} | 628 | copy = {...other} |
| 564 | 629 | ||
| @@ -569,13 +634,13 @@ merge = {...a, ...b} | |||
| 569 | <YueDisplay> | 634 | <YueDisplay> |
| 570 | <pre> | 635 | <pre> |
| 571 | parts = | 636 | parts = |
| 572 | * "shoulders" | 637 | * "shoulders" |
| 573 | * "knees" | 638 | * "knees" |
| 574 | lyrics = | 639 | lyrics = |
| 575 | * "head" | 640 | * "head" |
| 576 | * ...parts | 641 | * ...parts |
| 577 | * "and" | 642 | * "and" |
| 578 | * "toes" | 643 | * "toes" |
| 579 | 644 | ||
| 580 | copy = {...other} | 645 | copy = {...other} |
| 581 | 646 | ||
| @@ -585,12 +650,29 @@ merge = {...a, ...b} | |||
| 585 | </pre> | 650 | </pre> |
| 586 | </YueDisplay> | 651 | </YueDisplay> |
| 587 | 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 | |||
| 588 | ### 元表 | 670 | ### 元表 |
| 589 | 671 | ||
| 590 | **<>** 操作符可提供元表操作的快捷方式。 | 672 | **<>** 操作符可提供元表操作的快捷方式。 |
| 591 | 673 | ||
| 592 | * **元表创建** | 674 | * **元表创建** |
| 593 | 使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的Lua表。 | 675 | 使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的 Lua 表。 |
| 594 | 676 | ||
| 595 | ```moonscript | 677 | ```moonscript |
| 596 | mt = {} | 678 | mt = {} |
| @@ -732,7 +814,7 @@ readFile "example.txt" | |||
| 732 | 814 | ||
| 733 | ### 空值合并 | 815 | ### 空值合并 |
| 734 | 816 | ||
| 735 | 如果其左操作数不是**nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非nil的值,**??** 运算符将不再计算其右操作数。 | 817 | 如果其左操作数不是 **nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非 nil 的值,**??** 运算符将不再计算其右操作数。 |
| 736 | ```moonscript | 818 | ```moonscript |
| 737 | local a, b, c, d | 819 | local a, b, c, d |
| 738 | a = b ?? c ?? d | 820 | a = b ?? c ?? d |
| @@ -751,67 +833,87 @@ a ??= false | |||
| 751 | 833 | ||
| 752 | ### 隐式对象 | 834 | ### 隐式对象 |
| 753 | 835 | ||
| 754 | 你可以在表格块内使用符号 **\*** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。 | 836 | 你可以在表格块内使用符号 **\*** 或是 **-** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。 |
| 837 | |||
| 755 | ```moonscript | 838 | ```moonscript |
| 839 | -- 赋值时使用隐式对象 | ||
| 756 | list = | 840 | list = |
| 757 | * 1 | 841 | * 1 |
| 758 | * 2 | 842 | * 2 |
| 759 | * 3 | 843 | * 3 |
| 760 | 844 | ||
| 845 | -- 函数调用时使用隐式对象 | ||
| 761 | func | 846 | func |
| 762 | * 1 | 847 | * 1 |
| 763 | * 2 | 848 | * 2 |
| 764 | * 3 | 849 | * 3 |
| 765 | 850 | ||
| 851 | -- 返回时使用隐式对象 | ||
| 852 | f = -> | ||
| 853 | return | ||
| 854 | * 1 | ||
| 855 | * 2 | ||
| 856 | * 3 | ||
| 857 | |||
| 858 | -- 表格时使用隐式对象 | ||
| 766 | tb = | 859 | tb = |
| 767 | name: "abc" | 860 | name: "abc" |
| 768 | 861 | ||
| 769 | values: | 862 | values: |
| 770 | * "a" | 863 | - "a" |
| 771 | * "b" | 864 | - "b" |
| 772 | * "c" | 865 | - "c" |
| 773 | 866 | ||
| 774 | objects: | 867 | objects: |
| 775 | * name: "a" | 868 | - name: "a" |
| 776 | value: 1 | 869 | value: 1 |
| 777 | func: => @value + 1 | 870 | func: => @value + 1 |
| 778 | tb: | 871 | tb: |
| 779 | fieldA: 1 | 872 | fieldA: 1 |
| 780 | 873 | ||
| 781 | * name: "b" | 874 | - name: "b" |
| 782 | value: 2 | 875 | value: 2 |
| 783 | func: => @value + 2 | 876 | func: => @value + 2 |
| 784 | tb: { } | 877 | tb: { } |
| 785 | |||
| 786 | ``` | 878 | ``` |
| 787 | <YueDisplay> | 879 | <YueDisplay> |
| 788 | <pre> | 880 | <pre> |
| 881 | -- 赋值时使用隐式对象 | ||
| 789 | list = | 882 | list = |
| 790 | * 1 | 883 | * 1 |
| 791 | * 2 | 884 | * 2 |
| 792 | * 3 | 885 | * 3 |
| 793 | 886 | ||
| 887 | -- 函数调用时使用隐式对象 | ||
| 794 | func | 888 | func |
| 795 | * 1 | 889 | * 1 |
| 796 | * 2 | 890 | * 2 |
| 797 | * 3 | 891 | * 3 |
| 798 | 892 | ||
| 893 | -- 返回时使用隐式对象 | ||
| 894 | f = -> | ||
| 895 | return | ||
| 896 | * 1 | ||
| 897 | * 2 | ||
| 898 | * 3 | ||
| 899 | |||
| 900 | -- 表格时使用隐式对象 | ||
| 799 | tb = | 901 | tb = |
| 800 | name: "abc" | 902 | name: "abc" |
| 801 | 903 | ||
| 802 | values: | 904 | values: |
| 803 | * "a" | 905 | - "a" |
| 804 | * "b" | 906 | - "b" |
| 805 | * "c" | 907 | - "c" |
| 806 | 908 | ||
| 807 | objects: | 909 | objects: |
| 808 | * name: "a" | 910 | - name: "a" |
| 809 | value: 1 | 911 | value: 1 |
| 810 | func: => @value + 1 | 912 | func: => @value + 1 |
| 811 | tb: | 913 | tb: |
| 812 | fieldA: 1 | 914 | fieldA: 1 |
| 813 | 915 | ||
| 814 | * name: "b" | 916 | - name: "b" |
| 815 | value: 2 | 917 | value: 2 |
| 816 | func: => @value + 2 | 918 | func: => @value + 2 |
| 817 | tb: { } | 919 | tb: { } |
| @@ -991,7 +1093,7 @@ export default -> | |||
| 991 | 1093 | ||
| 992 | ## 赋值 | 1094 | ## 赋值 |
| 993 | 1095 | ||
| 994 | 月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过**local**和**global**声明来改变声明变量的作用范围。 | 1096 | 月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过 **local** 和 **global** 声明来改变声明变量的作用范围。 |
| 995 | 1097 | ||
| 996 | ```moonscript | 1098 | ```moonscript |
| 997 | hello = "world" | 1099 | hello = "world" |
| @@ -1120,9 +1222,9 @@ do | |||
| 1120 | 1222 | ||
| 1121 | ## 解构赋值 | 1223 | ## 解构赋值 |
| 1122 | 1224 | ||
| 1123 | 解构赋值是一种快速从Lua表中按名称或基于数组中的位置提取值的方法。 | 1225 | 解构赋值是一种快速从 Lua 表中按名称或基于数组中的位置提取值的方法。 |
| 1124 | 1226 | ||
| 1125 | 通常当你看到一个字面量的Lua表,比如{1,2,3},它位于赋值的右侧,因为它是一个值。解构赋值语句的写法就是交换了字面量Lua表的角色,并将其放在赋值语句的左侧。 | 1227 | 通常当你看到一个字面量的 Lua 表,比如 `{1,2,3}`,它位于赋值的右侧,因为它是一个值。解构赋值语句的写法就是交换了字面量 Lua 表的角色,并将其放在赋值语句的左侧。 |
| 1126 | 1228 | ||
| 1127 | 最好是通过示例来解释。以下是如何从表格中解包前两个值的方法: | 1229 | 最好是通过示例来解释。以下是如何从表格中解包前两个值的方法: |
| 1128 | 1230 | ||
| @@ -1221,7 +1323,7 @@ print first, second, color | |||
| 1221 | </pre> | 1323 | </pre> |
| 1222 | </YueDisplay> | 1324 | </YueDisplay> |
| 1223 | 1325 | ||
| 1224 | 有时候我们会需要从Lua表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: | 1326 | 有时候我们会需要从 Lua 表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: |
| 1225 | 1327 | ||
| 1226 | ```moonscript | 1328 | ```moonscript |
| 1227 | {:concat, :insert} = table | 1329 | {:concat, :insert} = table |
| @@ -1265,9 +1367,55 @@ print first, second, color | |||
| 1265 | </pre> | 1367 | </pre> |
| 1266 | </YueDisplay> | 1368 | </YueDisplay> |
| 1267 | 1369 | ||
| 1268 | ### 在其它地方的解构 | 1370 | ### 范围解构 |
| 1371 | |||
| 1372 | 你可以使用展开运算符 `...` 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。 | ||
| 1373 | |||
| 1374 | ```moonscript | ||
| 1375 | orders = ["first", "second", "third", "fourth", "last"] | ||
| 1376 | [first, ...bulk, last] = orders | ||
| 1377 | print first -- 打印: first | ||
| 1378 | print bulk -- 打印: {"second", "third", "fourth"} | ||
| 1379 | print last -- 打印: last | ||
| 1380 | ``` | ||
| 1381 | <YueDisplay> | ||
| 1382 | <pre> | ||
| 1383 | orders = ["first", "second", "third", "fourth", "last"] | ||
| 1384 | [first, ...bulk, last] = orders | ||
| 1385 | print first -- 打印: first | ||
| 1386 | print bulk -- 打印: {"second", "third", "fourth"} | ||
| 1387 | print last -- 打印: last | ||
| 1388 | </pre> | ||
| 1389 | </YueDisplay> | ||
| 1269 | 1390 | ||
| 1270 | 解构也可以出现在其它隐式进行赋值的地方。一个例子是用在for循环: | 1391 | 展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 `_` 作为占位符来表示你想跳过对应范围的捕获: |
| 1392 | |||
| 1393 | ```moonscript | ||
| 1394 | -- 捕获第一个元素之后的所有元素 | ||
| 1395 | [first, ...rest] = orders | ||
| 1396 | |||
| 1397 | -- 捕获最后一个元素之前的所有元素 | ||
| 1398 | [...start, last] = orders | ||
| 1399 | |||
| 1400 | -- 跳过中间的元素,只捕获第一个和最后一个元素 | ||
| 1401 | [first, ..._, last] = orders | ||
| 1402 | ``` | ||
| 1403 | <YueDisplay> | ||
| 1404 | <pre> | ||
| 1405 | -- 捕获第一个元素之后的所有元素 | ||
| 1406 | [first, ...rest] = orders | ||
| 1407 | |||
| 1408 | -- 捕获最后一个元素之前的所有元素 | ||
| 1409 | [...start, last] = orders | ||
| 1410 | |||
| 1411 | -- 跳过中间的元素,只捕获第一个和最后一个元素 | ||
| 1412 | [first, ..._, last] = orders | ||
| 1413 | </pre> | ||
| 1414 | </YueDisplay> | ||
| 1415 | |||
| 1416 | ### 在其它地方的解构赋值 | ||
| 1417 | |||
| 1418 | 解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在 for 循环中: | ||
| 1271 | 1419 | ||
| 1272 | ```moonscript | 1420 | ```moonscript |
| 1273 | tuples = [ | 1421 | tuples = [ |
| @@ -1290,7 +1438,7 @@ for [left, right] in *tuples | |||
| 1290 | </pre> | 1438 | </pre> |
| 1291 | </YueDisplay> | 1439 | </YueDisplay> |
| 1292 | 1440 | ||
| 1293 | 我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在for语句的名称子句中使用解构来解包它。 | 1441 | 我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在 for 语句的名称子句中使用解构来解包它。 |
| 1294 | 1442 | ||
| 1295 | ## If 赋值 | 1443 | ## If 赋值 |
| 1296 | 1444 | ||
| @@ -1358,7 +1506,7 @@ while byte := stream\read_one! | |||
| 1358 | 1506 | ||
| 1359 | ## 可变参数赋值 | 1507 | ## 可变参数赋值 |
| 1360 | 1508 | ||
| 1361 | 你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用Lua的方式访问其内容。 | 1509 | 你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用 Lua 的方式访问其内容。 |
| 1362 | ```moonscript | 1510 | ```moonscript |
| 1363 | list = [1, 2, 3, 4, 5] | 1511 | list = [1, 2, 3, 4, 5] |
| 1364 | fn = (ok) -> ok, table.unpack list | 1512 | fn = (ok) -> ok, table.unpack list |
| @@ -1435,7 +1583,7 @@ func --[[端口]] 3000, --[[ip]] "192.168.1.1" | |||
| 1435 | 1583 | ||
| 1436 | ## 错误处理 | 1584 | ## 错误处理 |
| 1437 | 1585 | ||
| 1438 | 用于统一进行Lua错误处理的便捷语法。 | 1586 | 用于统一进行 Lua 错误处理的便捷语法。 |
| 1439 | 1587 | ||
| 1440 | ```moonscript | 1588 | ```moonscript |
| 1441 | try | 1589 | try |
| @@ -1494,9 +1642,50 @@ catch err | |||
| 1494 | </pre> | 1642 | </pre> |
| 1495 | </YueDisplay> | 1643 | </YueDisplay> |
| 1496 | 1644 | ||
| 1645 | ### 错误处理简化 | ||
| 1646 | |||
| 1647 | `try?` 是 `try` 的功能简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。 | ||
| 1648 | |||
| 1649 | ```moonscript | ||
| 1650 | a, b, c = try? func! | ||
| 1651 | |||
| 1652 | -- 与空值合并运算符一起使用 | ||
| 1653 | a = (try? func!) ?? "default" | ||
| 1654 | |||
| 1655 | -- 作为函数参数 | ||
| 1656 | f try? func! | ||
| 1657 | |||
| 1658 | -- 带 catch 块的 try! | ||
| 1659 | f try? | ||
| 1660 | print 123 | ||
| 1661 | func! | ||
| 1662 | catch e | ||
| 1663 | print e | ||
| 1664 | e | ||
| 1665 | ``` | ||
| 1666 | <YueDisplay> | ||
| 1667 | <pre> | ||
| 1668 | a, b, c = try? func! | ||
| 1669 | |||
| 1670 | -- 与空值合并运算符一起使用 | ||
| 1671 | a = (try? func!) ?? "default" | ||
| 1672 | |||
| 1673 | -- 作为函数参数 | ||
| 1674 | f try? func! | ||
| 1675 | |||
| 1676 | -- 带 catch 块的 try! | ||
| 1677 | f try? | ||
| 1678 | print 123 | ||
| 1679 | func! | ||
| 1680 | catch e | ||
| 1681 | print e | ||
| 1682 | e | ||
| 1683 | </pre> | ||
| 1684 | </YueDisplay> | ||
| 1685 | |||
| 1497 | ## 属性 | 1686 | ## 属性 |
| 1498 | 1687 | ||
| 1499 | 月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。 | 1688 | 月之脚本现在提供了 Lua 5.4 新增的叫做属性的语法支持。在月之脚本编译到的 Lua 目标版本低于 5.4 时,你仍然可以同时使用`const` 和 `close` 的属性声明语法,并获得常量检查和作用域回调的功能。 |
| 1500 | 1689 | ||
| 1501 | ```moonscript | 1690 | ```moonscript |
| 1502 | const a = 123 | 1691 | const a = 123 |
| @@ -1537,9 +1726,9 @@ global const Constant = 123 | |||
| 1537 | 1726 | ||
| 1538 | ## 字面量 | 1727 | ## 字面量 |
| 1539 | 1728 | ||
| 1540 | Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 | 1729 | Lua 中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和 **nil**。 |
| 1541 | 1730 | ||
| 1542 | 但与Lua不同的是,单引号和双引号字符串内部允许有换行: | 1731 | 但与 Lua 不同的是,单引号和双引号字符串内部允许有换行: |
| 1543 | 1732 | ||
| 1544 | ```moonscript | 1733 | ```moonscript |
| 1545 | some_string = "这是一个字符串 | 1734 | some_string = "这是一个字符串 |
| @@ -1574,6 +1763,66 @@ binary = 0B10011 | |||
| 1574 | <pre> | 1763 | <pre> |
| 1575 | integer = 1_000_000 | 1764 | integer = 1_000_000 |
| 1576 | hex = 0xEF_BB_BF | 1765 | hex = 0xEF_BB_BF |
| 1766 | binary = 0B10011 | ||
| 1767 | </pre> | ||
| 1768 | </YueDisplay> | ||
| 1769 | |||
| 1770 | ### YAML 风格字符串 | ||
| 1771 | |||
| 1772 | 使用 `|` 前缀标记一个多行 YAML 风格字符串: | ||
| 1773 | |||
| 1774 | ```moonscript | ||
| 1775 | str = | | ||
| 1776 | key: value | ||
| 1777 | list: | ||
| 1778 | - item1 | ||
| 1779 | - #{expr} | ||
| 1780 | ``` | ||
| 1781 | <YueDisplay> | ||
| 1782 | <pre> | ||
| 1783 | str = | | ||
| 1784 | key: value | ||
| 1785 | list: | ||
| 1786 | - item1 | ||
| 1787 | - #{expr} | ||
| 1788 | </pre> | ||
| 1789 | </YueDisplay> | ||
| 1790 | |||
| 1791 | 其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。 | ||
| 1792 | |||
| 1793 | YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。 | ||
| 1794 | |||
| 1795 | ```moonscript | ||
| 1796 | fn = -> | ||
| 1797 | str = | | ||
| 1798 | foo: | ||
| 1799 | bar: baz | ||
| 1800 | return str | ||
| 1801 | ``` | ||
| 1802 | <YueDisplay> | ||
| 1803 | <pre> | ||
| 1804 | fn = -> | ||
| 1805 | str = | | ||
| 1806 | foo: | ||
| 1807 | bar: baz | ||
| 1808 | return str | ||
| 1809 | </pre> | ||
| 1810 | </YueDisplay> | ||
| 1811 | |||
| 1812 | 输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。 | ||
| 1813 | |||
| 1814 | 支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义: | ||
| 1815 | |||
| 1816 | ```moonscript | ||
| 1817 | str = | | ||
| 1818 | path: "C:\Program Files\App" | ||
| 1819 | note: 'He said: "#{Hello}!"' | ||
| 1820 | ``` | ||
| 1821 | <YueDisplay> | ||
| 1822 | <pre> | ||
| 1823 | str = | | ||
| 1824 | path: "C:\Program Files\App" | ||
| 1825 | note: 'He said: "#{Hello}!"' | ||
| 1577 | </pre> | 1826 | </pre> |
| 1578 | </YueDisplay> | 1827 | </YueDisplay> |
| 1579 | 1828 | ||
| @@ -1678,7 +1927,7 @@ print "数字的和是", sum 10, 20 | |||
| 1678 | </pre> | 1927 | </pre> |
| 1679 | </YueDisplay> | 1928 | </YueDisplay> |
| 1680 | 1929 | ||
| 1681 | 如果你需要做显式返回,可以使用return关键字: | 1930 | 如果你需要做显式返回,可以使用 return 关键字: |
| 1682 | 1931 | ||
| 1683 | ```moonscript | 1932 | ```moonscript |
| 1684 | sum = (x, y) -> return x + y | 1933 | sum = (x, y) -> return x + y |
| @@ -1704,7 +1953,7 @@ a, b = mystery 10, 20 | |||
| 1704 | 1953 | ||
| 1705 | ### 粗箭头 | 1954 | ### 粗箭头 |
| 1706 | 1955 | ||
| 1707 | 因为在Lua中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含self参数的函数。 | 1956 | 因为在 Lua 中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含 self 参数的函数。 |
| 1708 | 1957 | ||
| 1709 | ```moonscript | 1958 | ```moonscript |
| 1710 | func = (num) => @value + num | 1959 | func = (num) => @value + num |
| @@ -1717,7 +1966,7 @@ func = (num) => @value + num | |||
| 1717 | 1966 | ||
| 1718 | ### 参数默认值 | 1967 | ### 参数默认值 |
| 1719 | 1968 | ||
| 1720 | 可以为函数的参数提供默认值。如果参数的值为nil,则确定该参数为空。任何具有默认值的nil参数在函数体运行之前都会被替换。 | 1969 | 可以为函数的参数提供默认值。如果参数的值为 nil,则确定该参数为空。任何具有默认值的 nil 参数在函数体运行之前都会被替换。 |
| 1721 | 1970 | ||
| 1722 | ```moonscript | 1971 | ```moonscript |
| 1723 | my_function = (name = "某物", height = 100) -> | 1972 | my_function = (name = "某物", height = 100) -> |
| @@ -1789,7 +2038,7 @@ my_func 5, 6, 7, | |||
| 1789 | </pre> | 2038 | </pre> |
| 1790 | </YueDisplay> | 2039 | </YueDisplay> |
| 1791 | 2040 | ||
| 1792 | 因为Lua表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是Lua表的一部分。 | 2041 | 因为 Lua 表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是 Lua 表的一部分。 |
| 1793 | 2042 | ||
| 1794 | ```moonscript | 2043 | ```moonscript |
| 1795 | x = [ | 2044 | x = [ |
| @@ -1856,6 +2105,138 @@ if func 1, 2, 3, | |||
| 1856 | </pre> | 2105 | </pre> |
| 1857 | </YueDisplay> | 2106 | </YueDisplay> |
| 1858 | 2107 | ||
| 2108 | ### 参数解构 | ||
| 2109 | |||
| 2110 | 月之脚本支持在函数形参位置对传入对象进行解构。适用两类解构表子面量: | ||
| 2111 | |||
| 2112 | - 使用 {} 包裹的字面量/对象形参,支持提供获得空字段时的默认值(例如 {:a, :b}、{a: a1 = 123})。 | ||
| 2113 | |||
| 2114 | - 无 {} 包裹、以键值/简写键序列开头,直至遇到其它表达式终止(例如 :a, b: b1, :c),表示从同一个对象中解构多个字段。 | ||
| 2115 | |||
| 2116 | ```moonscript | ||
| 2117 | f1 = (:a, :b, :c) -> | ||
| 2118 | print a, b, c | ||
| 2119 | |||
| 2120 | f1 a: 1, b: "2", c: {} | ||
| 2121 | |||
| 2122 | f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) -> | ||
| 2123 | print a1, b, c | ||
| 2124 | |||
| 2125 | arg1 = {a: 0} | ||
| 2126 | f2 arg1, arg2 | ||
| 2127 | ``` | ||
| 2128 | <YueDisplay> | ||
| 2129 | <pre> | ||
| 2130 | f1 = (:a, :b, :c) -> | ||
| 2131 | print a, b, c | ||
| 2132 | |||
| 2133 | f1 a: 1, b: "2", c: {} | ||
| 2134 | |||
| 2135 | f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) -> | ||
| 2136 | print a1, b, c | ||
| 2137 | |||
| 2138 | arg1 = {a: 0} | ||
| 2139 | f2 arg1, arg2 | ||
| 2140 | </pre> | ||
| 2141 | </YueDisplay> | ||
| 2142 | |||
| 2143 | ### 前置返回表达式 | ||
| 2144 | |||
| 2145 | 在深度嵌套的函数体中,为了提升返回值的可读性及编写便利性,我们新增了 “前置返回表达式” 语法。其形式如下: | ||
| 2146 | |||
| 2147 | ```moon | ||
| 2148 | findFirstEven = (list): nil -> | ||
| 2149 | for item in *list | ||
| 2150 | if type(item) == "table" | ||
| 2151 | for sub in *item | ||
| 2152 | if sub % 2 == 0 | ||
| 2153 | return sub | ||
| 2154 | ``` | ||
| 2155 | <YueDisplay> | ||
| 2156 | <pre> | ||
| 2157 | findFirstEven = (list): nil -> | ||
| 2158 | for item in *list | ||
| 2159 | if type(item) == "table" | ||
| 2160 | for sub in *item | ||
| 2161 | if sub % 2 == 0 | ||
| 2162 | return sub | ||
| 2163 | </pre> | ||
| 2164 | </YueDisplay> | ||
| 2165 | |||
| 2166 | 这个写法等价于: | ||
| 2167 | |||
| 2168 | ```moon | ||
| 2169 | findFirstEven = (list) -> | ||
| 2170 | for item in *list | ||
| 2171 | if type(item) == "table" | ||
| 2172 | for sub in *item | ||
| 2173 | if sub % 2 == 0 | ||
| 2174 | return sub | ||
| 2175 | nil | ||
| 2176 | ``` | ||
| 2177 | <YueDisplay> | ||
| 2178 | <pre> | ||
| 2179 | findFirstEven = (list) -> | ||
| 2180 | for item in *list | ||
| 2181 | if type(item) == "table" | ||
| 2182 | for sub in *item | ||
| 2183 | if sub % 2 == 0 | ||
| 2184 | return sub | ||
| 2185 | nil | ||
| 2186 | </pre> | ||
| 2187 | </YueDisplay> | ||
| 2188 | |||
| 2189 | 唯一的区别在于:你可以将函数的返回值表达式提前写在 `->` 或 `=>` 前,用以指示该函数应隐式返回该表达式的值。这样即使在多层循环或条件判断的场景下,也无需编写尾行悬挂的返回表达式,逻辑结构会更加直观清晰。 | ||
| 2190 | |||
| 2191 | ### 命名变长参数 | ||
| 2192 | |||
| 2193 | 你可以使用 `(...t) ->` 语法来将变长参数自动存储到一个命名表中。这个表会包含所有传入的参数(包括 `nil` 值),并且会在表的 `n` 字段中存储实际传入的参数个数(包括 `nil` 值在内的个数)。 | ||
| 2194 | |||
| 2195 | ```moonscript | ||
| 2196 | f = (...t) -> | ||
| 2197 | print "参数个数:", t.n | ||
| 2198 | print "表长度:", #t | ||
| 2199 | for i = 1, t.n | ||
| 2200 | print t[i] | ||
| 2201 | |||
| 2202 | f 1, 2, 3 | ||
| 2203 | f "a", "b", "c", "d" | ||
| 2204 | f! | ||
| 2205 | |||
| 2206 | -- 处理包含 nil 的情况 | ||
| 2207 | process = (...args) -> | ||
| 2208 | sum = 0 | ||
| 2209 | for i = 1, args.n | ||
| 2210 | if args[i] != nil and type(args[i]) == "number" | ||
| 2211 | sum += args[i] | ||
| 2212 | sum | ||
| 2213 | |||
| 2214 | process 1, nil, 3, nil, 5 | ||
| 2215 | ``` | ||
| 2216 | <YueDisplay> | ||
| 2217 | <pre> | ||
| 2218 | f = (...t) -> | ||
| 2219 | print "参数个数:", t.n | ||
| 2220 | print "表长度:", #t | ||
| 2221 | for i = 1, t.n | ||
| 2222 | print t[i] | ||
| 2223 | |||
| 2224 | f 1, 2, 3 | ||
| 2225 | f "a", "b", "c", "d" | ||
| 2226 | f! | ||
| 2227 | |||
| 2228 | -- 处理包含 nil 的情况 | ||
| 2229 | process = (...args) -> | ||
| 2230 | sum = 0 | ||
| 2231 | for i = 1, args.n | ||
| 2232 | if args[i] != nil and type(args[i]) == "number" | ||
| 2233 | sum += args[i] | ||
| 2234 | sum | ||
| 2235 | |||
| 2236 | process 1, nil, 3, nil, 5 | ||
| 2237 | </pre> | ||
| 2238 | </YueDisplay> | ||
| 2239 | |||
| 1859 | ## 反向回调 | 2240 | ## 反向回调 |
| 1860 | 2241 | ||
| 1861 | 反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。 | 2242 | 反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。 |
| @@ -1920,7 +2301,7 @@ print result, msg | |||
| 1920 | 2301 | ||
| 1921 | ## 表格字面量 | 2302 | ## 表格字面量 |
| 1922 | 2303 | ||
| 1923 | 和Lua一样,表格可以通过花括号进行定义。 | 2304 | 和 Lua 一样,表格可以通过花括号进行定义。 |
| 1924 | 2305 | ||
| 1925 | ```moonscript | 2306 | ```moonscript |
| 1926 | some_values = [1, 2, 3, 4] | 2307 | some_values = [1, 2, 3, 4] |
| @@ -2003,7 +2384,7 @@ y = type: "狗", legs: 4, tails: 1 | |||
| 2003 | </pre> | 2384 | </pre> |
| 2004 | </YueDisplay> | 2385 | </YueDisplay> |
| 2005 | 2386 | ||
| 2006 | 表格字面量的键可以使用Lua语言的关键字,而无需转义: | 2387 | 表格字面量的键可以使用 Lua 语言的关键字,而无需转义: |
| 2007 | 2388 | ||
| 2008 | ```moonscript | 2389 | ```moonscript |
| 2009 | tbl = { | 2390 | tbl = { |
| @@ -2039,7 +2420,7 @@ print_table :hair, :height | |||
| 2039 | </pre> | 2420 | </pre> |
| 2040 | </YueDisplay> | 2421 | </YueDisplay> |
| 2041 | 2422 | ||
| 2042 | 如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在Lua中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。 | 2423 | 如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在 Lua 中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。 |
| 2043 | 2424 | ||
| 2044 | ```moonscript | 2425 | ```moonscript |
| 2045 | t = { | 2426 | t = { |
| @@ -2056,7 +2437,7 @@ t = { | |||
| 2056 | </pre> | 2437 | </pre> |
| 2057 | </YueDisplay> | 2438 | </YueDisplay> |
| 2058 | 2439 | ||
| 2059 | Lua的表同时具有数组部分和哈希部分,但有时候你会希望在书写Lua表时,对Lua表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。 | 2440 | Lua 的表同时具有数组部分和哈希部分,但有时候你会希望在书写 Lua 表时,对 Lua 表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。 |
| 2060 | 2441 | ||
| 2061 | ```moonscript | 2442 | ```moonscript |
| 2062 | some_values = [ 1, 2, 3, 4 ] | 2443 | some_values = [ 1, 2, 3, 4 ] |
| @@ -2071,11 +2452,11 @@ list_with_one_element = [ 1, ] | |||
| 2071 | 2452 | ||
| 2072 | ## 推导式 | 2453 | ## 推导式 |
| 2073 | 2454 | ||
| 2074 | 推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生Lua表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。 | 2455 | 推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生 Lua 表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。 |
| 2075 | 2456 | ||
| 2076 | ### 列表推导式 | 2457 | ### 列表推导式 |
| 2077 | 2458 | ||
| 2078 | 以下操作创建了一个items表的副本,但所有包含的值都翻倍了。 | 2459 | 以下操作创建了一个 items 表的副本,但所有包含的值都翻倍了。 |
| 2079 | 2460 | ||
| 2080 | ```moonscript | 2461 | ```moonscript |
| 2081 | items = [1, 2, 3, 4] | 2462 | items = [1, 2, 3, 4] |
| @@ -2088,7 +2469,7 @@ doubled = [item * 2 for i, item in ipairs items] | |||
| 2088 | </pre> | 2469 | </pre> |
| 2089 | </YueDisplay> | 2470 | </YueDisplay> |
| 2090 | 2471 | ||
| 2091 | 可以使用when子句筛选新表中包含的项目: | 2472 | 可以使用 `when` 子句筛选新表中包含的项目: |
| 2092 | 2473 | ||
| 2093 | ```moonscript | 2474 | ```moonscript |
| 2094 | slice = [item for i, item in ipairs items when i > 1 and i < 3] | 2475 | slice = [item for i, item in ipairs items when i > 1 and i < 3] |
| @@ -2099,7 +2480,7 @@ slice = [item for i, item in ipairs items when i > 1 and i < 3] | |||
| 2099 | </pre> | 2480 | </pre> |
| 2100 | </YueDisplay> | 2481 | </YueDisplay> |
| 2101 | 2482 | ||
| 2102 | 因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled示例可以重写为: | 2483 | 因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled 示例可以重写为: |
| 2103 | 2484 | ||
| 2104 | ```moonscript | 2485 | ```moonscript |
| 2105 | doubled = [item * 2 for item in *items] | 2486 | doubled = [item * 2 for item in *items] |
| @@ -2110,9 +2491,30 @@ doubled = [item * 2 for item in *items] | |||
| 2110 | </pre> | 2491 | </pre> |
| 2111 | </YueDisplay> | 2492 | </YueDisplay> |
| 2112 | 2493 | ||
| 2113 | for和when子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个for子句。 | 2494 | 在列表推导式中,你还可以使用展开操作符 `...` 来实现对列表嵌套层级进行扁平化的处理: |
| 2495 | |||
| 2496 | ```moonscript | ||
| 2497 | data = | ||
| 2498 | a: [1, 2, 3] | ||
| 2499 | b: [4, 5, 6] | ||
| 2500 | |||
| 2501 | flat = [...v for k,v in pairs data] | ||
| 2502 | -- flat 现在为 [1, 2, 3, 4, 5, 6] | ||
| 2503 | ``` | ||
| 2504 | <YueDisplay> | ||
| 2505 | <pre> | ||
| 2506 | data = | ||
| 2507 | a: [1, 2, 3] | ||
| 2508 | b: [4, 5, 6] | ||
| 2509 | |||
| 2510 | flat = [...v for k,v in pairs data] | ||
| 2511 | -- flat 现在为 [1, 2, 3, 4, 5, 6] | ||
| 2512 | </pre> | ||
| 2513 | </YueDisplay> | ||
| 2514 | |||
| 2515 | for 和 when 子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个 for 子句。 | ||
| 2114 | 2516 | ||
| 2115 | 使用多个for子句与使用多重循环的效果相同: | 2517 | 使用多个 for 子句与使用多重循环的效果相同: |
| 2116 | 2518 | ||
| 2117 | ```moonscript | 2519 | ```moonscript |
| 2118 | x_coords = [4, 5, 6, 7] | 2520 | x_coords = [4, 5, 6, 7] |
| @@ -2131,7 +2533,7 @@ for y in *y_coords] | |||
| 2131 | </pre> | 2533 | </pre> |
| 2132 | </YueDisplay> | 2534 | </YueDisplay> |
| 2133 | 2535 | ||
| 2134 | 在推导式中也可以使用简单的数值for循环: | 2536 | 在推导式中也可以使用简单的数值 for 循环: |
| 2135 | 2537 | ||
| 2136 | ```moonscript | 2538 | ```moonscript |
| 2137 | evens = [i for i = 1, 100 when i % 2 == 0] | 2539 | evens = [i for i = 1, 100 when i % 2 == 0] |
| @@ -2146,7 +2548,7 @@ evens = [i for i = 1, 100 when i % 2 == 0] | |||
| 2146 | 2548 | ||
| 2147 | 表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。 | 2549 | 表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。 |
| 2148 | 2550 | ||
| 2149 | 以下示例生成了表格thing的副本: | 2551 | 以下示例生成了表格 thing 的副本: |
| 2150 | 2552 | ||
| 2151 | ```moonscript | 2553 | ```moonscript |
| 2152 | thing = { | 2554 | thing = { |
| @@ -2208,9 +2610,9 @@ tbl = {unpack tuple for tuple in *tuples} | |||
| 2208 | 2610 | ||
| 2209 | ### 切片 | 2611 | ### 切片 |
| 2210 | 2612 | ||
| 2211 | 当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在for循环中设置迭代边界和步长。 | 2613 | 当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在 for 循环中设置迭代边界和步长。 |
| 2212 | 2614 | ||
| 2213 | 下面的案例中,我们在切片中设置最小和最大边界,取索引在1到5之间(包括1和5)的所有项目: | 2615 | 下面的案例中,我们在切片中设置最小和最大边界,取索引在 1 到 5 之间(包括 1 和 5)的所有项目: |
| 2214 | 2616 | ||
| 2215 | ```moonscript | 2617 | ```moonscript |
| 2216 | slice = [item for item in *items[1, 5]] | 2618 | slice = [item for item in *items[1, 5]] |
| @@ -2232,7 +2634,7 @@ slice = [item for item in *items[2,]] | |||
| 2232 | </pre> | 2634 | </pre> |
| 2233 | </YueDisplay> | 2635 | </YueDisplay> |
| 2234 | 2636 | ||
| 2235 | 如果省略了最小边界,便默认会设置为1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …) | 2637 | 如果省略了最小边界,便默认会设置为 1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …) |
| 2236 | 2638 | ||
| 2237 | ```moonscript | 2639 | ```moonscript |
| 2238 | slice = [item for item in *items[,,2]] | 2640 | slice = [item for item in *items[,,2]] |
| @@ -2244,9 +2646,48 @@ slice = [item for item in *items[,,2]] | |||
| 2244 | </pre> | 2646 | </pre> |
| 2245 | </YueDisplay> | 2647 | </YueDisplay> |
| 2246 | 2648 | ||
| 2649 | 最小和最大边界都可以是负数,使用负数意味着边界是从表的末尾开始计算的。 | ||
| 2650 | |||
| 2651 | ```moonscript | ||
| 2652 | -- 取最后4个元素 | ||
| 2653 | slice = [item for item in *items[-4,-1]] | ||
| 2654 | ``` | ||
| 2655 | <YueDisplay> | ||
| 2656 | <pre> | ||
| 2657 | -- 取最后4个元素 | ||
| 2658 | slice = [item for item in *items[-4,-1]] | ||
| 2659 | </pre> | ||
| 2660 | </YueDisplay> | ||
| 2661 | |||
| 2662 | 切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。 | ||
| 2663 | |||
| 2664 | ```moonscript | ||
| 2665 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
| 2666 | ``` | ||
| 2667 | <YueDisplay> | ||
| 2668 | <pre> | ||
| 2669 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
| 2670 | </pre> | ||
| 2671 | </YueDisplay> | ||
| 2672 | |||
| 2673 | #### 切片表达式 | ||
| 2674 | |||
| 2675 | 切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。 | ||
| 2676 | |||
| 2677 | ```moonscript | ||
| 2678 | -- 取第2和第4个元素作为新的列表 | ||
| 2679 | sub_list = items[2, 4] | ||
| 2680 | ``` | ||
| 2681 | <YueDisplay> | ||
| 2682 | <pre> | ||
| 2683 | -- 取第2和第4个元素作为新的列表 | ||
| 2684 | sub_list = items[2, 4] | ||
| 2685 | </pre> | ||
| 2686 | </YueDisplay> | ||
| 2687 | |||
| 2247 | ## for 循环 | 2688 | ## for 循环 |
| 2248 | 2689 | ||
| 2249 | Lua中有两种for循环形式,数字型和通用型: | 2690 | Lua 中有两种 for 循环形式,数字型和通用型: |
| 2250 | 2691 | ||
| 2251 | ```moonscript | 2692 | ```moonscript |
| 2252 | for i = 10, 20 | 2693 | for i = 10, 20 |
| @@ -2299,7 +2740,7 @@ for j = 1, 10, 3 do print j | |||
| 2299 | </pre> | 2740 | </pre> |
| 2300 | </YueDisplay> | 2741 | </YueDisplay> |
| 2301 | 2742 | ||
| 2302 | for循环也可以用作表达式。for循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。 | 2743 | for 循环也可以用作表达式。for 循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。 |
| 2303 | 2744 | ||
| 2304 | 将每个偶数加倍: | 2745 | 将每个偶数加倍: |
| 2305 | 2746 | ||
| @@ -2320,9 +2761,9 @@ doubled_evens = for i = 1, 20 | |||
| 2320 | </pre> | 2761 | </pre> |
| 2321 | </YueDisplay> | 2762 | </YueDisplay> |
| 2322 | 2763 | ||
| 2323 | 此外,for循环还支持带返回值的break语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。 | 2764 | 此外,for 循环还支持带返回值的 break 语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。 |
| 2324 | 2765 | ||
| 2325 | 例如,查找第一个大于10的数字: | 2766 | 例如,查找第一个大于 10 的数字: |
| 2326 | 2767 | ||
| 2327 | ```moonscript | 2768 | ```moonscript |
| 2328 | first_large = for n in *numbers | 2769 | first_large = for n in *numbers |
| @@ -2335,9 +2776,9 @@ first_large = for n in *numbers | |||
| 2335 | </pre> | 2776 | </pre> |
| 2336 | </YueDisplay> | 2777 | </YueDisplay> |
| 2337 | 2778 | ||
| 2338 | 你还可以结合for循环表达式与continue语句来过滤值。 | 2779 | 你还可以结合 for 循环表达式与 continue 语句来过滤值。 |
| 2339 | 2780 | ||
| 2340 | 注意出现在函数体末尾的for循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加for循环表达式。 | 2781 | 注意出现在函数体末尾的 for 循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回 nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加 for 循环表达式。 |
| 2341 | 2782 | ||
| 2342 | ```moonscript | 2783 | ```moonscript |
| 2343 | func_a = -> for i = 1, 10 do print i | 2784 | func_a = -> for i = 1, 10 do print i |
| @@ -2360,7 +2801,7 @@ print func_b! -- 打印 table 对象 | |||
| 2360 | 2801 | ||
| 2361 | ## repeat 循环 | 2802 | ## repeat 循环 |
| 2362 | 2803 | ||
| 2363 | repeat循环是从Lua语言中搬过来的相似语法: | 2804 | repeat 循环是从 Lua 语言中搬过来的相似语法: |
| 2364 | 2805 | ||
| 2365 | ```moonscript | 2806 | ```moonscript |
| 2366 | i = 10 | 2807 | i = 10 |
| @@ -2381,7 +2822,7 @@ until i == 0 | |||
| 2381 | 2822 | ||
| 2382 | ## while 循环 | 2823 | ## while 循环 |
| 2383 | 2824 | ||
| 2384 | 在月之脚本中的while循环有四种写法: | 2825 | 在月之脚本中的 while 循环有四种写法: |
| 2385 | 2826 | ||
| 2386 | ```moonscript | 2827 | ```moonscript |
| 2387 | i = 10 | 2828 | i = 10 |
| @@ -2420,7 +2861,7 @@ until running == false do my_function! | |||
| 2420 | </pre> | 2861 | </pre> |
| 2421 | </YueDisplay> | 2862 | </YueDisplay> |
| 2422 | 2863 | ||
| 2423 | 像for循环的语法一样,while循环也可以作为一个表达式使用。为了使函数返回while循环的累积列表值,必须明确使用返回语句返回while循环表达式。 | 2864 | 像 for 循环的语法一样,while 循环也可以作为一个表达式使用。为了使函数返回 while 循环的累积列表值,必须明确使用返回语句返回 while 循环表达式。 |
| 2424 | 2865 | ||
| 2425 | ## 继续 | 2866 | ## 继续 |
| 2426 | 2867 | ||
| @@ -2538,13 +2979,14 @@ print message -- 打印: 我很高 | |||
| 2538 | </pre> | 2979 | </pre> |
| 2539 | </YueDisplay> | 2980 | </YueDisplay> |
| 2540 | 2981 | ||
| 2541 | if的反义词是unless(相当于if not,如果 vs 除非): | 2982 | if 的反义词是 unless(相当于 if not,正如“如果”对应“除非”): |
| 2542 | 2983 | ||
| 2543 | ```moonscript | 2984 | ```moonscript |
| 2544 | unless os.date("%A") == "Monday" | 2985 | unless os.date("%A") == "Monday" |
| 2545 | print "今天不是星期一!" | 2986 | print "今天不是星期一!" |
| 2546 | ``` | 2987 | ``` |
| 2547 | <YueDisplay> | 2988 | <YueDisplay> |
| 2989 | |||
| 2548 | <pre> | 2990 | <pre> |
| 2549 | unless os.date("%A") == "Monday" | 2991 | unless os.date("%A") == "Monday" |
| 2550 | print "今天不是星期一!" | 2992 | print "今天不是星期一!" |
| @@ -2596,7 +3038,7 @@ print "你很幸运!" unless math.random! > 0.1 | |||
| 2596 | 3038 | ||
| 2597 | ## 代码行修饰符 | 3039 | ## 代码行修饰符 |
| 2598 | 3040 | ||
| 2599 | 为了方便编写代码,循环语句和if语句可以应用于单行代码语句的末尾: | 3041 | 为了方便编写代码,循环语句和 if 语句可以应用于单行代码语句的末尾: |
| 2600 | 3042 | ||
| 2601 | ```moonscript | 3043 | ```moonscript |
| 2602 | print "你好,世界" if name == "Rob" | 3044 | print "你好,世界" if name == "Rob" |
| @@ -2607,7 +3049,7 @@ print "你好,世界" if name == "Rob" | |||
| 2607 | </pre> | 3049 | </pre> |
| 2608 | </YueDisplay> | 3050 | </YueDisplay> |
| 2609 | 3051 | ||
| 2610 | 修饰for循环的示例: | 3052 | 修饰 for 循环的示例: |
| 2611 | 3053 | ||
| 2612 | ```moonscript | 3054 | ```moonscript |
| 2613 | print "项目: ", item for item in *items | 3055 | print "项目: ", item for item in *items |
| @@ -2618,7 +3060,7 @@ print "项目: ", item for item in *items | |||
| 2618 | </pre> | 3060 | </pre> |
| 2619 | </YueDisplay> | 3061 | </YueDisplay> |
| 2620 | 3062 | ||
| 2621 | 修饰while循环的示例: | 3063 | 修饰 while 循环的示例: |
| 2622 | 3064 | ||
| 2623 | ```moonscript | 3065 | ```moonscript |
| 2624 | game\update! while game\isRunning! | 3066 | game\update! while game\isRunning! |
| @@ -2635,34 +3077,32 @@ reader\parse_line! until reader\eof! | |||
| 2635 | 3077 | ||
| 2636 | ## switch 语句 | 3078 | ## switch 语句 |
| 2637 | 3079 | ||
| 2638 | switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。 | 3080 | switch 语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和 if 语句一样,switch 语句在最后可以接一个 else 代码块来处理没有匹配的情况。在生成的 Lua 代码中,进行比较是使用 == 操作符完成的。switch 语句中也可以使用赋值表达式来储存临时变量值。 |
| 2639 | 3081 | ||
| 2640 | ```moonscript | 3082 | ```moonscript |
| 2641 | name = "Dan" | 3083 | switch name := "Dan" |
| 2642 | switch name | ||
| 2643 | when "Robert" | 3084 | when "Robert" |
| 2644 | print "你是Robert" | 3085 | print "你是Robert" |
| 2645 | when "Dan", "Daniel" | 3086 | when "Dan", "Daniel" |
| 2646 | print "你的名字是Dan" | 3087 | print "你的名字是Dan" |
| 2647 | else | 3088 | else |
| 2648 | print "我不知道你的名字" | 3089 | print "我不认识你,你的名字是#{name}" |
| 2649 | ``` | 3090 | ``` |
| 2650 | <YueDisplay> | 3091 | <YueDisplay> |
| 2651 | <pre> | 3092 | <pre> |
| 2652 | name = "Dan" | 3093 | switch name := "Dan" |
| 2653 | switch name | ||
| 2654 | when "Robert" | 3094 | when "Robert" |
| 2655 | print "你是Robert" | 3095 | print "你是Robert" |
| 2656 | when "Dan", "Daniel" | 3096 | when "Dan", "Daniel" |
| 2657 | print "你的名字是Dan" | 3097 | print "你的名字是Dan" |
| 2658 | else | 3098 | else |
| 2659 | print "我不知道你的名字" | 3099 | print "我不认识你,你的名字是#{name}" |
| 2660 | </pre> | 3100 | </pre> |
| 2661 | </YueDisplay> | 3101 | </YueDisplay> |
| 2662 | 3102 | ||
| 2663 | switch语句的when子句中可以通过使用逗号分隔的列表来匹配多个值。 | 3103 | switch 语句的 when 子句中可以通过使用逗号分隔的列表来匹配多个值。 |
| 2664 | 3104 | ||
| 2665 | switch语句也可以作为表达式使用,下面我们可以将switch语句返回的结果分配给一个变量: | 3105 | switch 语句也可以作为表达式使用,下面我们可以将 switch 语句返回的结果分配给一个变量: |
| 2666 | 3106 | ||
| 2667 | ```moonscript | 3107 | ```moonscript |
| 2668 | b = 1 | 3108 | b = 1 |
| @@ -2687,7 +3127,7 @@ next_number = switch b | |||
| 2687 | </pre> | 3127 | </pre> |
| 2688 | </YueDisplay> | 3128 | </YueDisplay> |
| 2689 | 3129 | ||
| 2690 | 我们可以使用then关键字在when子句的同一行上编写处理代码。else代码块的后续代码中要写在同一行上不需要额外的关键字。 | 3130 | 我们可以使用 then 关键字在 when 子句的同一行上编写处理代码。else 代码块的后续代码中要写在同一行上不需要额外的关键字。 |
| 2691 | 3131 | ||
| 2692 | ```moonscript | 3132 | ```moonscript |
| 2693 | msg = switch math.random(1, 5) | 3133 | msg = switch math.random(1, 5) |
| @@ -2704,7 +3144,7 @@ msg = switch math.random(1, 5) | |||
| 2704 | </pre> | 3144 | </pre> |
| 2705 | </YueDisplay> | 3145 | </YueDisplay> |
| 2706 | 3146 | ||
| 2707 | 如果在编写switch语句时希望少写一个缩进,那么你可以把第一个when子句放在switch开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。 | 3147 | 如果在编写 switch 语句时希望少写一个缩进,那么你可以把第一个 when 子句放在 switch 开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。 |
| 2708 | 3148 | ||
| 2709 | ```moonscript | 3149 | ```moonscript |
| 2710 | switch math.random(1, 5) | 3150 | switch math.random(1, 5) |
| @@ -2733,11 +3173,11 @@ else | |||
| 2733 | </pre> | 3173 | </pre> |
| 2734 | </YueDisplay> | 3174 | </YueDisplay> |
| 2735 | 3175 | ||
| 2736 | 值得注意的是,在生成Lua代码时,我们要做检查的目标变量会放在==表达式的右侧。当你希望给when子句的比较对象定义一个\_\_eq元方法来重载判断逻辑时,可能会有用。 | 3176 | 值得注意的是,在生成 Lua 代码时,我们要做检查的目标变量会放在 == 表达式的右侧。当你希望给 when 子句的比较对象定义一个 \_\_eq 元方法来重载判断逻辑时,可能会有用。 |
| 2737 | 3177 | ||
| 2738 | ### 表格匹配 | 3178 | ### 表格匹配 |
| 2739 | 3179 | ||
| 2740 | 在switch的when子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非nil值,那么你可以尝试使用表格匹配的语法。 | 3180 | 在 switch 的 when 子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非 nil 值,那么你可以尝试使用表格匹配的语法。 |
| 2741 | 3181 | ||
| 2742 | ```moonscript | 3182 | ```moonscript |
| 2743 | items = | 3183 | items = |
| @@ -2889,9 +3329,30 @@ switch tb | |||
| 2889 | </pre> | 3329 | </pre> |
| 2890 | </YueDisplay> | 3330 | </YueDisplay> |
| 2891 | 3331 | ||
| 3332 | 匹配一个列表并捕获特定范围内的元素。 | ||
| 3333 | |||
| 3334 | ```moonscript | ||
| 3335 | segments = ["admin", "users", "logs", "view"] | ||
| 3336 | switch segments | ||
| 3337 | when [...groups, resource, action] | ||
| 3338 | print "Group:", groups -- 打印: {"admin", "users"} | ||
| 3339 | print "Resource:", resource -- 打印: "logs" | ||
| 3340 | print "Action:", action -- 打印: "view" | ||
| 3341 | ``` | ||
| 3342 | <YueDisplay> | ||
| 3343 | <pre> | ||
| 3344 | segments = ["admin", "users", "logs", "view"] | ||
| 3345 | switch segments | ||
| 3346 | when [...groups, resource, action] | ||
| 3347 | print "Group:", groups -- 打印: {"admin", "users"} | ||
| 3348 | print "Resource:", resource -- 打印: "logs" | ||
| 3349 | print "Action:", action -- 打印: "view" | ||
| 3350 | </pre> | ||
| 3351 | </YueDisplay> | ||
| 3352 | |||
| 2892 | ## 面向对象编程 | 3353 | ## 面向对象编程 |
| 2893 | 3354 | ||
| 2894 | 在以下的示例中,月之脚本生成的Lua代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看Lua代码。 | 3355 | 在以下的示例中,月之脚本生成的 Lua 代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看 Lua 代码。 |
| 2895 | 3356 | ||
| 2896 | 一个简单的类: | 3357 | 一个简单的类: |
| 2897 | 3358 | ||
| @@ -2920,11 +3381,11 @@ class Inventory | |||
| 2920 | </pre> | 3381 | </pre> |
| 2921 | </YueDisplay> | 3382 | </YueDisplay> |
| 2922 | 3383 | ||
| 2923 | 在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合Lua表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为“new”的成员扮演了一个重要的角色,是作为构造函数来使用。 | 3384 | 在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合 Lua 表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为 “new” 的成员扮演了一个重要的角色,是作为构造函数来使用。 |
| 2924 | 3385 | ||
| 2925 | 值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为“self”的参数。 | 3386 | 值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为 “self” 的参数。 |
| 2926 | 3387 | ||
| 2927 | 此外,“@”前缀在变量名上起到了简化作用,代表“self”。例如,`@items` 就等同于 `self.items`。 | 3388 | 此外,“@” 前缀在变量名上起到了简化作用,代表 “self”。例如,`@items` 就等同于 `self.items`。 |
| 2928 | 3389 | ||
| 2929 | 为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。 | 3390 | 为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。 |
| 2930 | 3391 | ||
| @@ -2946,7 +3407,7 @@ inv\add_item "pants" | |||
| 2946 | 3407 | ||
| 2947 | 需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 | 3408 | 需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 |
| 2948 | 3409 | ||
| 2949 | 例如,在下面的示例中,clothes属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。 | 3410 | 例如,在下面的示例中,clothes 属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。 |
| 2950 | 3411 | ||
| 2951 | ```moonscript | 3412 | ```moonscript |
| 2952 | class Person | 3413 | class Person |
| @@ -2998,7 +3459,7 @@ class Person | |||
| 2998 | 3459 | ||
| 2999 | ### 继承 | 3460 | ### 继承 |
| 3000 | 3461 | ||
| 3001 | `extends`关键字可以在类声明中使用,以继承另一个类的属性和方法。 | 3462 | `extends` 关键字可以在类声明中使用,以继承另一个类的属性和方法。 |
| 3002 | 3463 | ||
| 3003 | ```moonscript | 3464 | ```moonscript |
| 3004 | class BackPack extends Inventory | 3465 | class BackPack extends Inventory |
| @@ -3018,11 +3479,11 @@ class BackPack extends Inventory | |||
| 3018 | </YueDisplay> | 3479 | </YueDisplay> |
| 3019 | 3480 | ||
| 3020 | 3481 | ||
| 3021 | 在这一部分,我们对月之脚本中的`Inventory`类进行了扩展,加入了对可以携带物品数量的限制。 | 3482 | 在这一部分,我们对月之脚本中的 `Inventory` 类进行了扩展,加入了对可以携带物品数量的限制。 |
| 3022 | 3483 | ||
| 3023 | 在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用`super`方法来调用并执行父类的构造函数。 | 3484 | 在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用 `super` 方法来调用并执行父类的构造函数。 |
| 3024 | 3485 | ||
| 3025 | 此外,当一个类继承自另一个类时,它会尝试调用父类上的`__inherited`方法(如果这个方法存在的话),以此来向父类发送通知。这个`__inherited`函数接受两个参数:被继承的父类和继承的子类。 | 3486 | 此外,当一个类继承自另一个类时,它会尝试调用父类上的 `__inherited` 方法(如果这个方法存在的话),以此来向父类发送通知。这个 `__inherited` 函数接受两个参数:被继承的父类和继承的子类。 |
| 3026 | 3487 | ||
| 3027 | ```moonscript | 3488 | ```moonscript |
| 3028 | class Shelf | 3489 | class Shelf |
| @@ -3045,15 +3506,15 @@ class Cupboard extends Shelf | |||
| 3045 | 3506 | ||
| 3046 | ### super 关键字 | 3507 | ### super 关键字 |
| 3047 | 3508 | ||
| 3048 | `super`是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 | 3509 | `super` 是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 |
| 3049 | 3510 | ||
| 3050 | 当`super`被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的`self`会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。 | 3511 | 当 `super` 被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的 `self` 会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。 |
| 3051 | 3512 | ||
| 3052 | 在将`super`当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。 | 3513 | 在将 `super` 当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。 |
| 3053 | 3514 | ||
| 3054 | 此外,当使用`\`操作符与`super`一起使用时,`self`将被插入为第一个参数,而不是使用`super`本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。 | 3515 | 此外,当使用 `\` 操作符与 `super` 一起使用时,`self`将被插入为第一个参数,而不是使用 `super` 本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。 |
| 3055 | 3516 | ||
| 3056 | 下面是一些使用`super`的不同方法的示例: | 3517 | 下面是一些使用 `super` 的不同方法的示例: |
| 3057 | 3518 | ||
| 3058 | ```moonscript | 3519 | ```moonscript |
| 3059 | class MyClass extends ParentClass | 3520 | class MyClass extends ParentClass |
| @@ -3112,9 +3573,9 @@ print BackPack.size -- 打印 10 | |||
| 3112 | 3573 | ||
| 3113 | 如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。 | 3574 | 如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。 |
| 3114 | 3575 | ||
| 3115 | 需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的“__base”字段。 | 3576 | 需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的 “__base” 字段。 |
| 3116 | 3577 | ||
| 3117 | 此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的“__name”字段中。 | 3578 | 此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的 “__name” 字段中。 |
| 3118 | 3579 | ||
| 3119 | ```moonscript | 3580 | ```moonscript |
| 3120 | print BackPack.__name -- 打印 Backpack | 3581 | print BackPack.__name -- 打印 Backpack |
| @@ -3196,7 +3657,7 @@ print Counter.count -- 输出 2 | |||
| 3196 | 3657 | ||
| 3197 | ### 类声明语句 | 3658 | ### 类声明语句 |
| 3198 | 3659 | ||
| 3199 | 在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self等于类对象,而不是实例对象。 | 3660 | 在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self 等于类对象,而不是实例对象。 |
| 3200 | 3661 | ||
| 3201 | 以下是创建类变量的另一种方法: | 3662 | 以下是创建类变量的另一种方法: |
| 3202 | 3663 | ||
| @@ -3236,9 +3697,9 @@ class MoreThings | |||
| 3236 | 3697 | ||
| 3237 | ### @ 和 @@ 值 | 3698 | ### @ 和 @@ 值 |
| 3238 | 3699 | ||
| 3239 | 当@和@@前缀在一个名字前时,它们分别代表在self和self.\_\_class中访问的那个名字。 | 3700 | 当 @ 和 @@ 前缀在一个名字前时,它们分别代表在 self 和 self.\_\_class 中访问的那个名字。 |
| 3240 | 3701 | ||
| 3241 | 如果它们单独使用,它们是self和self.\_\_class的别名。 | 3702 | 如果它们单独使用,它们是 self 和 self.\_\_class 的别名。 |
| 3242 | 3703 | ||
| 3243 | ```moonscript | 3704 | ```moonscript |
| 3244 | assert @ == self | 3705 | assert @ == self |
| @@ -3251,7 +3712,7 @@ assert @@ == self.__class | |||
| 3251 | </pre> | 3712 | </pre> |
| 3252 | </YueDisplay> | 3713 | </YueDisplay> |
| 3253 | 3714 | ||
| 3254 | 例如,使用@@从实例方法快速创建同一类的新实例的方法: | 3715 | 例如,使用 @@ 从实例方法快速创建同一类的新实例的方法: |
| 3255 | 3716 | ||
| 3256 | ```moonscript | 3717 | ```moonscript |
| 3257 | some_instance_method = (...) => @@ ... | 3718 | some_instance_method = (...) => @@ ... |
| @@ -3329,7 +3790,7 @@ x = class Bucket | |||
| 3329 | 3790 | ||
| 3330 | ### 匿名类 | 3791 | ### 匿名类 |
| 3331 | 3792 | ||
| 3332 | 声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name属性将为nil。如果出现在赋值语句中,赋值操作左侧的名称将代替nil。 | 3793 | 声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name 属性将为 nil。如果出现在赋值语句中,赋值操作左侧的名称将代替 nil。 |
| 3333 | 3794 | ||
| 3334 | ```moonscript | 3795 | ```moonscript |
| 3335 | BigBucket = class extends Bucket | 3796 | BigBucket = class extends Bucket |
| @@ -3400,11 +3861,11 @@ assert y.__class.__parent ~= X -- X 不是 Y 的父类 | |||
| 3400 | 3861 | ||
| 3401 | ## with 语句 | 3862 | ## with 语句 |
| 3402 | 3863 | ||
| 3403 | 在编写Lua代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。 | 3864 | 在编写 Lua 代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。 |
| 3404 | 3865 | ||
| 3405 | 这导致在代码中多次重复引用对象的名称,增加了不必要的文本噪音。一个常见的解决方案是在创建对象时,在构造函数传入一个表,该表包含要覆盖设置的键和值的集合。这样做的缺点是该对象的构造函数必须支持这种初始化形式。 | 3866 | 这导致在代码中多次重复引用对象的名称,增加了不必要的文本噪音。一个常见的解决方案是在创建对象时,在构造函数传入一个表,该表包含要覆盖设置的键和值的集合。这样做的缺点是该对象的构造函数必须支持这种初始化形式。 |
| 3406 | 3867 | ||
| 3407 | with块有助于简化编写这样的代码。在with块内,我们可以使用以.或\开头的特殊语句,这些语句代表我们正在使用的对象的操作。 | 3868 | with 块有助于简化编写这样的代码。在 with 块内,我们可以使用以 . 或 \ 开头的特殊语句,这些语句代表我们正在使用的对象的操作。 |
| 3408 | 3869 | ||
| 3409 | 例如,我们可以这样处理一个新创建的对象: | 3870 | 例如,我们可以这样处理一个新创建的对象: |
| 3410 | 3871 | ||
| @@ -3425,7 +3886,7 @@ with Person! | |||
| 3425 | </pre> | 3886 | </pre> |
| 3426 | </YueDisplay> | 3887 | </YueDisplay> |
| 3427 | 3888 | ||
| 3428 | with语句也可以用作一个表达式,并返回它的代码块正在处理的对象。 | 3889 | with 语句也可以用作一个表达式,并返回它的代码块正在处理的对象。 |
| 3429 | 3890 | ||
| 3430 | ```moonscript | 3891 | ```moonscript |
| 3431 | file = with File "favorite_foods.txt" | 3892 | file = with File "favorite_foods.txt" |
| @@ -3459,24 +3920,24 @@ me = create_person "Leaf", [dad, mother, sister] | |||
| 3459 | </pre> | 3920 | </pre> |
| 3460 | </YueDisplay> | 3921 | </YueDisplay> |
| 3461 | 3922 | ||
| 3462 | 在此用法中,with可以被视为K组合子(k-combinator)的一种特殊形式。 | 3923 | 在此用法中,with 可以被视为K组合子(k-combinator)的一种特殊形式。 |
| 3463 | 3924 | ||
| 3464 | 如果你想给表达式另外起一个名称的话,with语句中的表达式也可以是一个赋值语句。 | 3925 | 如果你想给表达式另外起一个名称的话,with 语句中的表达式也可以是一个赋值语句。 |
| 3465 | 3926 | ||
| 3466 | ```moonscript | 3927 | ```moonscript |
| 3467 | with str = "你好" | 3928 | with str := "你好" |
| 3468 | print "原始:", str | 3929 | print "原始:", str |
| 3469 | print "大写:", \upper! | 3930 | print "大写:", \upper! |
| 3470 | ``` | 3931 | ``` |
| 3471 | <YueDisplay> | 3932 | <YueDisplay> |
| 3472 | <pre> | 3933 | <pre> |
| 3473 | with str = "你好" | 3934 | with str := "你好" |
| 3474 | print "原始:", str | 3935 | print "原始:", str |
| 3475 | print "大写:", \upper! | 3936 | print "大写:", \upper! |
| 3476 | </pre> | 3937 | </pre> |
| 3477 | </YueDisplay> | 3938 | </YueDisplay> |
| 3478 | 3939 | ||
| 3479 | 在with语句中可用`[]`访问特殊键。 | 3940 | 你以 `with` 语句中使用 `[]` 访问特殊键。 |
| 3480 | 3941 | ||
| 3481 | ```moonscript | 3942 | ```moonscript |
| 3482 | with tb | 3943 | with tb |
| @@ -3499,9 +3960,22 @@ with tb | |||
| 3499 | </pre> | 3960 | </pre> |
| 3500 | </YueDisplay> | 3961 | </YueDisplay> |
| 3501 | 3962 | ||
| 3963 | `with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。 | ||
| 3964 | |||
| 3965 | ```moonscript | ||
| 3966 | with? obj | ||
| 3967 | print obj.name | ||
| 3968 | ``` | ||
| 3969 | <YueDisplay> | ||
| 3970 | <pre> | ||
| 3971 | with? obj | ||
| 3972 | print obj.name | ||
| 3973 | </pre> | ||
| 3974 | </YueDisplay> | ||
| 3975 | |||
| 3502 | ## do 语句 | 3976 | ## do 语句 |
| 3503 | 3977 | ||
| 3504 | 当用作语句时,do语句的作用就像在Lua中差不多。 | 3978 | 当用作语句时,do 语句的作用就像在 Lua 中差不多。 |
| 3505 | 3979 | ||
| 3506 | ```moonscript | 3980 | ```moonscript |
| 3507 | do | 3981 | do |
| @@ -3518,7 +3992,7 @@ print var -- 这里是nil | |||
| 3518 | </pre> | 3992 | </pre> |
| 3519 | </YueDisplay> | 3993 | </YueDisplay> |
| 3520 | 3994 | ||
| 3521 | 月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将do语句代码块的最后一个语句作为表达式返回的结果。 | 3995 | 月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将 do 语句代码块的最后一个语句作为表达式返回的结果。 |
| 3522 | 3996 | ||
| 3523 | ```moonscript | 3997 | ```moonscript |
| 3524 | counter = do | 3998 | counter = do |
| @@ -3702,7 +4176,7 @@ print i, k -- 这些已经被更新 | |||
| 3702 | 4176 | ||
| 3703 | ## 月之脚本语言库 | 4177 | ## 月之脚本语言库 |
| 3704 | 4178 | ||
| 3705 | 使用`require("yue")`来访问。 | 4179 | 使用 `require("yue")` 来访问。 |
| 3706 | 4180 | ||
| 3707 | ### yue | 4181 | ### yue |
| 3708 | 4182 | ||
| @@ -3760,9 +4234,9 @@ yue_compiled: {string: string} | |||
| 3760 | **签名:** | 4234 | **签名:** |
| 3761 | ```lua | 4235 | ```lua |
| 3762 | to_lua: function(code: string, config?: Config): | 4236 | to_lua: function(code: string, config?: Config): |
| 3763 | --[[codes]] string | nil, | 4237 | --[[codes]] string | nil, |
| 3764 | --[[error]] string | nil, | 4238 | --[[error]] string | nil, |
| 3765 | --[[globals]] {{string, integer, integer}} | nil | 4239 | --[[globals]] {{string, integer, integer}} | nil |
| 3766 | ``` | 4240 | ``` |
| 3767 | 4241 | ||
| 3768 | **参数:** | 4242 | **参数:** |
| @@ -3885,8 +4359,8 @@ remove_loader: function(): boolean | |||
| 3885 | **签名:** | 4359 | **签名:** |
| 3886 | ```lua | 4360 | ```lua |
| 3887 | loadstring: function(input: string, chunkname: string, env: table, config?: Config): | 4361 | loadstring: function(input: string, chunkname: string, env: table, config?: Config): |
| 3888 | --[[loaded function]] nil | function(...: any): (any...), | 4362 | --[[loaded function]] nil | function(...: any): (any...), |
| 3889 | --[[error]] string | nil | 4363 | --[[error]] string | nil |
| 3890 | ``` | 4364 | ``` |
| 3891 | 4365 | ||
| 3892 | **参数:** | 4366 | **参数:** |
| @@ -3916,8 +4390,8 @@ loadstring: function(input: string, chunkname: string, env: table, config?: Conf | |||
| 3916 | **签名:** | 4390 | **签名:** |
| 3917 | ```lua | 4391 | ```lua |
| 3918 | loadstring: function(input: string, chunkname: string, config?: Config): | 4392 | loadstring: function(input: string, chunkname: string, config?: Config): |
| 3919 | --[[loaded function]] nil | function(...: any): (any...), | 4393 | --[[loaded function]] nil | function(...: any): (any...), |
| 3920 | --[[error]] string | nil | 4394 | --[[error]] string | nil |
| 3921 | ``` | 4395 | ``` |
| 3922 | 4396 | ||
| 3923 | **参数:** | 4397 | **参数:** |
| @@ -3946,8 +4420,8 @@ loadstring: function(input: string, chunkname: string, config?: Config): | |||
| 3946 | **签名:** | 4420 | **签名:** |
| 3947 | ```lua | 4421 | ```lua |
| 3948 | loadstring: function(input: string, config?: Config): | 4422 | loadstring: function(input: string, config?: Config): |
| 3949 | --[[loaded function]] nil | function(...: any): (any...), | 4423 | --[[loaded function]] nil | function(...: any): (any...), |
| 3950 | --[[error]] string | nil | 4424 | --[[error]] string | nil |
| 3951 | ``` | 4425 | ``` |
| 3952 | 4426 | ||
| 3953 | **参数:** | 4427 | **参数:** |
| @@ -3975,8 +4449,8 @@ loadstring: function(input: string, config?: Config): | |||
| 3975 | **签名:** | 4449 | **签名:** |
| 3976 | ```lua | 4450 | ```lua |
| 3977 | loadfile: function(filename: string, env: table, config?: Config): | 4451 | loadfile: function(filename: string, env: table, config?: Config): |
| 3978 | nil | function(...: any): (any...), | 4452 | nil | function(...: any): (any...), |
| 3979 | string | nil | 4453 | string | nil |
| 3980 | ``` | 4454 | ``` |
| 3981 | 4455 | ||
| 3982 | **参数:** | 4456 | **参数:** |
| @@ -4005,8 +4479,8 @@ loadfile: function(filename: string, env: table, config?: Config): | |||
| 4005 | **签名:** | 4479 | **签名:** |
| 4006 | ```lua | 4480 | ```lua |
| 4007 | loadfile: function(filename: string, config?: Config): | 4481 | loadfile: function(filename: string, config?: Config): |
| 4008 | nil | function(...: any): (any...), | 4482 | nil | function(...: any): (any...), |
| 4009 | string | nil | 4483 | string | nil |
| 4010 | ``` | 4484 | ``` |
| 4011 | 4485 | ||
| 4012 | **参数:** | 4486 | **参数:** |
| @@ -4261,9 +4735,9 @@ type AST = {string, integer, integer, any} | |||
| 4261 | 4735 | ||
| 4262 | **签名:** | 4736 | **签名:** |
| 4263 | ```lua | 4737 | ```lua |
| 4264 | to_ast: function(code: string, flattenLevel?: number, astName?: string): | 4738 | to_ast: function(code: string, flattenLevel?: number, astName?: string, reserveComment?: boolean): |
| 4265 | --[[AST]] AST | nil, | 4739 | --[[AST]] AST | nil, |
| 4266 | --[[error]] nil | string | 4740 | --[[error]] nil | string |
| 4267 | ``` | 4741 | ``` |
| 4268 | 4742 | ||
| 4269 | **参数:** | 4743 | **参数:** |
| @@ -4272,6 +4746,42 @@ to_ast: function(code: string, flattenLevel?: number, astName?: string): | |||
| 4272 | | --- | --- | --- | | 4746 | | --- | --- | --- | |
| 4273 | | code | string | 代码。 | | 4747 | | code | string | 代码。 | |
| 4274 | | flattenLevel | integer | [可选] 扁平化级别。级别越高,会消除更多的 AST 结构的嵌套。默认为 0。最大为 2。 | | 4748 | | flattenLevel | integer | [可选] 扁平化级别。级别越高,会消除更多的 AST 结构的嵌套。默认为 0。最大为 2。 | |
| 4749 | | astName | string | [可选] AST 名称。默认为 "File"。 | | ||
| 4750 | | reserveComment | boolean | [可选] 是否保留原始注释。默认为 false。 | | ||
| 4751 | |||
| 4752 | **返回值:** | ||
| 4753 | |||
| 4754 | | 返回类型 | 描述 | | ||
| 4755 | | --- | --- | | ||
| 4756 | | AST \| nil | AST,如果转换失败则为 nil。 | | ||
| 4757 | | string \| nil | 错误消息,如果转换成功则为 nil。 | | ||
| 4758 | |||
| 4759 | #### format | ||
| 4760 | |||
| 4761 | **类型:** 函数。 | ||
| 4762 | |||
| 4763 | **描述:** | ||
| 4764 | |||
| 4765 | 格式化 YueScript 代码。 | ||
| 4766 | |||
| 4767 | **签名:** | ||
| 4768 | ```lua | ||
| 4769 | format: function(code: string, tabSize?: number, reserveComment?: boolean): string | ||
| 4770 | ``` | ||
| 4771 | |||
| 4772 | **参数:** | ||
| 4773 | |||
| 4774 | | 参数名 | 类型 | 描述 | | ||
| 4775 | | --- | --- | --- | | ||
| 4776 | | code | string | 代码。 | | ||
| 4777 | | tabSize | integer | [可选] 制表符大小。默认为 4。 | | ||
| 4778 | | reserveComment | boolean | [可选] 是否保留原始注释。默认为 true。 | | ||
| 4779 | |||
| 4780 | **返回值:** | ||
| 4781 | |||
| 4782 | | 返回类型 | 描述 | | ||
| 4783 | | --- | --- | | ||
| 4784 | | string | 格式化后的代码。 | | ||
| 4275 | 4785 | ||
| 4276 | #### __call | 4786 | #### __call |
| 4277 | 4787 | ||
| @@ -4344,6 +4854,19 @@ implicit_return_root: boolean | |||
| 4344 | reserve_line_number: boolean | 4854 | reserve_line_number: boolean |
| 4345 | ``` | 4855 | ``` |
| 4346 | 4856 | ||
| 4857 | #### reserve_comment | ||
| 4858 | |||
| 4859 | **类型:** 成员变量。 | ||
| 4860 | |||
| 4861 | **描述:** | ||
| 4862 | |||
| 4863 | 编译器是否应该在编译后的代码中保留原始注释。 | ||
| 4864 | |||
| 4865 | **签名:** | ||
| 4866 | ```lua | ||
| 4867 | reserve_comment: boolean | ||
| 4868 | ``` | ||
| 4869 | |||
| 4347 | #### space_over_tab | 4870 | #### space_over_tab |
| 4348 | 4871 | ||
| 4349 | **类型:** 成员变量。 | 4872 | **类型:** 成员变量。 |
| @@ -4394,11 +4917,11 @@ line_offset: integer | |||
| 4394 | **签名:** | 4917 | **签名:** |
| 4395 | ```lua | 4918 | ```lua |
| 4396 | enum LuaTarget | 4919 | enum LuaTarget |
| 4397 | "5.1" | 4920 | "5.1" |
| 4398 | "5.2" | 4921 | "5.2" |
| 4399 | "5.3" | 4922 | "5.3" |
| 4400 | "5.4" | 4923 | "5.4" |
| 4401 | "5.5" | 4924 | "5.5" |
| 4402 | end | 4925 | end |
| 4403 | ``` | 4926 | ``` |
| 4404 | 4927 | ||
