diff options
Diffstat (limited to 'doc/yue-zh.md')
| -rw-r--r-- | doc/yue-zh.md | 2495 |
1 files changed, 1 insertions, 2494 deletions
diff --git a/doc/yue-zh.md b/doc/yue-zh.md index 93e21d8..d8b5346 100644 --- a/doc/yue-zh.md +++ b/doc/yue-zh.md | |||
| @@ -1,11 +1,5 @@ | |||
| 1 | --- | ||
| 2 | title: 参考手册 | ||
| 3 | --- | ||
| 4 | |||
| 5 | # 月之脚本文档 | 1 | # 月之脚本文档 |
| 6 | 2 | ||
| 7 | <img src="/image/yuescript.svg" width="250px" height="250px" alt="logo" style="padding-top: 3em;padding-bottom: 2em;"/> | ||
| 8 | |||
| 9 | 欢迎来到 <b>月之脚本(YueScript)</b> 官方文档!<br/> | 3 | 欢迎来到 <b>月之脚本(YueScript)</b> 官方文档!<br/> |
| 10 | 这里收录了语言特性、用法、参考示例和资源。<br/> | 4 | 这里收录了语言特性、用法、参考示例和资源。<br/> |
| 11 | 请选择左侧的章节索引或目录,开启你的月之脚本之旅 ☽ | 5 | 请选择左侧的章节索引或目录,开启你的月之脚本之旅 ☽ |
| @@ -21,17 +15,6 @@ do | |||
| 21 | print var -- 这里是nil | 15 | print var -- 这里是nil |
| 22 | ``` | 16 | ``` |
| 23 | 17 | ||
| 24 | <YueDisplay> | ||
| 25 | |||
| 26 | ```yue | ||
| 27 | do | ||
| 28 | var = "hello" | ||
| 29 | print var | ||
| 30 | print var -- 这里是nil | ||
| 31 | ``` | ||
| 32 | |||
| 33 | </YueDisplay> | ||
| 34 | |||
| 35 |   月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将 do 语句代码块的最后一个语句作为表达式返回的结果。`do` 表达式支持通过 `break` 打断执行流并提前返回多个值。 | 18 |   月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将 do 语句代码块的最后一个语句作为表达式返回的结果。`do` 表达式支持通过 `break` 打断执行流并提前返回多个值。 |
| 36 | 19 | ||
| 37 | ```yuescript | 20 | ```yuescript |
| @@ -42,18 +25,6 @@ status, value = do | |||
| 42 | break "small", n | 25 | break "small", n |
| 43 | ``` | 26 | ``` |
| 44 | 27 | ||
| 45 | <YueDisplay> | ||
| 46 | |||
| 47 | ```yue | ||
| 48 | status, value = do | ||
| 49 | n = 12 | ||
| 50 | if n > 10 | ||
| 51 | break "large", n | ||
| 52 | break "small", n | ||
| 53 | ``` | ||
| 54 | |||
| 55 | </YueDisplay> | ||
| 56 | |||
| 57 | ```yuescript | 28 | ```yuescript |
| 58 | counter = do | 29 | counter = do |
| 59 | i = 0 | 30 | i = 0 |
| @@ -65,21 +36,6 @@ print counter! | |||
| 65 | print counter! | 36 | print counter! |
| 66 | ``` | 37 | ``` |
| 67 | 38 | ||
| 68 | <YueDisplay> | ||
| 69 | |||
| 70 | ```yue | ||
| 71 | counter = do | ||
| 72 | i = 0 | ||
| 73 | -> | ||
| 74 | i += 1 | ||
| 75 | i | ||
| 76 | |||
| 77 | print counter! | ||
| 78 | print counter! | ||
| 79 | ``` | ||
| 80 | |||
| 81 | </YueDisplay> | ||
| 82 | |||
| 83 | ```yuescript | 39 | ```yuescript |
| 84 | tbl = { | 40 | tbl = { |
| 85 | key: do | 41 | key: do |
| @@ -88,18 +44,6 @@ tbl = { | |||
| 88 | } | 44 | } |
| 89 | ``` | 45 | ``` |
| 90 | 46 | ||
| 91 | <YueDisplay> | ||
| 92 | |||
| 93 | ```yue | ||
| 94 | tbl = { | ||
| 95 | key: do | ||
| 96 | print "分配键值!" | ||
| 97 | 1234 | ||
| 98 | } | ||
| 99 | ``` | ||
| 100 | |||
| 101 | </YueDisplay> | ||
| 102 | |||
| 103 | # 代码行修饰 | 47 | # 代码行修饰 |
| 104 | 48 | ||
| 105 |   为了方便编写代码,循环语句和 if 语句可以应用于单行代码语句的末尾: | 49 |   为了方便编写代码,循环语句和 if 语句可以应用于单行代码语句的末尾: |
| @@ -108,28 +52,12 @@ tbl = { | |||
| 108 | print "你好,世界" if name == "Rob" | 52 | print "你好,世界" if name == "Rob" |
| 109 | ``` | 53 | ``` |
| 110 | 54 | ||
| 111 | <YueDisplay> | ||
| 112 | |||
| 113 | ```yue | ||
| 114 | print "你好,世界" if name == "Rob" | ||
| 115 | ``` | ||
| 116 | |||
| 117 | </YueDisplay> | ||
| 118 | |||
| 119 |   修饰 for 循环的示例: | 55 |   修饰 for 循环的示例: |
| 120 | 56 | ||
| 121 | ```yuescript | 57 | ```yuescript |
| 122 | print "项目: ", item for item in *items | 58 | print "项目: ", item for item in *items |
| 123 | ``` | 59 | ``` |
| 124 | 60 | ||
| 125 | <YueDisplay> | ||
| 126 | |||
| 127 | ```yue | ||
| 128 | print "项目: ", item for item in *items | ||
| 129 | ``` | ||
| 130 | |||
| 131 | </YueDisplay> | ||
| 132 | |||
| 133 |   修饰 while 循环的示例: | 61 |   修饰 while 循环的示例: |
| 134 | 62 | ||
| 135 | ```yuescript | 63 | ```yuescript |
| @@ -138,16 +66,6 @@ game\update! while game\isRunning! | |||
| 138 | reader\parse_line! until reader\eof! | 66 | reader\parse_line! until reader\eof! |
| 139 | ``` | 67 | ``` |
| 140 | 68 | ||
| 141 | <YueDisplay> | ||
| 142 | |||
| 143 | ```yue | ||
| 144 | game\update! while game\isRunning! | ||
| 145 | |||
| 146 | reader\parse_line! until reader\eof! | ||
| 147 | ``` | ||
| 148 | |||
| 149 | </YueDisplay> | ||
| 150 | |||
| 151 | # 宏 | 69 | # 宏 |
| 152 | 70 | ||
| 153 | ## 常见用法 | 71 | ## 常见用法 |
| @@ -183,39 +101,6 @@ if $and f1!, f2!, f3! | |||
| 183 | print "OK" | 101 | print "OK" |
| 184 | ``` | 102 | ``` |
| 185 | 103 | ||
| 186 | <YueDisplay> | ||
| 187 | |||
| 188 | ```yue | ||
| 189 | macro PI2 = -> math.pi * 2 | ||
| 190 | area = $PI2 * 5 | ||
| 191 | |||
| 192 | macro HELLO = -> "'你好 世界'" | ||
| 193 | print $HELLO | ||
| 194 | |||
| 195 | macro config = (debugging) -> | ||
| 196 | global debugMode = debugging == "true" | ||
| 197 | "" | ||
| 198 | |||
| 199 | macro asserts = (cond) -> | ||
| 200 | debugMode and "assert #{cond}" or "" | ||
| 201 | |||
| 202 | macro assert = (cond) -> | ||
| 203 | debugMode and "assert #{cond}" or "#{cond}" | ||
| 204 | |||
| 205 | $config true | ||
| 206 | $asserts item ~= nil | ||
| 207 | |||
| 208 | $config false | ||
| 209 | value = $assert item | ||
| 210 | |||
| 211 | -- 宏函数参数传递的表达式会被转换为字符串 | ||
| 212 | macro and = (...) -> "#{ table.concat {...}, ' and ' }" | ||
| 213 | if $and f1!, f2!, f3! | ||
| 214 | print "OK" | ||
| 215 | ``` | ||
| 216 | |||
| 217 | </YueDisplay> | ||
| 218 | |||
| 219 | ## 直接插入代码 | 104 | ## 直接插入代码 |
| 220 | 105 | ||
| 221 |   宏函数可以返回一个包含月之脚本代码的字符串,或是一个包含 Lua 代码字符串的配置表。 | 106 |   宏函数可以返回一个包含月之脚本代码的字符串,或是一个包含 Lua 代码字符串的配置表。 |
| @@ -246,36 +131,6 @@ end | |||
| 246 | ]==] | 131 | ]==] |
| 247 | ``` | 132 | ``` |
| 248 | 133 | ||
| 249 | <YueDisplay> | ||
| 250 | |||
| 251 | ```yue | ||
| 252 | macro yueFunc = (var) -> "local #{var} = ->" | ||
| 253 | $yueFunc funcA | ||
| 254 | funcA = -> "无法访问宏生成月之脚本里定义的变量" | ||
| 255 | |||
| 256 | macro luaFunc = (var) -> { | ||
| 257 | code: "local function #{var}() end" | ||
| 258 | type: "lua" | ||
| 259 | } | ||
| 260 | $luaFunc funcB | ||
| 261 | funcB = -> "无法访问宏生成 Lua 代码里定义的变量" | ||
| 262 | |||
| 263 | macro lua = (code) -> { | ||
| 264 | :code | ||
| 265 | type: "lua" | ||
| 266 | } | ||
| 267 | |||
| 268 | -- raw字符串的开始和结束符号会自动被去除了再传入宏函数 | ||
| 269 | $lua[==[ | ||
| 270 | -- 插入原始Lua代码 | ||
| 271 | if cond then | ||
| 272 | print("输出") | ||
| 273 | end | ||
| 274 | ]==] | ||
| 275 | ``` | ||
| 276 | |||
| 277 | </YueDisplay> | ||
| 278 | |||
| 279 | ## 导出宏 | 134 | ## 导出宏 |
| 280 | 135 | ||
| 281 |   宏函数可以从一个模块中导出,并在另一个模块中导入。你必须将导出的宏函数放在一个单独的文件中使用,而且只有宏定义、宏导入和宏展开可以放入这个宏导出模块中。 | 136 |   宏函数可以从一个模块中导出,并在另一个模块中导入。你必须将导出的宏函数放在一个单独的文件中使用,而且只有宏定义、宏导入和宏展开可以放入这个宏导出模块中。 |
| @@ -295,28 +150,6 @@ import "utils" as { | |||
| 295 | [1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _ | 150 | [1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _ |
| 296 | ``` | 151 | ``` |
| 297 | 152 | ||
| 298 | <YueDisplay> | ||
| 299 | |||
| 300 | ```yue | ||
| 301 | -- 文件: utils.yue | ||
| 302 | export macro map = (items, action) -> "[#{action} for _ in *#{items}]" | ||
| 303 | export macro filter = (items, action) -> "[_ for _ in *#{items} when #{action}]" | ||
| 304 | export macro foreach = (items, action) -> "for _ in *#{items} | ||
| 305 | #{action}" | ||
| 306 | |||
| 307 | -- 文件 main.yue | ||
| 308 | -- 在浏览器中不支持import函数,请在真实环境中尝试 | ||
| 309 | --[[ | ||
| 310 | import "utils" as { | ||
| 311 | $, -- 表示导入所有宏的符号 | ||
| 312 | $foreach: $each -- 重命名宏 $foreach 为 $each | ||
| 313 | } | ||
| 314 | [1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _ | ||
| 315 | ]] | ||
| 316 | ``` | ||
| 317 | |||
| 318 | </YueDisplay> | ||
| 319 | |||
| 320 | ## 内置宏 | 153 | ## 内置宏 |
| 321 | 154 | ||
| 322 |   月之脚本中有一些内置可以直接使用的宏,但你可以通过声明相同名称的宏来覆盖它们。 | 155 |   月之脚本中有一些内置可以直接使用的宏,但你可以通过声明相同名称的宏来覆盖它们。 |
| @@ -326,15 +159,6 @@ print $FILE -- 获取当前模块名称的字符串 | |||
| 326 | print $LINE -- 获取当前代码行数:2 | 159 | print $LINE -- 获取当前代码行数:2 |
| 327 | ``` | 160 | ``` |
| 328 | 161 | ||
| 329 | <YueDisplay> | ||
| 330 | |||
| 331 | ```yue | ||
| 332 | print $FILE -- 获取当前模块名称的字符串 | ||
| 333 | print $LINE -- 获取当前代码行数:2 | ||
| 334 | ``` | ||
| 335 | |||
| 336 | </YueDisplay> | ||
| 337 | |||
| 338 | ## 用宏生成宏 | 162 | ## 用宏生成宏 |
| 339 | 163 | ||
| 340 |   在月之脚本中,宏函数允许你在编译时生成代码。通过嵌套的宏函数,你可以创建更复杂的生成模式。这个特性允许你定义一个宏函数,用它来生成另一个宏函数,从而实现更加动态的代码生成。 | 164 |   在月之脚本中,宏函数允许你在编译时生成代码。通过嵌套的宏函数,你可以创建更复杂的生成模式。这个特性允许你定义一个宏函数,用它来生成另一个宏函数,从而实现更加动态的代码生成。 |
| @@ -357,28 +181,6 @@ print "有效的枚举类型:", $BodyType Static | |||
| 357 | -- print "编译报错的枚举类型:", $BodyType Unknown | 181 | -- print "编译报错的枚举类型:", $BodyType Unknown |
| 358 | ``` | 182 | ``` |
| 359 | 183 | ||
| 360 | <YueDisplay> | ||
| 361 | |||
| 362 | ```yue | ||
| 363 | macro Enum = (...) -> | ||
| 364 | items = {...} | ||
| 365 | itemSet = {item, true for item in *items} | ||
| 366 | (item) -> | ||
| 367 | error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item] | ||
| 368 | "\"#{item}\"" | ||
| 369 | |||
| 370 | macro BodyType = $Enum( | ||
| 371 | Static | ||
| 372 | Dynamic | ||
| 373 | Kinematic | ||
| 374 | ) | ||
| 375 | |||
| 376 | print "有效的枚举类型:", $BodyType Static | ||
| 377 | -- print "编译报错的枚举类型:", $BodyType Unknown | ||
| 378 | ``` | ||
| 379 | |||
| 380 | </YueDisplay> | ||
| 381 | |||
| 382 | ## 宏参数检查 | 184 | ## 宏参数检查 |
| 383 | 185 | ||
| 384 |   可以直接在参数列表中声明期望的 AST 节点类型,并在编译时检查传入的宏参数是否符合预期。 | 186 |   可以直接在参数列表中声明期望的 AST 节点类型,并在编译时检查传入的宏参数是否符合预期。 |
| @@ -393,20 +195,6 @@ macro printNumAndStr = (num `Num, str `String) -> | | |||
| 393 | $printNumAndStr 123, "hello" | 195 | $printNumAndStr 123, "hello" |
| 394 | ``` | 196 | ``` |
| 395 | 197 | ||
| 396 | <YueDisplay> | ||
| 397 | |||
| 398 | ```yue | ||
| 399 | macro printNumAndStr = (num `Num, str `String) -> | | ||
| 400 | print( | ||
| 401 | #{num} | ||
| 402 | #{str} | ||
| 403 | ) | ||
| 404 | |||
| 405 | $printNumAndStr 123, "hello" | ||
| 406 | ``` | ||
| 407 | |||
| 408 | </YueDisplay> | ||
| 409 | |||
| 410 |   如果需要做更加灵活的参数检查操作,可以使用内置的 `$is_ast` 宏函数在合适的位置进行手动检查。 | 198 |   如果需要做更加灵活的参数检查操作,可以使用内置的 `$is_ast` 宏函数在合适的位置进行手动检查。 |
| 411 | 199 | ||
| 412 | ```yuescript | 200 | ```yuescript |
| @@ -418,19 +206,6 @@ macro printNumAndStr = (num, str) -> | |||
| 418 | $printNumAndStr 123, "hello" | 206 | $printNumAndStr 123, "hello" |
| 419 | ``` | 207 | ``` |
| 420 | 208 | ||
| 421 | <YueDisplay> | ||
| 422 | |||
| 423 | ```yue | ||
| 424 | macro printNumAndStr = (num, str) -> | ||
| 425 | error "expected Num as first argument" unless $is_ast Num, num | ||
| 426 | error "expected String as second argument" unless $is_ast String, str | ||
| 427 | "print(#{num}, #{str})" | ||
| 428 | |||
| 429 | $printNumAndStr 123, "hello" | ||
| 430 | ``` | ||
| 431 | |||
| 432 | </YueDisplay> | ||
| 433 | |||
| 434 |   更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。 | 209 |   更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。 |
| 435 | 210 | ||
| 436 | # 错误处理 | 211 | # 错误处理 |
| @@ -465,38 +240,6 @@ catch err | |||
| 465 | print result | 240 | print result |
| 466 | ``` | 241 | ``` |
| 467 | 242 | ||
| 468 | <YueDisplay> | ||
| 469 | |||
| 470 | ```yue | ||
| 471 | try | ||
| 472 | func 1, 2, 3 | ||
| 473 | catch err | ||
| 474 | print yue.traceback err | ||
| 475 | |||
| 476 | success, result = try | ||
| 477 | func 1, 2, 3 | ||
| 478 | catch err | ||
| 479 | yue.traceback err | ||
| 480 | |||
| 481 | try func 1, 2, 3 | ||
| 482 | catch err | ||
| 483 | print yue.traceback err | ||
| 484 | |||
| 485 | success, result = try func 1, 2, 3 | ||
| 486 | |||
| 487 | try | ||
| 488 | print "尝试中" | ||
| 489 | func 1, 2, 3 | ||
| 490 | |||
| 491 | -- 使用if赋值模式 | ||
| 492 | if success, result := try func 1, 2, 3 | ||
| 493 | catch err | ||
| 494 | print yue.traceback err | ||
| 495 | print result | ||
| 496 | ``` | ||
| 497 | |||
| 498 | </YueDisplay> | ||
| 499 | |||
| 500 | ## 错误处理简化 | 243 | ## 错误处理简化 |
| 501 | 244 | ||
| 502 |   `try?` 是 `try` 的功能简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。 | 245 |   `try?` 是 `try` 的功能简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。 |
| @@ -519,44 +262,14 @@ catch e | |||
| 519 | e | 262 | e |
| 520 | ``` | 263 | ``` |
| 521 | 264 | ||
| 522 | <YueDisplay> | ||
| 523 | |||
| 524 | ```yue | ||
| 525 | a, b, c = try? func! | ||
| 526 | |||
| 527 | -- 与空值合并运算符一起使用 | ||
| 528 | a = (try? func!) ?? "default" | ||
| 529 | |||
| 530 | -- 作为函数参数 | ||
| 531 | f try? func! | ||
| 532 | |||
| 533 | -- 带 catch 块的 try! | ||
| 534 | f try? | ||
| 535 | print 123 | ||
| 536 | func! | ||
| 537 | catch e | ||
| 538 | print e | ||
| 539 | e | ||
| 540 | ``` | ||
| 541 | |||
| 542 | </YueDisplay> | ||
| 543 | |||
| 544 | # 表格字面量 | 265 | # 表格字面量 |
| 545 | 266 | ||
| 546 |   和 Lua 一样,表格可以通过花括号进行定义。 | 267 |   和 Lua 一样,表格可以通过花括号进行定义。 |
| 547 | 268 | ||
| 548 | ```yuescript | 269 | ```yuescript |
| 549 | some_values = [1, 2, 3, 4] | 270 | some_values = {1, 2, 3, 4} |
| 550 | ``` | ||
| 551 | |||
| 552 | <YueDisplay> | ||
| 553 | |||
| 554 | ```yue | ||
| 555 | some_values = [1, 2, 3, 4] | ||
| 556 | ``` | 271 | ``` |
| 557 | 272 | ||
| 558 | </YueDisplay> | ||
| 559 | |||
| 560 |   但与Lua不同的是,给表格中的键赋值是用 **:**(而不是 **=**)。 | 273 |   但与Lua不同的是,给表格中的键赋值是用 **:**(而不是 **=**)。 |
| 561 | 274 | ||
| 562 | ```yuescript | 275 | ```yuescript |
| @@ -567,18 +280,6 @@ some_values = { | |||
| 567 | } | 280 | } |
| 568 | ``` | 281 | ``` |
| 569 | 282 | ||
| 570 | <YueDisplay> | ||
| 571 | |||
| 572 | ```yue | ||
| 573 | some_values = { | ||
| 574 | name: "Bill", | ||
| 575 | age: 200, | ||
| 576 | ["favorite food"]: "rice" | ||
| 577 | } | ||
| 578 | ``` | ||
| 579 | |||
| 580 | </YueDisplay> | ||
| 581 | |||
| 582 |   如果只分配一个键值对的表格,可以省略花括号。 | 283 |   如果只分配一个键值对的表格,可以省略花括号。 |
| 583 | 284 | ||
| 584 | ```yuescript | 285 | ```yuescript |
| @@ -588,17 +289,6 @@ profile = | |||
| 588 | favorite_foods: ["冰淇淋", "甜甜圈"] | 289 | favorite_foods: ["冰淇淋", "甜甜圈"] |
| 589 | ``` | 290 | ``` |
| 590 | 291 | ||
| 591 | <YueDisplay> | ||
| 592 | |||
| 593 | ```yue | ||
| 594 | profile = | ||
| 595 | height: "4英尺", | ||
| 596 | shoe_size: 13, | ||
| 597 | favorite_foods: ["冰淇淋", "甜甜圈"] | ||
| 598 | ``` | ||
| 599 | |||
| 600 | </YueDisplay> | ||
| 601 | |||
| 602 |   可以使用换行符而不使用逗号(或两者都用)来分隔表格中的值: | 292 |   可以使用换行符而不使用逗号(或两者都用)来分隔表格中的值: |
| 603 | 293 | ||
| 604 | ```yuescript | 294 | ```yuescript |
| @@ -610,19 +300,6 @@ values = { | |||
| 610 | } | 300 | } |
| 611 | ``` | 301 | ``` |
| 612 | 302 | ||
| 613 | <YueDisplay> | ||
| 614 | |||
| 615 | ```yue | ||
| 616 | values = { | ||
| 617 | 1, 2, 3, 4 | ||
| 618 | 5, 6, 7, 8 | ||
| 619 | name: "超人" | ||
| 620 | occupation: "打击犯罪" | ||
| 621 | } | ||
| 622 | ``` | ||
| 623 | |||
| 624 | </YueDisplay> | ||
| 625 | |||
| 626 |   创建单行表格字面量时,也可以省略花括号: | 303 |   创建单行表格字面量时,也可以省略花括号: |
| 627 | 304 | ||
| 628 | ```yuescript | 305 | ```yuescript |
| @@ -631,16 +308,6 @@ my_function dance: "探戈", partner: "无" | |||
| 631 | y = type: "狗", legs: 4, tails: 1 | 308 | y = type: "狗", legs: 4, tails: 1 |
| 632 | ``` | 309 | ``` |
| 633 | 310 | ||
| 634 | <YueDisplay> | ||
| 635 | |||
| 636 | ```yue | ||
| 637 | my_function dance: "探戈", partner: "无" | ||
| 638 | |||
| 639 | y = type: "狗", legs: 4, tails: 1 | ||
| 640 | ``` | ||
| 641 | |||
| 642 | </YueDisplay> | ||
| 643 | |||
| 644 |   表格字面量的键可以使用 Lua 语言的关键字,而无需转义: | 311 |   表格字面量的键可以使用 Lua 语言的关键字,而无需转义: |
| 645 | 312 | ||
| 646 | ```yuescript | 313 | ```yuescript |
| @@ -650,17 +317,6 @@ tbl = { | |||
| 650 | } | 317 | } |
| 651 | ``` | 318 | ``` |
| 652 | 319 | ||
| 653 | <YueDisplay> | ||
| 654 | |||
| 655 | ```yue | ||
| 656 | tbl = { | ||
| 657 | do: "某事" | ||
| 658 | end: "饥饿" | ||
| 659 | } | ||
| 660 | ``` | ||
| 661 | |||
| 662 | </YueDisplay> | ||
| 663 | |||
| 664 |   如果你要构造一个由变量组成的表,并希望键与变量名相同,那么可以使用 **:** 前缀操作符: | 320 |   如果你要构造一个由变量组成的表,并希望键与变量名相同,那么可以使用 **:** 前缀操作符: |
| 665 | 321 | ||
| 666 | ```yuescript | 322 | ```yuescript |
| @@ -671,18 +327,6 @@ person = { :hair, :height, shoe_size: 40 } | |||
| 671 | print_table :hair, :height | 327 | print_table :hair, :height |
| 672 | ``` | 328 | ``` |
| 673 | 329 | ||
| 674 | <YueDisplay> | ||
| 675 | |||
| 676 | ```yue | ||
| 677 | hair = "金色" | ||
| 678 | height = 200 | ||
| 679 | person = { :hair, :height, shoe_size: 40 } | ||
| 680 | |||
| 681 | print_table :hair, :height | ||
| 682 | ``` | ||
| 683 | |||
| 684 | </YueDisplay> | ||
| 685 | |||
| 686 |   如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在 Lua 中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。 | 330 |   如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在 Lua 中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。 |
| 687 | 331 | ||
| 688 | ```yuescript | 332 | ```yuescript |
| @@ -692,17 +336,6 @@ t = { | |||
| 692 | } | 336 | } |
| 693 | ``` | 337 | ``` |
| 694 | 338 | ||
| 695 | <YueDisplay> | ||
| 696 | |||
| 697 | ```yue | ||
| 698 | t = { | ||
| 699 | [1 + 2]: "你好" | ||
| 700 | "你好 世界": true | ||
| 701 | } | ||
| 702 | ``` | ||
| 703 | |||
| 704 | </YueDisplay> | ||
| 705 | |||
| 706 |   Lua 的表同时具有数组部分和哈希部分,但有时候你会希望在书写 Lua 表时,对 Lua 表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。 | 339 |   Lua 的表同时具有数组部分和哈希部分,但有时候你会希望在书写 Lua 表时,对 Lua 表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。 |
| 707 | 340 | ||
| 708 | ```yuescript | 341 | ```yuescript |
| @@ -710,15 +343,6 @@ some_values = [ 1, 2, 3, 4 ] | |||
| 710 | list_with_one_element = [ 1, ] | 343 | list_with_one_element = [ 1, ] |
| 711 | ``` | 344 | ``` |
| 712 | 345 | ||
| 713 | <YueDisplay> | ||
| 714 | |||
| 715 | ```yue | ||
| 716 | some_values = [ 1, 2, 3, 4 ] | ||
| 717 | list_with_one_element = [ 1, ] | ||
| 718 | ``` | ||
| 719 | |||
| 720 | </YueDisplay> | ||
| 721 | |||
| 722 | # 推导式 | 346 | # 推导式 |
| 723 | 347 | ||
| 724 |   推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生 Lua 表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。 | 348 |   推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生 Lua 表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。 |
| @@ -732,43 +356,18 @@ items = [1, 2, 3, 4] | |||
| 732 | doubled = [item * 2 for i, item in ipairs items] | 356 | doubled = [item * 2 for i, item in ipairs items] |
| 733 | ``` | 357 | ``` |
| 734 | 358 | ||
| 735 | <YueDisplay> | ||
| 736 | |||
| 737 | ```yue | ||
| 738 | items = [1, 2, 3, 4] | ||
| 739 | doubled = [item * 2 for i, item in ipairs items] | ||
| 740 | ``` | ||
| 741 | |||
| 742 | </YueDisplay> | ||
| 743 | |||
| 744 |   可以使用 `when` 子句筛选新表中包含的项目: | 359 |   可以使用 `when` 子句筛选新表中包含的项目: |
| 745 | 360 | ||
| 746 | ```yuescript | 361 | ```yuescript |
| 747 | slice = [item for i, item in ipairs items when i > 1 and i < 3] | 362 | slice = [item for i, item in ipairs items when i > 1 and i < 3] |
| 748 | ``` | 363 | ``` |
| 749 | 364 | ||
| 750 | <YueDisplay> | ||
| 751 | |||
| 752 | ```yue | ||
| 753 | slice = [item for i, item in ipairs items when i > 1 and i < 3] | ||
| 754 | ``` | ||
| 755 | |||
| 756 | </YueDisplay> | ||
| 757 | |||
| 758 |   因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled 示例可以重写为: | 365 |   因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled 示例可以重写为: |
| 759 | 366 | ||
| 760 | ```yuescript | 367 | ```yuescript |
| 761 | doubled = [item * 2 for item in *items] | 368 | doubled = [item * 2 for item in *items] |
| 762 | ``` | 369 | ``` |
| 763 | 370 | ||
| 764 | <YueDisplay> | ||
| 765 | |||
| 766 | ```yue | ||
| 767 | doubled = [item * 2 for item in *items] | ||
| 768 | ``` | ||
| 769 | |||
| 770 | </YueDisplay> | ||
| 771 | |||
| 772 |   在列表推导式中,你还可以使用展开操作符 `...` 来实现对列表嵌套层级进行扁平化的处理: | 371 |   在列表推导式中,你还可以使用展开操作符 `...` 来实现对列表嵌套层级进行扁平化的处理: |
| 773 | 372 | ||
| 774 | ```yuescript | 373 | ```yuescript |
| @@ -780,19 +379,6 @@ flat = [...v for k,v in pairs data] | |||
| 780 | -- flat 现在为 [1, 2, 3, 4, 5, 6] | 379 | -- flat 现在为 [1, 2, 3, 4, 5, 6] |
| 781 | ``` | 380 | ``` |
| 782 | 381 | ||
| 783 | <YueDisplay> | ||
| 784 | |||
| 785 | ```yue | ||
| 786 | data = | ||
| 787 | a: [1, 2, 3] | ||
| 788 | b: [4, 5, 6] | ||
| 789 | |||
| 790 | flat = [...v for k,v in pairs data] | ||
| 791 | -- flat 现在为 [1, 2, 3, 4, 5, 6] | ||
| 792 | ``` | ||
| 793 | |||
| 794 | </YueDisplay> | ||
| 795 | |||
| 796 |   for 和 when 子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个 for 子句。 | 382 |   for 和 when 子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个 for 子句。 |
| 797 | 383 | ||
| 798 |   使用多个 for 子句与使用多重循环的效果相同: | 384 |   使用多个 for 子句与使用多重循环的效果相同: |
| @@ -805,32 +391,12 @@ points = [ [x, y] for x in *x_coords \ | |||
| 805 | for y in *y_coords] | 391 | for y in *y_coords] |
| 806 | ``` | 392 | ``` |
| 807 | 393 | ||
| 808 | <YueDisplay> | ||
| 809 | |||
| 810 | ```yue | ||
| 811 | x_coords = [4, 5, 6, 7] | ||
| 812 | y_coords = [9, 2, 3] | ||
| 813 | |||
| 814 | points = [ [x, y] for x in *x_coords \ | ||
| 815 | for y in *y_coords] | ||
| 816 | ``` | ||
| 817 | |||
| 818 | </YueDisplay> | ||
| 819 | |||
| 820 |   在推导式中也可以使用简单的数值 for 循环: | 394 |   在推导式中也可以使用简单的数值 for 循环: |
| 821 | 395 | ||
| 822 | ```yuescript | 396 | ```yuescript |
| 823 | evens = [i for i = 1, 100 when i % 2 == 0] | 397 | evens = [i for i = 1, 100 when i % 2 == 0] |
| 824 | ``` | 398 | ``` |
| 825 | 399 | ||
| 826 | <YueDisplay> | ||
| 827 | |||
| 828 | ```yue | ||
| 829 | evens = [i for i = 1, 100 when i % 2 == 0] | ||
| 830 | ``` | ||
| 831 | |||
| 832 | </YueDisplay> | ||
| 833 | |||
| 834 | ## 表格推导式 | 400 | ## 表格推导式 |
| 835 | 401 | ||
| 836 |   表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。 | 402 |   表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。 |
| @@ -847,32 +413,10 @@ thing = { | |||
| 847 | thing_copy = {k, v for k, v in pairs thing} | 413 | thing_copy = {k, v for k, v in pairs thing} |
| 848 | ``` | 414 | ``` |
| 849 | 415 | ||
| 850 | <YueDisplay> | ||
| 851 | |||
| 852 | ```yue | ||
| 853 | thing = { | ||
| 854 | color: "red" | ||
| 855 | name: "fast" | ||
| 856 | width: 123 | ||
| 857 | } | ||
| 858 | |||
| 859 | thing_copy = {k, v for k, v in pairs thing} | ||
| 860 | ``` | ||
| 861 | |||
| 862 | </YueDisplay> | ||
| 863 | |||
| 864 | ```yuescript | 416 | ```yuescript |
| 865 | no_color = {k, v for k, v in pairs thing when k != "color"} | 417 | no_color = {k, v for k, v in pairs thing when k != "color"} |
| 866 | ``` | 418 | ``` |
| 867 | 419 | ||
| 868 | <YueDisplay> | ||
| 869 | |||
| 870 | ```yue | ||
| 871 | no_color = {k, v for k, v in pairs thing when k != "color"} | ||
| 872 | ``` | ||
| 873 | |||
| 874 | </YueDisplay> | ||
| 875 | |||
| 876 |   **\*** 操作符在表格推导式中能使用。在下面的例子里,我们为几个数字创建了一个平方根查找表。 | 420 |   **\*** 操作符在表格推导式中能使用。在下面的例子里,我们为几个数字创建了一个平方根查找表。 |
| 877 | 421 | ||
| 878 | ```yuescript | 422 | ```yuescript |
| @@ -880,15 +424,6 @@ numbers = [1, 2, 3, 4] | |||
| 880 | sqrts = {i, math.sqrt i for i in *numbers} | 424 | sqrts = {i, math.sqrt i for i in *numbers} |
| 881 | ``` | 425 | ``` |
| 882 | 426 | ||
| 883 | <YueDisplay> | ||
| 884 | |||
| 885 | ```yue | ||
| 886 | numbers = [1, 2, 3, 4] | ||
| 887 | sqrts = {i, math.sqrt i for i in *numbers} | ||
| 888 | ``` | ||
| 889 | |||
| 890 | </YueDisplay> | ||
| 891 | |||
| 892 |   表格推导式中的键值元组也可以来自单个表达式,在这种情况下,表达式在计算后应返回两个值。第一个用作键,第二个用作值: | 427 |   表格推导式中的键值元组也可以来自单个表达式,在这种情况下,表达式在计算后应返回两个值。第一个用作键,第二个用作值: |
| 893 | 428 | ||
| 894 |   在下面的示例中,我们将一些数组转换为一个表,其中每个数组里的第一项是键,第二项是值。 | 429 |   在下面的示例中,我们将一些数组转换为一个表,其中每个数组里的第一项是键,第二项是值。 |
| @@ -898,15 +433,6 @@ tuples = [ ["hello", "world"], ["foo", "bar"]] | |||
| 898 | tbl = {unpack tuple for tuple in *tuples} | 433 | tbl = {unpack tuple for tuple in *tuples} |
| 899 | ``` | 434 | ``` |
| 900 | 435 | ||
| 901 | <YueDisplay> | ||
| 902 | |||
| 903 | ```yue | ||
| 904 | tuples = [ ["hello", "world"], ["foo", "bar"]] | ||
| 905 | tbl = {unpack tuple for tuple in *tuples} | ||
| 906 | ``` | ||
| 907 | |||
| 908 | </YueDisplay> | ||
| 909 | |||
| 910 | ## 切片 | 436 | ## 切片 |
| 911 | 437 | ||
| 912 |   当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在 for 循环中设置迭代边界和步长。 | 438 |   当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在 for 循环中设置迭代边界和步长。 |
| @@ -917,42 +443,18 @@ tbl = {unpack tuple for tuple in *tuples} | |||
| 917 | slice = [item for item in *items[1, 5]] | 443 | slice = [item for item in *items[1, 5]] |
| 918 | ``` | 444 | ``` |
| 919 | 445 | ||
| 920 | <YueDisplay> | ||
| 921 | |||
| 922 | ```yue | ||
| 923 | slice = [item for item in *items[1, 5]] | ||
| 924 | ``` | ||
| 925 | |||
| 926 | </YueDisplay> | ||
| 927 | |||
| 928 |   切片的任意参数都可以省略,并会使用默认值。在如下示例中,如果省略了最大索引边界,它默认为表的长度。使下面的代码取除第一个元素之外的所有元素: | 446 |   切片的任意参数都可以省略,并会使用默认值。在如下示例中,如果省略了最大索引边界,它默认为表的长度。使下面的代码取除第一个元素之外的所有元素: |
| 929 | 447 | ||
| 930 | ```yuescript | 448 | ```yuescript |
| 931 | slice = [item for item in *items[2,]] | 449 | slice = [item for item in *items[2,]] |
| 932 | ``` | 450 | ``` |
| 933 | 451 | ||
| 934 | <YueDisplay> | ||
| 935 | |||
| 936 | ```yue | ||
| 937 | slice = [item for item in *items[2,]] | ||
| 938 | ``` | ||
| 939 | |||
| 940 | </YueDisplay> | ||
| 941 | |||
| 942 |   如果省略了最小边界,便默认会设置为 1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …) | 452 |   如果省略了最小边界,便默认会设置为 1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …) |
| 943 | 453 | ||
| 944 | ```yuescript | 454 | ```yuescript |
| 945 | slice = [item for item in *items[,,2]] | 455 | slice = [item for item in *items[,,2]] |
| 946 | ``` | 456 | ``` |
| 947 | 457 | ||
| 948 | <YueDisplay> | ||
| 949 | |||
| 950 | ```yue | ||
| 951 | slice = [item for item in *items[,,2]] | ||
| 952 | ``` | ||
| 953 | |||
| 954 | </YueDisplay> | ||
| 955 | |||
| 956 |   最小和最大边界都可以是负数,使用负数意味着边界是从表的末尾开始计算的。 | 458 |   最小和最大边界都可以是负数,使用负数意味着边界是从表的末尾开始计算的。 |
| 957 | 459 | ||
| 958 | ```yuescript | 460 | ```yuescript |
| @@ -960,29 +462,12 @@ slice = [item for item in *items[,,2]] | |||
| 960 | slice = [item for item in *items[-4,-1]] | 462 | slice = [item for item in *items[-4,-1]] |
| 961 | ``` | 463 | ``` |
| 962 | 464 | ||
| 963 | <YueDisplay> | ||
| 964 | |||
| 965 | ```yue | ||
| 966 | -- 取最后4个元素 | ||
| 967 | slice = [item for item in *items[-4,-1]] | ||
| 968 | ``` | ||
| 969 | |||
| 970 | </YueDisplay> | ||
| 971 | |||
| 972 |   切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。 | 465 |   切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。 |
| 973 | 466 | ||
| 974 | ```yuescript | 467 | ```yuescript |
| 975 | reverse_slice = [item for item in *items[-1,1,-1]] | 468 | reverse_slice = [item for item in *items[-1,1,-1]] |
| 976 | ``` | 469 | ``` |
| 977 | 470 | ||
| 978 | <YueDisplay> | ||
| 979 | |||
| 980 | ```yue | ||
| 981 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
| 982 | ``` | ||
| 983 | |||
| 984 | </YueDisplay> | ||
| 985 | |||
| 986 | ### 切片表达式 | 471 | ### 切片表达式 |
| 987 | 472 | ||
| 988 |   切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。 | 473 |   切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。 |
| @@ -995,18 +480,6 @@ sub_list = items[2, 4] | |||
| 995 | last_four_items = items[-4, -1] | 480 | last_four_items = items[-4, -1] |
| 996 | ``` | 481 | ``` |
| 997 | 482 | ||
| 998 | <YueDisplay> | ||
| 999 | |||
| 1000 | ```yue | ||
| 1001 | -- 取第2和第4个元素作为新的列表 | ||
| 1002 | sub_list = items[2, 4] | ||
| 1003 | |||
| 1004 | -- 取最后4个元素作为新的列表 | ||
| 1005 | last_four_items = items[-4, -1] | ||
| 1006 | ``` | ||
| 1007 | |||
| 1008 | </YueDisplay> | ||
| 1009 | |||
| 1010 | # 面向对象编程 | 483 | # 面向对象编程 |
| 1011 | 484 | ||
| 1012 |   在以下的示例中,月之脚本生成的 Lua 代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看 Lua 代码。 | 485 |   在以下的示例中,月之脚本生成的 Lua 代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看 Lua 代码。 |
| @@ -1025,22 +498,6 @@ class Inventory | |||
| 1025 | @items[name] = 1 | 498 | @items[name] = 1 |
| 1026 | ``` | 499 | ``` |
| 1027 | 500 | ||
| 1028 | <YueDisplay> | ||
| 1029 | |||
| 1030 | ```yue | ||
| 1031 | class Inventory | ||
| 1032 | new: => | ||
| 1033 | @items = {} | ||
| 1034 | |||
| 1035 | add_item: (name) => | ||
| 1036 | if @items[name] | ||
| 1037 | @items[name] += 1 | ||
| 1038 | else | ||
| 1039 | @items[name] = 1 | ||
| 1040 | ``` | ||
| 1041 | |||
| 1042 | </YueDisplay> | ||
| 1043 | |||
| 1044 |   在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合 Lua 表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为 “new” 的成员扮演了一个重要的角色,是作为构造函数来使用。 | 501 |   在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合 Lua 表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为 “new” 的成员扮演了一个重要的角色,是作为构造函数来使用。 |
| 1045 | 502 | ||
| 1046 |   值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为 “self” 的参数。 | 503 |   值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为 “self” 的参数。 |
| @@ -1055,16 +512,6 @@ inv\add_item "t-shirt" | |||
| 1055 | inv\add_item "pants" | 512 | inv\add_item "pants" |
| 1056 | ``` | 513 | ``` |
| 1057 | 514 | ||
| 1058 | <YueDisplay> | ||
| 1059 | |||
| 1060 | ```yue | ||
| 1061 | inv = Inventory! | ||
| 1062 | inv\add_item "t-shirt" | ||
| 1063 | inv\add_item "pants" | ||
| 1064 | ``` | ||
| 1065 | |||
| 1066 | </YueDisplay> | ||
| 1067 | |||
| 1068 |   在月之脚本的类中,由于需要将类的实例作为参数传入到调用的方法中,因此使用了 **\\** 操作符做类的成员函数调用。 | 515 |   在月之脚本的类中,由于需要将类的实例作为参数传入到调用的方法中,因此使用了 **\\** 操作符做类的成员函数调用。 |
| 1069 | 516 | ||
| 1070 |   需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 | 517 |   需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 |
| @@ -1087,26 +534,6 @@ b\give_item "shirt" | |||
| 1087 | print item for item in *a.clothes | 534 | print item for item in *a.clothes |
| 1088 | ``` | 535 | ``` |
| 1089 | 536 | ||
| 1090 | <YueDisplay> | ||
| 1091 | |||
| 1092 | ```yue | ||
| 1093 | class Person | ||
| 1094 | clothes: [] | ||
| 1095 | give_item: (name) => | ||
| 1096 | table.insert @clothes, name | ||
| 1097 | |||
| 1098 | a = Person! | ||
| 1099 | b = Person! | ||
| 1100 | |||
| 1101 | a\give_item "pants" | ||
| 1102 | b\give_item "shirt" | ||
| 1103 | |||
| 1104 | -- 会同时打印出裤子和衬衫 | ||
| 1105 | print item for item in *a.clothes | ||
| 1106 | ``` | ||
| 1107 | |||
| 1108 | </YueDisplay> | ||
| 1109 | |||
| 1110 |   避免这个问题的正确方法是在构造函数中创建对象的可变状态: | 537 |   避免这个问题的正确方法是在构造函数中创建对象的可变状态: |
| 1111 | 538 | ||
| 1112 | ```yuescript | 539 | ```yuescript |
| @@ -1115,16 +542,6 @@ class Person | |||
| 1115 | @clothes = [] | 542 | @clothes = [] |
| 1116 | ``` | 543 | ``` |
| 1117 | 544 | ||
| 1118 | <YueDisplay> | ||
| 1119 | |||
| 1120 | ```yue | ||
| 1121 | class Person | ||
| 1122 | new: => | ||
| 1123 | @clothes = [] | ||
| 1124 | ``` | ||
| 1125 | |||
| 1126 | </YueDisplay> | ||
| 1127 | |||
| 1128 | ## 继承 | 545 | ## 继承 |
| 1129 | 546 | ||
| 1130 |   `extends` 关键字可以在类声明中使用,以继承另一个类的属性和方法。 | 547 |   `extends` 关键字可以在类声明中使用,以继承另一个类的属性和方法。 |
| @@ -1137,18 +554,6 @@ class BackPack extends Inventory | |||
| 1137 | super name | 554 | super name |
| 1138 | ``` | 555 | ``` |
| 1139 | 556 | ||
| 1140 | <YueDisplay> | ||
| 1141 | |||
| 1142 | ```yue | ||
| 1143 | class BackPack extends Inventory | ||
| 1144 | size: 10 | ||
| 1145 | add_item: (name) => | ||
| 1146 | if #@items > size then error "背包已满" | ||
| 1147 | super name | ||
| 1148 | ``` | ||
| 1149 | |||
| 1150 | </YueDisplay> | ||
| 1151 | |||
| 1152 |   在这一部分,我们对月之脚本中的 `Inventory` 类进行了扩展,加入了对可以携带物品数量的限制。 | 557 |   在这一部分,我们对月之脚本中的 `Inventory` 类进行了扩展,加入了对可以携带物品数量的限制。 |
| 1153 | 558 | ||
| 1154 |   在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用 `super` 方法来调用并执行父类的构造函数。 | 559 |   在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用 `super` 方法来调用并执行父类的构造函数。 |
| @@ -1164,19 +569,6 @@ class Shelf | |||
| 1164 | class Cupboard extends Shelf | 569 | class Cupboard extends Shelf |
| 1165 | ``` | 570 | ``` |
| 1166 | 571 | ||
| 1167 | <YueDisplay> | ||
| 1168 | |||
| 1169 | ```yue | ||
| 1170 | class Shelf | ||
| 1171 | @__inherited: (child) => | ||
| 1172 | print @__name, "被", child.__name, "继承" | ||
| 1173 | |||
| 1174 | -- 将打印: Shelf 被 Cupboard 继承 | ||
| 1175 | class Cupboard extends Shelf | ||
| 1176 | ``` | ||
| 1177 | |||
| 1178 | </YueDisplay> | ||
| 1179 | |||
| 1180 | ## super 关键字 | 572 | ## super 关键字 |
| 1181 | 573 | ||
| 1182 |   `super` 是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 | 574 |   `super` 是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 |
| @@ -1201,22 +593,6 @@ class MyClass extends ParentClass | |||
| 1201 | assert super == ParentClass | 593 | assert super == ParentClass |
| 1202 | ``` | 594 | ``` |
| 1203 | 595 | ||
| 1204 | <YueDisplay> | ||
| 1205 | |||
| 1206 | ```yue | ||
| 1207 | class MyClass extends ParentClass | ||
| 1208 | a_method: => | ||
| 1209 | -- 以下效果相同: | ||
| 1210 | super "你好", "世界" | ||
| 1211 | super\a_method "你好", "世界" | ||
| 1212 | super.a_method self, "你好", "世界" | ||
| 1213 | |||
| 1214 | -- super 作为值等于父类: | ||
| 1215 | assert super == ParentClass | ||
| 1216 | ``` | ||
| 1217 | |||
| 1218 | </YueDisplay> | ||
| 1219 | |||
| 1220 |   **super** 也可以用在函数存根的左侧。唯一的主要区别是,生成的函数不是绑定到 super 的值,而是绑定到 self。 | 596 |   **super** 也可以用在函数存根的左侧。唯一的主要区别是,生成的函数不是绑定到 super 的值,而是绑定到 self。 |
| 1221 | 597 | ||
| 1222 | ## 类型 | 598 | ## 类型 |
| @@ -1230,17 +606,6 @@ assert b.__class == BackPack | |||
| 1230 | print BackPack.size -- 打印 10 | 606 | print BackPack.size -- 打印 10 |
| 1231 | ``` | 607 | ``` |
| 1232 | 608 | ||
| 1233 | <YueDisplay> | ||
| 1234 | |||
| 1235 | ```yue | ||
| 1236 | b = BackPack! | ||
| 1237 | assert b.__class == BackPack | ||
| 1238 | |||
| 1239 | print BackPack.size -- 打印 10 | ||
| 1240 | ``` | ||
| 1241 | |||
| 1242 | </YueDisplay> | ||
| 1243 | |||
| 1244 | ## 类对象 | 609 | ## 类对象 |
| 1245 | 610 | ||
| 1246 |   在月之脚本中,当我们编写类的定义语句时,实际上是在创建一个类对象。这个类对象被保存在一个与该类同名的变量中。 | 611 |   在月之脚本中,当我们编写类的定义语句时,实际上是在创建一个类对象。这个类对象被保存在一个与该类同名的变量中。 |
| @@ -1259,14 +624,6 @@ print BackPack.size -- 打印 10 | |||
| 1259 | print BackPack.__name -- 打印 Backpack | 624 | print BackPack.__name -- 打印 Backpack |
| 1260 | ``` | 625 | ``` |
| 1261 | 626 | ||
| 1262 | <YueDisplay> | ||
| 1263 | |||
| 1264 | ```yue | ||
| 1265 | print BackPack.__name -- 打印 Backpack | ||
| 1266 | ``` | ||
| 1267 | |||
| 1268 | </YueDisplay> | ||
| 1269 | |||
| 1270 |   基础对象被保存在一个名为 `__base` 的特殊表中。我们可以编辑这个表,以便为那些已经创建出来的实例和还未创建的实例增加新的功能。 | 627 |   基础对象被保存在一个名为 `__base` 的特殊表中。我们可以编辑这个表,以便为那些已经创建出来的实例和还未创建的实例增加新的功能。 |
| 1271 | 628 | ||
| 1272 |   另外,如果一个类是从另一个类派生而来的,那么其父类对象则会被存储在名为 `__parent` 的地方。这种机制允许在类之间实现继承和功能扩展。 | 629 |   另外,如果一个类是从另一个类派生而来的,那么其父类对象则会被存储在名为 `__parent` 的地方。这种机制允许在类之间实现继承和功能扩展。 |
| @@ -1285,20 +642,6 @@ Things\some_func! | |||
| 1285 | assert Things().some_func == nil | 642 | assert Things().some_func == nil |
| 1286 | ``` | 643 | ``` |
| 1287 | 644 | ||
| 1288 | <YueDisplay> | ||
| 1289 | |||
| 1290 | ```yue | ||
| 1291 | class Things | ||
| 1292 | @some_func: => print "Hello from", @__name | ||
| 1293 | |||
| 1294 | Things\some_func! | ||
| 1295 | |||
| 1296 | -- 类变量在实例中不可见 | ||
| 1297 | assert Things().some_func == nil | ||
| 1298 | ``` | ||
| 1299 | |||
| 1300 | </YueDisplay> | ||
| 1301 | |||
| 1302 |   在表达式中,我们可以使用 @@ 来访问存储在 `self.__class` 中的值。因此,`@@hello` 是 `self.__class.hello` 的简写。 | 645 |   在表达式中,我们可以使用 @@ 来访问存储在 `self.__class` 中的值。因此,`@@hello` 是 `self.__class.hello` 的简写。 |
| 1303 | 646 | ||
| 1304 | ```yuescript | 647 | ```yuescript |
| @@ -1314,37 +657,12 @@ Counter! | |||
| 1314 | print Counter.count -- 输出 2 | 657 | print Counter.count -- 输出 2 |
| 1315 | ``` | 658 | ``` |
| 1316 | 659 | ||
| 1317 | <YueDisplay> | ||
| 1318 | |||
| 1319 | ```yue | ||
| 1320 | class Counter | ||
| 1321 | @count: 0 | ||
| 1322 | |||
| 1323 | new: => | ||
| 1324 | @@count += 1 | ||
| 1325 | |||
| 1326 | Counter! | ||
| 1327 | Counter! | ||
| 1328 | |||
| 1329 | print Counter.count -- 输出 2 | ||
| 1330 | ``` | ||
| 1331 | |||
| 1332 | </YueDisplay> | ||
| 1333 | |||
| 1334 |   @@ 的调用语义与 @ 类似。调用 @@ 时,会使用 Lua 的冒号语法将类作为第一个参数传入。 | 660 |   @@ 的调用语义与 @ 类似。调用 @@ 时,会使用 Lua 的冒号语法将类作为第一个参数传入。 |
| 1335 | 661 | ||
| 1336 | ```yuescript | 662 | ```yuescript |
| 1337 | @@hello 1,2,3,4 | 663 | @@hello 1,2,3,4 |
| 1338 | ``` | 664 | ``` |
| 1339 | 665 | ||
| 1340 | <YueDisplay> | ||
| 1341 | |||
| 1342 | ```yue | ||
| 1343 | @@hello 1,2,3,4 | ||
| 1344 | ``` | ||
| 1345 | |||
| 1346 | </YueDisplay> | ||
| 1347 | |||
| 1348 | ## 类声明语句 | 666 | ## 类声明语句 |
| 1349 | 667 | ||
| 1350 |   在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self 等于类对象,而不是实例对象。 | 668 |   在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self 等于类对象,而不是实例对象。 |
| @@ -1356,15 +674,6 @@ class Things | |||
| 1356 | @class_var = "hello world" | 674 | @class_var = "hello world" |
| 1357 | ``` | 675 | ``` |
| 1358 | 676 | ||
| 1359 | <YueDisplay> | ||
| 1360 | |||
| 1361 | ```yue | ||
| 1362 | class Things | ||
| 1363 | @class_var = "hello world" | ||
| 1364 | ``` | ||
| 1365 | |||
| 1366 | </YueDisplay> | ||
| 1367 | |||
| 1368 |   这些表达式会在所有属性被添加到类的基对象后执行。 | 677 |   这些表达式会在所有属性被添加到类的基对象后执行。 |
| 1369 | 678 | ||
| 1370 |   在类的主体中声明的所有变量都会限制作用域只在类声明的范围。这对于放置只有类方法可以访问的私有值或辅助函数很方便: | 679 |   在类的主体中声明的所有变量都会限制作用域只在类声明的范围。这对于放置只有类方法可以访问的私有值或辅助函数很方便: |
| @@ -1378,19 +687,6 @@ class MoreThings | |||
| 1378 | log "hello world: " .. secret | 687 | log "hello world: " .. secret |
| 1379 | ``` | 688 | ``` |
| 1380 | 689 | ||
| 1381 | <YueDisplay> | ||
| 1382 | |||
| 1383 | ```yue | ||
| 1384 | class MoreThings | ||
| 1385 | secret = 123 | ||
| 1386 | log = (msg) -> print "LOG:", msg | ||
| 1387 | |||
| 1388 | some_method: => | ||
| 1389 | log "hello world: " .. secret | ||
| 1390 | ``` | ||
| 1391 | |||
| 1392 | </YueDisplay> | ||
| 1393 | |||
| 1394 | ## @ 和 @@ 值 | 690 | ## @ 和 @@ 值 |
| 1395 | 691 | ||
| 1396 |   当 @ 和 @@ 前缀在一个名字前时,它们分别代表在 self 和 self.\_\_class 中访问的那个名字。 | 692 |   当 @ 和 @@ 前缀在一个名字前时,它们分别代表在 self 和 self.\_\_class 中访问的那个名字。 |
| @@ -1402,29 +698,12 @@ assert @ == self | |||
| 1402 | assert @@ == self.__class | 698 | assert @@ == self.__class |
| 1403 | ``` | 699 | ``` |
| 1404 | 700 | ||
| 1405 | <YueDisplay> | ||
| 1406 | |||
| 1407 | ```yue | ||
| 1408 | assert @ == self | ||
| 1409 | assert @@ == self.__class | ||
| 1410 | ``` | ||
| 1411 | |||
| 1412 | </YueDisplay> | ||
| 1413 | |||
| 1414 |   例如,使用 @@ 从实例方法快速创建同一类的新实例的方法: | 701 |   例如,使用 @@ 从实例方法快速创建同一类的新实例的方法: |
| 1415 | 702 | ||
| 1416 | ```yuescript | 703 | ```yuescript |
| 1417 | some_instance_method = (...) => @@ ... | 704 | some_instance_method = (...) => @@ ... |
| 1418 | ``` | 705 | ``` |
| 1419 | 706 | ||
| 1420 | <YueDisplay> | ||
| 1421 | |||
| 1422 | ```yue | ||
| 1423 | some_instance_method = (...) => @@ ... | ||
| 1424 | ``` | ||
| 1425 | |||
| 1426 | </YueDisplay> | ||
| 1427 | |||
| 1428 | ## 构造属性提升 | 707 | ## 构造属性提升 |
| 1429 | 708 | ||
| 1430 |   为了减少编写简单值对象定义的代码。你可以这样简单写一个类: | 709 |   为了减少编写简单值对象定义的代码。你可以这样简单写一个类: |
| @@ -1443,24 +722,6 @@ class Something | |||
| 1443 | @@baz = baz | 722 | @@baz = baz |
| 1444 | ``` | 723 | ``` |
| 1445 | 724 | ||
| 1446 | <YueDisplay> | ||
| 1447 | |||
| 1448 | ```yue | ||
| 1449 | class Something | ||
| 1450 | new: (@foo, @bar, @@biz, @@baz) => | ||
| 1451 | |||
| 1452 | -- 这是以下声明的简写形式 | ||
| 1453 | |||
| 1454 | class Something | ||
| 1455 | new: (foo, bar, biz, baz) => | ||
| 1456 | @foo = foo | ||
| 1457 | @bar = bar | ||
| 1458 | @@biz = biz | ||
| 1459 | @@baz = baz | ||
| 1460 | ``` | ||
| 1461 | |||
| 1462 | </YueDisplay> | ||
| 1463 | |||
| 1464 |   你也可以使用这种语法为一个函数初始化传入对象的字段。 | 725 |   你也可以使用这种语法为一个函数初始化传入对象的字段。 |
| 1465 | 726 | ||
| 1466 | ```yuescript | 727 | ```yuescript |
| @@ -1469,16 +730,6 @@ obj = new {}, 123, "abc" | |||
| 1469 | print obj | 730 | print obj |
| 1470 | ``` | 731 | ``` |
| 1471 | 732 | ||
| 1472 | <YueDisplay> | ||
| 1473 | |||
| 1474 | ```yue | ||
| 1475 | new = (@fieldA, @fieldB) => @ | ||
| 1476 | obj = new {}, 123, "abc" | ||
| 1477 | print obj | ||
| 1478 | ``` | ||
| 1479 | |||
| 1480 | </YueDisplay> | ||
| 1481 | |||
| 1482 | ## 类表达式 | 733 | ## 类表达式 |
| 1483 | 734 | ||
| 1484 |   类声明的语法也可以作为一个表达式使用,可以赋值给一个变量或者被返回语句返回。 | 735 |   类声明的语法也可以作为一个表达式使用,可以赋值给一个变量或者被返回语句返回。 |
| @@ -1489,16 +740,6 @@ x = class Bucket | |||
| 1489 | add_drop: => @drops += 1 | 740 | add_drop: => @drops += 1 |
| 1490 | ``` | 741 | ``` |
| 1491 | 742 | ||
| 1492 | <YueDisplay> | ||
| 1493 | |||
| 1494 | ```yue | ||
| 1495 | x = class Bucket | ||
| 1496 | drops: 0 | ||
| 1497 | add_drop: => @drops += 1 | ||
| 1498 | ``` | ||
| 1499 | |||
| 1500 | </YueDisplay> | ||
| 1501 | |||
| 1502 | ## 匿名类 | 743 | ## 匿名类 |
| 1503 | 744 | ||
| 1504 |   声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name 属性将为 nil。如果出现在赋值语句中,赋值操作左侧的名称将代替 nil。 | 745 |   声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name 属性将为 nil。如果出现在赋值语句中,赋值操作左侧的名称将代替 nil。 |
| @@ -1510,31 +751,12 @@ BigBucket = class extends Bucket | |||
| 1510 | assert Bucket.__name == "BigBucket" | 751 | assert Bucket.__name == "BigBucket" |
| 1511 | ``` | 752 | ``` |
| 1512 | 753 | ||
| 1513 | <YueDisplay> | ||
| 1514 | |||
| 1515 | ```yue | ||
| 1516 | BigBucket = class extends Bucket | ||
| 1517 | add_drop: => @drops += 10 | ||
| 1518 | |||
| 1519 | assert Bucket.__name == "BigBucket" | ||
| 1520 | ``` | ||
| 1521 | |||
| 1522 | </YueDisplay> | ||
| 1523 | |||
| 1524 |   你甚至可以省略掉主体,这意味着你可以这样写一个空白的匿名类: | 754 |   你甚至可以省略掉主体,这意味着你可以这样写一个空白的匿名类: |
| 1525 | 755 | ||
| 1526 | ```yuescript | 756 | ```yuescript |
| 1527 | x = class | 757 | x = class |
| 1528 | ``` | 758 | ``` |
| 1529 | 759 | ||
| 1530 | <YueDisplay> | ||
| 1531 | |||
| 1532 | ```yue | ||
| 1533 | x = class | ||
| 1534 | ``` | ||
| 1535 | |||
| 1536 | </YueDisplay> | ||
| 1537 | |||
| 1538 | ## 类混合 | 760 | ## 类混合 |
| 1539 | 761 | ||
| 1540 |   你可以通过使用 `using` 关键字来实现类混合。这意味着你可以从一个普通 Lua 表格或已定义的类对象中,复制函数到你创建的新类中。当你使用普通 Lua 表格进行类混合时,你有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当你从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 | 762 |   你可以通过使用 `using` 关键字来实现类混合。这意味着你可以从一个普通 Lua 表格或已定义的类对象中,复制函数到你创建的新类中。当你使用普通 Lua 表格进行类混合时,你有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当你从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 |
| @@ -1557,28 +779,6 @@ y\func! | |||
| 1557 | assert y.__class.__parent ~= X -- X 不是 Y 的父类 | 779 | assert y.__class.__parent ~= X -- X 不是 Y 的父类 |
| 1558 | ``` | 780 | ``` |
| 1559 | 781 | ||
| 1560 | <YueDisplay> | ||
| 1561 | |||
| 1562 | ```yue | ||
| 1563 | MyIndex = __index: var: 1 | ||
| 1564 | |||
| 1565 | class X using MyIndex | ||
| 1566 | func: => | ||
| 1567 | print 123 | ||
| 1568 | |||
| 1569 | x = X! | ||
| 1570 | print x.var | ||
| 1571 | |||
| 1572 | class Y using X | ||
| 1573 | |||
| 1574 | y = Y! | ||
| 1575 | y\func! | ||
| 1576 | |||
| 1577 | assert y.__class.__parent ~= X -- X 不是 Y 的父类 | ||
| 1578 | ``` | ||
| 1579 | |||
| 1580 | </YueDisplay> | ||
| 1581 | |||
| 1582 | # with 语句 | 782 | # with 语句 |
| 1583 | 783 | ||
| 1584 | 在编写 Lua 代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。 | 784 | 在编写 Lua 代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。 |
| @@ -1597,18 +797,6 @@ with Person! | |||
| 1597 | print .name | 797 | print .name |
| 1598 | ``` | 798 | ``` |
| 1599 | 799 | ||
| 1600 | <YueDisplay> | ||
| 1601 | |||
| 1602 | ```yue | ||
| 1603 | with Person! | ||
| 1604 | .name = "Oswald" | ||
| 1605 | \add_relative my_dad | ||
| 1606 | \save! | ||
| 1607 | print .name | ||
| 1608 | ``` | ||
| 1609 | |||
| 1610 | </YueDisplay> | ||
| 1611 | |||
| 1612 | with 语句也可以用作一个表达式,并返回它的代码块正在处理的对象。 | 800 | with 语句也可以用作一个表达式,并返回它的代码块正在处理的对象。 |
| 1613 | 801 | ||
| 1614 | ```yuescript | 802 | ```yuescript |
| @@ -1616,15 +804,6 @@ file = with File "favorite_foods.txt" | |||
| 1616 | \set_encoding "utf8" | 804 | \set_encoding "utf8" |
| 1617 | ``` | 805 | ``` |
| 1618 | 806 | ||
| 1619 | <YueDisplay> | ||
| 1620 | |||
| 1621 | ```yue | ||
| 1622 | file = with File "favorite_foods.txt" | ||
| 1623 | \set_encoding "utf8" | ||
| 1624 | ``` | ||
| 1625 | |||
| 1626 | </YueDisplay> | ||
| 1627 | |||
| 1628 | `with` 表达式支持 `break` 返回一个值: | 807 | `with` 表达式支持 `break` 返回一个值: |
| 1629 | 808 | ||
| 1630 | ```yuescript | 809 | ```yuescript |
| @@ -1632,15 +811,6 @@ result = with obj | |||
| 1632 | break .value | 811 | break .value |
| 1633 | ``` | 812 | ``` |
| 1634 | 813 | ||
| 1635 | <YueDisplay> | ||
| 1636 | |||
| 1637 | ```yue | ||
| 1638 | result = with obj | ||
| 1639 | break .value | ||
| 1640 | ``` | ||
| 1641 | |||
| 1642 | </YueDisplay> | ||
| 1643 | |||
| 1644 | 在 `with` 中使用 `break value` 后,`with` 表达式将不再返回其目标对象,而是返回 `break` 给出的值。 | 814 | 在 `with` 中使用 `break value` 后,`with` 表达式将不再返回其目标对象,而是返回 `break` 给出的值。 |
| 1645 | 815 | ||
| 1646 | ```yuescript | 816 | ```yuescript |
| @@ -1653,20 +823,6 @@ b = with obj | |||
| 1653 | -- b 是 .x,不是 obj | 823 | -- b 是 .x,不是 obj |
| 1654 | ``` | 824 | ``` |
| 1655 | 825 | ||
| 1656 | <YueDisplay> | ||
| 1657 | |||
| 1658 | ```yue | ||
| 1659 | a = with obj | ||
| 1660 | .x = 1 | ||
| 1661 | -- a 是 obj | ||
| 1662 | |||
| 1663 | b = with obj | ||
| 1664 | break .x | ||
| 1665 | -- b 是 .x,不是 obj | ||
| 1666 | ``` | ||
| 1667 | |||
| 1668 | </YueDisplay> | ||
| 1669 | |||
| 1670 | 与 `for` / `while` / `repeat` / `do` 不同,`with` 只支持一个 break 返回值。 | 826 | 与 `for` / `while` / `repeat` / `do` 不同,`with` 只支持一个 break 返回值。 |
| 1671 | 827 | ||
| 1672 | 或者… | 828 | 或者… |
| @@ -1680,19 +836,6 @@ create_person = (name, relatives) -> | |||
| 1680 | me = create_person "Leaf", [dad, mother, sister] | 836 | me = create_person "Leaf", [dad, mother, sister] |
| 1681 | ``` | 837 | ``` |
| 1682 | 838 | ||
| 1683 | <YueDisplay> | ||
| 1684 | |||
| 1685 | ```yue | ||
| 1686 | create_person = (name, relatives) -> | ||
| 1687 | with Person! | ||
| 1688 | .name = name | ||
| 1689 | \add_relative relative for relative in *relatives | ||
| 1690 | |||
| 1691 | me = create_person "Leaf", [dad, mother, sister] | ||
| 1692 | ``` | ||
| 1693 | |||
| 1694 | </YueDisplay> | ||
| 1695 | |||
| 1696 | 在此用法中,with 可以被视为K组合子(k-combinator)的一种特殊形式。 | 839 | 在此用法中,with 可以被视为K组合子(k-combinator)的一种特殊形式。 |
| 1697 | 840 | ||
| 1698 | 如果你想给表达式另外起一个名称的话,with 语句中的表达式也可以是一个赋值语句。 | 841 | 如果你想给表达式另外起一个名称的话,with 语句中的表达式也可以是一个赋值语句。 |
| @@ -1703,16 +846,6 @@ with str := "你好" | |||
| 1703 | print "大写:", \upper! | 846 | print "大写:", \upper! |
| 1704 | ``` | 847 | ``` |
| 1705 | 848 | ||
| 1706 | <YueDisplay> | ||
| 1707 | |||
| 1708 | ```yue | ||
| 1709 | with str := "你好" | ||
| 1710 | print "原始:", str | ||
| 1711 | print "大写:", \upper! | ||
| 1712 | ``` | ||
| 1713 | |||
| 1714 | </YueDisplay> | ||
| 1715 | |||
| 1716 | 你可以在 `with` 语句中使用 `[]` 访问特殊键。 | 849 | 你可以在 `with` 语句中使用 `[]` 访问特殊键。 |
| 1717 | 850 | ||
| 1718 | ```yuescript | 851 | ```yuescript |
| @@ -1725,20 +858,6 @@ with tb | |||
| 1725 | [] = "abc" -- 追加到 "tb" | 858 | [] = "abc" -- 追加到 "tb" |
| 1726 | ``` | 859 | ``` |
| 1727 | 860 | ||
| 1728 | <YueDisplay> | ||
| 1729 | |||
| 1730 | ```yue | ||
| 1731 | with tb | ||
| 1732 | [1] = 1 | ||
| 1733 | print [2] | ||
| 1734 | with [abc] | ||
| 1735 | [3] = [2]\func! | ||
| 1736 | ["key-name"] = value | ||
| 1737 | [] = "abc" -- 追加到 "tb" | ||
| 1738 | ``` | ||
| 1739 | |||
| 1740 | </YueDisplay> | ||
| 1741 | |||
| 1742 | `with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。 | 861 | `with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。 |
| 1743 | 862 | ||
| 1744 | ```yuescript | 863 | ```yuescript |
| @@ -1746,15 +865,6 @@ with? obj | |||
| 1746 | print obj.name | 865 | print obj.name |
| 1747 | ``` | 866 | ``` |
| 1748 | 867 | ||
| 1749 | <YueDisplay> | ||
| 1750 | |||
| 1751 | ```yue | ||
| 1752 | with? obj | ||
| 1753 | print obj.name | ||
| 1754 | ``` | ||
| 1755 | |||
| 1756 | </YueDisplay> | ||
| 1757 | |||
| 1758 | # 赋值 | 868 | # 赋值 |
| 1759 | 869 | ||
| 1760 |   月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过 **local** 和 **global** 声明来改变声明变量的作用范围。 | 870 |   月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过 **local** 和 **global** 声明来改变声明变量的作用范围。 |
| @@ -1765,16 +875,6 @@ a, b, c = 1, 2, 3 | |||
| 1765 | hello = 123 -- 访问现有的变量 | 875 | hello = 123 -- 访问现有的变量 |
| 1766 | ``` | 876 | ``` |
| 1767 | 877 | ||
| 1768 | <YueDisplay> | ||
| 1769 | |||
| 1770 | ```yue | ||
| 1771 | hello = "world" | ||
| 1772 | a, b, c = 1, 2, 3 | ||
| 1773 | hello = 123 -- 访问现有的变量 | ||
| 1774 | ``` | ||
| 1775 | |||
| 1776 | </YueDisplay> | ||
| 1777 | |||
| 1778 | ## 执行更新 | 878 | ## 执行更新 |
| 1779 | 879 | ||
| 1780 |   你可以使用各式二进制运算符执行更新赋值。 | 880 |   你可以使用各式二进制运算符执行更新赋值。 |
| @@ -1790,21 +890,6 @@ s ..= "world" -- 如果执行更新的局部变量不存在,将新建一个局 | |||
| 1790 | arg or= "默认值" | 890 | arg or= "默认值" |
| 1791 | ``` | 891 | ``` |
| 1792 | 892 | ||
| 1793 | <YueDisplay> | ||
| 1794 | |||
| 1795 | ```yue | ||
| 1796 | x = 1 | ||
| 1797 | x += 1 | ||
| 1798 | x -= 1 | ||
| 1799 | x *= 10 | ||
| 1800 | x /= 10 | ||
| 1801 | x %= 10 | ||
| 1802 | s ..= "world" -- 如果执行更新的局部变量不存在,将新建一个局部变量 | ||
| 1803 | arg or= "默认值" | ||
| 1804 | ``` | ||
| 1805 | |||
| 1806 | </YueDisplay> | ||
| 1807 | |||
| 1808 | ## 链式赋值 | 893 | ## 链式赋值 |
| 1809 | 894 | ||
| 1810 |   你可以进行链式赋值,将多个项目赋予相同的值。 | 895 |   你可以进行链式赋值,将多个项目赋予相同的值。 |
| @@ -1814,15 +899,6 @@ a = b = c = d = e = 0 | |||
| 1814 | x = y = z = f! | 899 | x = y = z = f! |
| 1815 | ``` | 900 | ``` |
| 1816 | 901 | ||
| 1817 | <YueDisplay> | ||
| 1818 | |||
| 1819 | ```yue | ||
| 1820 | a = b = c = d = e = 0 | ||
| 1821 | x = y = z = f! | ||
| 1822 | ``` | ||
| 1823 | |||
| 1824 | </YueDisplay> | ||
| 1825 | |||
| 1826 | ## 显式声明局部变量 | 902 | ## 显式声明局部变量 |
| 1827 | 903 | ||
| 1828 | ```yuescript | 904 | ```yuescript |
| @@ -1842,27 +918,6 @@ do | |||
| 1842 | B = 2 | 918 | B = 2 |
| 1843 | ``` | 919 | ``` |
| 1844 | 920 | ||
| 1845 | <YueDisplay> | ||
| 1846 | |||
| 1847 | ```yue | ||
| 1848 | do | ||
| 1849 | local a = 1 | ||
| 1850 | local * | ||
| 1851 | print "预先声明后续所有变量为局部变量" | ||
| 1852 | x = -> 1 + y + z | ||
| 1853 | y, z = 2, 3 | ||
| 1854 | global instance = Item\new! | ||
| 1855 | |||
| 1856 | do | ||
| 1857 | local X = 1 | ||
| 1858 | local ^ | ||
| 1859 | print "只预先声明后续大写的变量为局部变量" | ||
| 1860 | a = 1 | ||
| 1861 | B = 2 | ||
| 1862 | ``` | ||
| 1863 | |||
| 1864 | </YueDisplay> | ||
| 1865 | |||
| 1866 | ## 显式声明全局变量 | 921 | ## 显式声明全局变量 |
| 1867 | 922 | ||
| 1868 | ```yuescript | 923 | ```yuescript |
| @@ -1882,27 +937,6 @@ do | |||
| 1882 | local Temp = "一个局部值" | 937 | local Temp = "一个局部值" |
| 1883 | ``` | 938 | ``` |
| 1884 | 939 | ||
| 1885 | <YueDisplay> | ||
| 1886 | |||
| 1887 | ```yue | ||
| 1888 | do | ||
| 1889 | global a = 1 | ||
| 1890 | global * | ||
| 1891 | print "预先声明所有变量为全局变量" | ||
| 1892 | x = -> 1 + y + z | ||
| 1893 | y, z = 2, 3 | ||
| 1894 | |||
| 1895 | do | ||
| 1896 | global x = 1 | ||
| 1897 | global ^ | ||
| 1898 | print "只预先声明大写的变量为全局变量" | ||
| 1899 | a = 1 | ||
| 1900 | B = 2 | ||
| 1901 | local Temp = "一个局部值" | ||
| 1902 | ``` | ||
| 1903 | |||
| 1904 | </YueDisplay> | ||
| 1905 | |||
| 1906 | # 可变参数赋值 | 940 | # 可变参数赋值 |
| 1907 | 941 | ||
| 1908 |   你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用 Lua 的方式访问其内容。 | 942 |   你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用 Lua 的方式访问其内容。 |
| @@ -1916,19 +950,6 @@ first = select 1, ... | |||
| 1916 | print ok, count, first | 950 | print ok, count, first |
| 1917 | ``` | 951 | ``` |
| 1918 | 952 | ||
| 1919 | <YueDisplay> | ||
| 1920 | |||
| 1921 | ```yue | ||
| 1922 | list = [1, 2, 3, 4, 5] | ||
| 1923 | fn = (ok) -> ok, table.unpack list | ||
| 1924 | ok, ... = fn true | ||
| 1925 | count = select '#', ... | ||
| 1926 | first = select 1, ... | ||
| 1927 | print ok, count, first | ||
| 1928 | ``` | ||
| 1929 | |||
| 1930 | </YueDisplay> | ||
| 1931 | |||
| 1932 | # If 赋值 | 953 | # If 赋值 |
| 1933 | 954 | ||
| 1934 |   `if` 和 `elseif` 代码块可以在条件表达式的位置进行赋值。在代码执行到要计算条件时,会首先进行赋值计算,并使用赋与的值作为分支判断的条件。赋值的变量仅在条件分支的代码块内有效,这意味着如果值不是真值,那么它就不会被用到。注意,你必须使用“海象运算符” `:=` 而不是 `=` 来做赋值。 | 955 |   `if` 和 `elseif` 代码块可以在条件表达式的位置进行赋值。在代码执行到要计算条件时,会首先进行赋值计算,并使用赋与的值作为分支判断的条件。赋值的变量仅在条件分支的代码块内有效,这意味着如果值不是真值,那么它就不会被用到。注意,你必须使用“海象运算符” `:=` 而不是 `=` 来做赋值。 |
| @@ -1938,15 +959,6 @@ if user := database.find_user "moon" | |||
| 1938 | print user.name | 959 | print user.name |
| 1939 | ``` | 960 | ``` |
| 1940 | 961 | ||
| 1941 | <YueDisplay> | ||
| 1942 | |||
| 1943 | ```yue | ||
| 1944 | if user := database.find_user "moon" | ||
| 1945 | print user.name | ||
| 1946 | ``` | ||
| 1947 | |||
| 1948 | </YueDisplay> | ||
| 1949 | |||
| 1950 | ```yuescript | 962 | ```yuescript |
| 1951 | if hello := os.getenv "hello" | 963 | if hello := os.getenv "hello" |
| 1952 | print "你有 hello", hello | 964 | print "你有 hello", hello |
| @@ -1956,19 +968,6 @@ else | |||
| 1956 | print "什么都没有 :(" | 968 | print "什么都没有 :(" |
| 1957 | ``` | 969 | ``` |
| 1958 | 970 | ||
| 1959 | <YueDisplay> | ||
| 1960 | |||
| 1961 | ```yue | ||
| 1962 | if hello := os.getenv "hello" | ||
| 1963 | print "你有 hello", hello | ||
| 1964 | elseif world := os.getenv "world" | ||
| 1965 | print "你有 world", world | ||
| 1966 | else | ||
| 1967 | print "什么都没有 :(" | ||
| 1968 | ``` | ||
| 1969 | |||
| 1970 | </YueDisplay> | ||
| 1971 | |||
| 1972 |   使用多个返回值的 If 赋值。只有第一个值会被检查,其他值都有同样的作用域。 | 971 |   使用多个返回值的 If 赋值。只有第一个值会被检查,其他值都有同样的作用域。 |
| 1973 | 972 | ||
| 1974 | ```yuescript | 973 | ```yuescript |
| @@ -1977,16 +976,6 @@ if success, result := pcall -> "无报错地获取结果" | |||
| 1977 | print "好的" | 976 | print "好的" |
| 1978 | ``` | 977 | ``` |
| 1979 | 978 | ||
| 1980 | <YueDisplay> | ||
| 1981 | |||
| 1982 | ```yue | ||
| 1983 | if success, result := pcall -> "无报错地获取结果" | ||
| 1984 | print result -- 变量 result 是有作用域的 | ||
| 1985 | print "好的" | ||
| 1986 | ``` | ||
| 1987 | |||
| 1988 | </YueDisplay> | ||
| 1989 | |||
| 1990 | ## While 赋值 | 979 | ## While 赋值 |
| 1991 | 980 | ||
| 1992 |   你可以在 while 循环中同样使用赋值来获取循环条件的值。 | 981 |   你可以在 while 循环中同样使用赋值来获取循环条件的值。 |
| @@ -1997,16 +986,6 @@ while byte := stream\read_one! | |||
| 1997 | print byte | 986 | print byte |
| 1998 | ``` | 987 | ``` |
| 1999 | 988 | ||
| 2000 | <YueDisplay> | ||
| 2001 | |||
| 2002 | ```yue | ||
| 2003 | while byte := stream\read_one! | ||
| 2004 | -- 对 byte 做一些操作 | ||
| 2005 | print byte | ||
| 2006 | ``` | ||
| 2007 | |||
| 2008 | </YueDisplay> | ||
| 2009 | |||
| 2010 | # 解构赋值 | 989 | # 解构赋值 |
| 2011 | 990 | ||
| 2012 |   解构赋值是一种快速从 Lua 表中按名称或基于数组中的位置提取值的方法。 | 991 |   解构赋值是一种快速从 Lua 表中按名称或基于数组中的位置提取值的方法。 |
| @@ -2022,17 +1001,6 @@ thing = [1, 2] | |||
| 2022 | print a, b | 1001 | print a, b |
| 2023 | ``` | 1002 | ``` |
| 2024 | 1003 | ||
| 2025 | <YueDisplay> | ||
| 2026 | |||
| 2027 | ```yue | ||
| 2028 | thing = [1, 2] | ||
| 2029 | |||
| 2030 | [a, b] = thing | ||
| 2031 | print a, b | ||
| 2032 | ``` | ||
| 2033 | |||
| 2034 | </YueDisplay> | ||
| 2035 | |||
| 2036 |   在解构表格字面量中,键代表从右侧读取的键,值代表读取的值将被赋予的名称。 | 1004 |   在解构表格字面量中,键代表从右侧读取的键,值代表读取的值将被赋予的名称。 |
| 2037 | 1005 | ||
| 2038 | ```yuescript | 1006 | ```yuescript |
| @@ -2048,23 +1016,6 @@ print hello, the_day | |||
| 2048 | :day = obj -- 可以不带大括号进行简单的解构 | 1016 | :day = obj -- 可以不带大括号进行简单的解构 |
| 2049 | ``` | 1017 | ``` |
| 2050 | 1018 | ||
| 2051 | <YueDisplay> | ||
| 2052 | |||
| 2053 | ```yue | ||
| 2054 | obj = { | ||
| 2055 | hello: "world" | ||
| 2056 | day: "tuesday" | ||
| 2057 | length: 20 | ||
| 2058 | } | ||
| 2059 | |||
| 2060 | {hello: hello, day: the_day} = obj | ||
| 2061 | print hello, the_day | ||
| 2062 | |||
| 2063 | :day = obj -- 可以不带大括号进行简单的解构 | ||
| 2064 | ``` | ||
| 2065 | |||
| 2066 | </YueDisplay> | ||
| 2067 | |||
| 2068 |   这也适用于嵌套的数据结构: | 1019 |   这也适用于嵌套的数据结构: |
| 2069 | 1020 | ||
| 2070 | ```yuescript | 1021 | ```yuescript |
| @@ -2080,23 +1031,6 @@ obj2 = { | |||
| 2080 | print first, second, color | 1031 | print first, second, color |
| 2081 | ``` | 1032 | ``` |
| 2082 | 1033 | ||
| 2083 | <YueDisplay> | ||
| 2084 | |||
| 2085 | ```yue | ||
| 2086 | obj2 = { | ||
| 2087 | numbers: [1,2,3,4] | ||
| 2088 | properties: { | ||
| 2089 | color: "green" | ||
| 2090 | height: 13.5 | ||
| 2091 | } | ||
| 2092 | } | ||
| 2093 | |||
| 2094 | {numbers: [first, second], properties: {color: color}} = obj2 | ||
| 2095 | print first, second, color | ||
| 2096 | ``` | ||
| 2097 | |||
| 2098 | </YueDisplay> | ||
| 2099 | |||
| 2100 |   如果解构语句很复杂,也可以任意将其分散在几行中。稍微复杂一些的示例: | 1034 |   如果解构语句很复杂,也可以任意将其分散在几行中。稍微复杂一些的示例: |
| 2101 | 1035 | ||
| 2102 | ```yuescript | 1036 | ```yuescript |
| @@ -2108,75 +1042,30 @@ print first, second, color | |||
| 2108 | } = obj2 | 1042 | } = obj2 |
| 2109 | ``` | 1043 | ``` |
| 2110 | 1044 | ||
| 2111 | <YueDisplay> | ||
| 2112 | |||
| 2113 | ```yue | ||
| 2114 | { | ||
| 2115 | numbers: [first, second] | ||
| 2116 | properties: { | ||
| 2117 | color: color | ||
| 2118 | } | ||
| 2119 | } = obj2 | ||
| 2120 | ``` | ||
| 2121 | |||
| 2122 | </YueDisplay> | ||
| 2123 | |||
| 2124 |   有时候我们会需要从 Lua 表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: | 1045 |   有时候我们会需要从 Lua 表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: |
| 2125 | 1046 | ||
| 2126 | ```yuescript | 1047 | ```yuescript |
| 2127 | {:concat, :insert} = table | 1048 | {:concat, :insert} = table |
| 2128 | ``` | 1049 | ``` |
| 2129 | 1050 | ||
| 2130 | <YueDisplay> | ||
| 2131 | |||
| 2132 | ```yue | ||
| 2133 | {:concat, :insert} = table | ||
| 2134 | ``` | ||
| 2135 | |||
| 2136 | </YueDisplay> | ||
| 2137 | |||
| 2138 |   这样的用法与导入语法有些相似。但我们可以通过混合语法重命名我们想要提取的字段: | 1051 |   这样的用法与导入语法有些相似。但我们可以通过混合语法重命名我们想要提取的字段: |
| 2139 | 1052 | ||
| 2140 | ```yuescript | 1053 | ```yuescript |
| 2141 | {:mix, :max, random: rand} = math | 1054 | {:mix, :max, random: rand} = math |
| 2142 | ``` | 1055 | ``` |
| 2143 | 1056 | ||
| 2144 | <YueDisplay> | ||
| 2145 | |||
| 2146 | ```yue | ||
| 2147 | {:mix, :max, random: rand} = math | ||
| 2148 | ``` | ||
| 2149 | |||
| 2150 | </YueDisplay> | ||
| 2151 | |||
| 2152 |   在进行解构时,你可以指定默认值,如: | 1057 |   在进行解构时,你可以指定默认值,如: |
| 2153 | 1058 | ||
| 2154 | ```yuescript | 1059 | ```yuescript |
| 2155 | {:name = "nameless", :job = "jobless"} = person | 1060 | {:name = "nameless", :job = "jobless"} = person |
| 2156 | ``` | 1061 | ``` |
| 2157 | 1062 | ||
| 2158 | <YueDisplay> | ||
| 2159 | |||
| 2160 | ```yue | ||
| 2161 | {:name = "nameless", :job = "jobless"} = person | ||
| 2162 | ``` | ||
| 2163 | |||
| 2164 | </YueDisplay> | ||
| 2165 | |||
| 2166 |   在进行列表解构时,你可以使用`_`作为占位符: | 1063 |   在进行列表解构时,你可以使用`_`作为占位符: |
| 2167 | 1064 | ||
| 2168 | ```yuescript | 1065 | ```yuescript |
| 2169 | [_, two, _, four] = items | 1066 | [_, two, _, four] = items |
| 2170 | ``` | 1067 | ``` |
| 2171 | 1068 | ||
| 2172 | <YueDisplay> | ||
| 2173 | |||
| 2174 | ```yue | ||
| 2175 | [_, two, _, four] = items | ||
| 2176 | ``` | ||
| 2177 | |||
| 2178 | </YueDisplay> | ||
| 2179 | |||
| 2180 | ## 范围解构 | 1069 | ## 范围解构 |
| 2181 | 1070 | ||
| 2182 |   你可以使用展开运算符 `...` 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。 | 1071 |   你可以使用展开运算符 `...` 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。 |
| @@ -2189,18 +1078,6 @@ print bulk -- 打印: {"second", "third", "fourth"} | |||
| 2189 | print last -- 打印: last | 1078 | print last -- 打印: last |
| 2190 | ``` | 1079 | ``` |
| 2191 | 1080 | ||
| 2192 | <YueDisplay> | ||
| 2193 | |||
| 2194 | ```yue | ||
| 2195 | orders = ["first", "second", "third", "fourth", "last"] | ||
| 2196 | [first, ...bulk, last] = orders | ||
| 2197 | print first -- 打印: first | ||
| 2198 | print bulk -- 打印: {"second", "third", "fourth"} | ||
| 2199 | print last -- 打印: last | ||
| 2200 | ``` | ||
| 2201 | |||
| 2202 | </YueDisplay> | ||
| 2203 | |||
| 2204 |   展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 `_` 作为占位符来表示你想跳过对应范围的捕获: | 1081 |   展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 `_` 作为占位符来表示你想跳过对应范围的捕获: |
| 2205 | 1082 | ||
| 2206 | ```yuescript | 1083 | ```yuescript |
| @@ -2214,21 +1091,6 @@ print last -- 打印: last | |||
| 2214 | [first, ..._, last] = orders | 1091 | [first, ..._, last] = orders |
| 2215 | ``` | 1092 | ``` |
| 2216 | 1093 | ||
| 2217 | <YueDisplay> | ||
| 2218 | |||
| 2219 | ```yue | ||
| 2220 | -- 捕获第一个元素之后的所有元素 | ||
| 2221 | [first, ...rest] = orders | ||
| 2222 | |||
| 2223 | -- 捕获最后一个元素之前的所有元素 | ||
| 2224 | [...start, last] = orders | ||
| 2225 | |||
| 2226 | -- 跳过中间的元素,只捕获第一个和最后一个元素 | ||
| 2227 | [first, ..._, last] = orders | ||
| 2228 | ``` | ||
| 2229 | |||
| 2230 | </YueDisplay> | ||
| 2231 | |||
| 2232 | ## 在其它地方的解构赋值 | 1094 | ## 在其它地方的解构赋值 |
| 2233 | 1095 | ||
| 2234 |   解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在 for 循环中: | 1096 |   解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在 for 循环中: |
| @@ -2243,20 +1105,6 @@ for [left, right] in *tuples | |||
| 2243 | print left, right | 1105 | print left, right |
| 2244 | ``` | 1106 | ``` |
| 2245 | 1107 | ||
| 2246 | <YueDisplay> | ||
| 2247 | |||
| 2248 | ```yue | ||
| 2249 | tuples = [ | ||
| 2250 | ["hello", "world"] | ||
| 2251 | ["egg", "head"] | ||
| 2252 | ] | ||
| 2253 | |||
| 2254 | for [left, right] in *tuples | ||
| 2255 | print left, right | ||
| 2256 | ``` | ||
| 2257 | |||
| 2258 | </YueDisplay> | ||
| 2259 | |||
| 2260 |   我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在 for 语句的名称子句中使用解构来解包它。 | 1108 |   我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在 for 语句的名称子句中使用解构来解包它。 |
| 2261 | 1109 | ||
| 2262 | # 使用 using 语句:防止破坏性赋值 | 1110 | # 使用 using 语句:防止破坏性赋值 |
| @@ -2279,26 +1127,6 @@ my_func! | |||
| 2279 | print i -- 将打印 0 | 1127 | print i -- 将打印 0 |
| 2280 | ``` | 1128 | ``` |
| 2281 | 1129 | ||
| 2282 | <YueDisplay> | ||
| 2283 | |||
| 2284 | ```yue | ||
| 2285 | i = 100 | ||
| 2286 | |||
| 2287 | -- 许多代码行... | ||
| 2288 | |||
| 2289 | my_func = -> | ||
| 2290 | i = 10 | ||
| 2291 | while i > 0 | ||
| 2292 | print i | ||
| 2293 | i -= 1 | ||
| 2294 | |||
| 2295 | my_func! | ||
| 2296 | |||
| 2297 | print i -- 将打印 0 | ||
| 2298 | ``` | ||
| 2299 | |||
| 2300 | </YueDisplay> | ||
| 2301 | |||
| 2302 |   在 `my_func` 中,我们不小心覆盖了变量 `i` 的值。虽然在这个例子中这个问题很明显,但在一个庞大的或者是由多人共同维护的代码库中,很难追踪每个变量的声明情况。 | 1130 |   在 `my_func` 中,我们不小心覆盖了变量 `i` 的值。虽然在这个例子中这个问题很明显,但在一个庞大的或者是由多人共同维护的代码库中,很难追踪每个变量的声明情况。 |
| 2303 | 1131 | ||
| 2304 |   如果我们可以明确指出哪些变量是我们想在当前作用域内修改的,并且防止我们不小心更改了其他作用域中同名的变量,那将大有裨益。 | 1132 |   如果我们可以明确指出哪些变量是我们想在当前作用域内修改的,并且防止我们不小心更改了其他作用域中同名的变量,那将大有裨益。 |
| @@ -2315,20 +1143,6 @@ my_func! | |||
| 2315 | print i -- 打印 100,i 没有受到影响 | 1143 | print i -- 打印 100,i 没有受到影响 |
| 2316 | ``` | 1144 | ``` |
| 2317 | 1145 | ||
| 2318 | <YueDisplay> | ||
| 2319 | |||
| 2320 | ```yue | ||
| 2321 | i = 100 | ||
| 2322 | |||
| 2323 | my_func = (using nil) -> | ||
| 2324 | i = "hello" -- 这里创建了一个新的局部变量 | ||
| 2325 | |||
| 2326 | my_func! | ||
| 2327 | print i -- 打印 100,i 没有受到影响 | ||
| 2328 | ``` | ||
| 2329 | |||
| 2330 | </YueDisplay> | ||
| 2331 | |||
| 2332 |   using子句中可以填写多个用逗号分隔名称。指定可以访问和修改的外部变量的名称: | 1146 |   using子句中可以填写多个用逗号分隔名称。指定可以访问和修改的外部变量的名称: |
| 2333 | 1147 | ||
| 2334 | ```yuescript | 1148 | ```yuescript |
| @@ -2344,23 +1158,6 @@ my_func(22) | |||
| 2344 | print i, k -- 这些已经被更新 | 1158 | print i, k -- 这些已经被更新 |
| 2345 | ``` | 1159 | ``` |
| 2346 | 1160 | ||
| 2347 | <YueDisplay> | ||
| 2348 | |||
| 2349 | ```yue | ||
| 2350 | tmp = 1213 | ||
| 2351 | i, k = 100, 50 | ||
| 2352 | |||
| 2353 | my_func = (add using k, i) -> | ||
| 2354 | tmp = tmp + add -- 创建了一个新的局部tmp | ||
| 2355 | i += tmp | ||
| 2356 | k += tmp | ||
| 2357 | |||
| 2358 | my_func(22) | ||
| 2359 | print i, k -- 这些已经被更新 | ||
| 2360 | ``` | ||
| 2361 | |||
| 2362 | </YueDisplay> | ||
| 2363 | |||
| 2364 | # 使用方法 | 1161 | # 使用方法 |
| 2365 | 1162 | ||
| 2366 | ## Lua 模块 | 1163 | ## Lua 模块 |
| @@ -2527,55 +1324,6 @@ with apple | |||
| 2527 | export 🌛 = "月之脚本" | 1324 | export 🌛 = "月之脚本" |
| 2528 | ``` | 1325 | ``` |
| 2529 | 1326 | ||
| 2530 | <YueDisplay> | ||
| 2531 | |||
| 2532 | ```yue | ||
| 2533 | -- 导入语法 | ||
| 2534 | import p, to_lua from "yue" | ||
| 2535 | |||
| 2536 | -- 隐式对象 | ||
| 2537 | inventory = | ||
| 2538 | equipment: | ||
| 2539 | - "sword" | ||
| 2540 | - "shield" | ||
| 2541 | items: | ||
| 2542 | - name: "potion" | ||
| 2543 | count: 10 | ||
| 2544 | - name: "bread" | ||
| 2545 | count: 3 | ||
| 2546 | |||
| 2547 | -- 列表推导 | ||
| 2548 | map = (arr, action) -> | ||
| 2549 | [action item for item in *arr] | ||
| 2550 | |||
| 2551 | filter = (arr, cond) -> | ||
| 2552 | [item for item in *arr when cond item] | ||
| 2553 | |||
| 2554 | reduce = (arr, init, action): init -> | ||
| 2555 | init = action init, item for item in *arr | ||
| 2556 | |||
| 2557 | -- 管道操作符 | ||
| 2558 | [1, 2, 3] | ||
| 2559 | |> map (x) -> x * 2 | ||
| 2560 | |> filter (x) -> x > 4 | ||
| 2561 | |> reduce 0, (a, b) -> a + b | ||
| 2562 | |||
| 2563 | |||
| 2564 | -- 元表操作 | ||
| 2565 | apple = | ||
| 2566 | size: 15 | ||
| 2567 | <index>: | ||
| 2568 | color: 0x00ffff | ||
| 2569 | |||
| 2570 | with apple | ||
| 2571 | p .size, .color, .<index> if .<>? | ||
| 2572 | |||
| 2573 | -- 类似js的导出语法 | ||
| 2574 | export 🌛 = "月之脚本" | ||
| 2575 | ``` | ||
| 2576 | |||
| 2577 | </YueDisplay> | ||
| 2578 | |||
| 2579 | ## 关于 Dora SSR | 1327 | ## 关于 Dora SSR |
| 2580 | 1328 | ||
| 2581 | 月之脚本是与开源游戏引擎 [Dora SSR](https://github.com/Dora-SSR/Dora-SSR) 一起开发和维护的。它已被用于创建引擎工具、游戏原型和演示,在实际的游戏项目中验证其能力,同时它也帮助增强了 Dora SSR 游戏引擎的开发体验。 | 1329 | 月之脚本是与开源游戏引擎 [Dora SSR](https://github.com/Dora-SSR/Dora-SSR) 一起开发和维护的。它已被用于创建引擎工具、游戏原型和演示,在实际的游戏项目中验证其能力,同时它也帮助增强了 Dora SSR 游戏引擎的开发体验。 |
| @@ -2634,18 +1382,6 @@ else | |||
| 2634 | print "没有硬币" | 1382 | print "没有硬币" |
| 2635 | ``` | 1383 | ``` |
| 2636 | 1384 | ||
| 2637 | <YueDisplay> | ||
| 2638 | |||
| 2639 | ```yue | ||
| 2640 | have_coins = false | ||
| 2641 | if have_coins | ||
| 2642 | print "有硬币" | ||
| 2643 | else | ||
| 2644 | print "没有硬币" | ||
| 2645 | ``` | ||
| 2646 | |||
| 2647 | </YueDisplay> | ||
| 2648 | |||
| 2649 |   对于简单的语句,也可以使用简短的语法: | 1385 |   对于简单的语句,也可以使用简短的语法: |
| 2650 | 1386 | ||
| 2651 | ```yuescript | 1387 | ```yuescript |
| @@ -2653,15 +1389,6 @@ have_coins = false | |||
| 2653 | if have_coins then print "有硬币" else print "没有硬币" | 1389 | if have_coins then print "有硬币" else print "没有硬币" |
| 2654 | ``` | 1390 | ``` |
| 2655 | 1391 | ||
| 2656 | <YueDisplay> | ||
| 2657 | |||
| 2658 | ```yue | ||
| 2659 | have_coins = false | ||
| 2660 | if have_coins then print "有硬币" else print "没有硬币" | ||
| 2661 | ``` | ||
| 2662 | |||
| 2663 | </YueDisplay> | ||
| 2664 | |||
| 2665 |   因为 if 语句可以用作表达式,所以也可以这样写: | 1392 |   因为 if 语句可以用作表达式,所以也可以这样写: |
| 2666 | 1393 | ||
| 2667 | ```yuescript | 1394 | ```yuescript |
| @@ -2669,15 +1396,6 @@ have_coins = false | |||
| 2669 | print if have_coins then "有硬币" else "没有硬币" | 1396 | print if have_coins then "有硬币" else "没有硬币" |
| 2670 | ``` | 1397 | ``` |
| 2671 | 1398 | ||
| 2672 | <YueDisplay> | ||
| 2673 | |||
| 2674 | ```yue | ||
| 2675 | have_coins = false | ||
| 2676 | print if have_coins then "有硬币" else "没有硬币" | ||
| 2677 | ``` | ||
| 2678 | |||
| 2679 | </YueDisplay> | ||
| 2680 | |||
| 2681 |   条件语句也可以作为表达式用在返回语句和赋值语句中: | 1399 |   条件语句也可以作为表达式用在返回语句和赋值语句中: |
| 2682 | 1400 | ||
| 2683 | ```yuescript | 1401 | ```yuescript |
| @@ -2695,25 +1413,6 @@ else | |||
| 2695 | print message -- 打印: 我很高 | 1413 | print message -- 打印: 我很高 |
| 2696 | ``` | 1414 | ``` |
| 2697 | 1415 | ||
| 2698 | <YueDisplay> | ||
| 2699 | |||
| 2700 | ```yue | ||
| 2701 | is_tall = (name) -> | ||
| 2702 | if name == "Rob" | ||
| 2703 | true | ||
| 2704 | else | ||
| 2705 | false | ||
| 2706 | |||
| 2707 | message = if is_tall "Rob" | ||
| 2708 | "我很高" | ||
| 2709 | else | ||
| 2710 | "我不是很高" | ||
| 2711 | |||
| 2712 | print message -- 打印: 我很高 | ||
| 2713 | ``` | ||
| 2714 | |||
| 2715 | </YueDisplay> | ||
| 2716 | |||
| 2717 |   if 的反义词是 unless(相当于 if not,正如“如果”对应“除非”): | 1416 |   if 的反义词是 unless(相当于 if not,正如“如果”对应“除非”): |
| 2718 | 1417 | ||
| 2719 | ```yuescript | 1418 | ```yuescript |
| @@ -2721,27 +1420,10 @@ unless os.date("%A") == "Monday" | |||
| 2721 | print "今天不是星期一!" | 1420 | print "今天不是星期一!" |
| 2722 | ``` | 1421 | ``` |
| 2723 | 1422 | ||
| 2724 | <YueDisplay> | ||
| 2725 | |||
| 2726 | ```yue | ||
| 2727 | unless os.date("%A") == "Monday" | ||
| 2728 | print "今天不是星期一!" | ||
| 2729 | ``` | ||
| 2730 | |||
| 2731 | </YueDisplay> | ||
| 2732 | |||
| 2733 | ```yuescript | 1423 | ```yuescript |
| 2734 | print "你真幸运!" unless math.random! > 0.1 | 1424 | print "你真幸运!" unless math.random! > 0.1 |
| 2735 | ``` | 1425 | ``` |
| 2736 | 1426 | ||
| 2737 | <YueDisplay> | ||
| 2738 | |||
| 2739 | ```yue | ||
| 2740 | print "你真幸运!" unless math.random! > 0.1 | ||
| 2741 | ``` | ||
| 2742 | |||
| 2743 | </YueDisplay> | ||
| 2744 | |||
| 2745 | ## 范围表达式 | 1427 | ## 范围表达式 |
| 2746 | 1428 | ||
| 2747 |   你可以使用范围表达式来编写进行范围检查的代码。 | 1429 |   你可以使用范围表达式来编写进行范围检查的代码。 |
| @@ -2756,20 +1438,6 @@ if a in list | |||
| 2756 | print "检查`a`是否在列表中" | 1438 | print "检查`a`是否在列表中" |
| 2757 | ``` | 1439 | ``` |
| 2758 | 1440 | ||
| 2759 | <YueDisplay> | ||
| 2760 | |||
| 2761 | ```yue | ||
| 2762 | a = 5 | ||
| 2763 | |||
| 2764 | if a in [1, 3, 5, 7] | ||
| 2765 | print "检查离散值的相等性" | ||
| 2766 | |||
| 2767 | if a in list | ||
| 2768 | print "检查`a`是否在列表中" | ||
| 2769 | ``` | ||
| 2770 | |||
| 2771 | </YueDisplay> | ||
| 2772 | |||
| 2773 | `in` 运算符也可以用于表,并支持 `not in` 变体来进行否定检查: | 1441 | `in` 运算符也可以用于表,并支持 `not in` 变体来进行否定检查: |
| 2774 | 1442 | ||
| 2775 | ```yuescript | 1443 | ```yuescript |
| @@ -2783,21 +1451,6 @@ not_exist = item not in list | |||
| 2783 | check = -> value not in table | 1451 | check = -> value not in table |
| 2784 | ``` | 1452 | ``` |
| 2785 | 1453 | ||
| 2786 | <YueDisplay> | ||
| 2787 | |||
| 2788 | ```yue | ||
| 2789 | has = "foo" in {"bar", "foo"} | ||
| 2790 | |||
| 2791 | if a in {1, 2, 3} | ||
| 2792 | print "a 在表中" | ||
| 2793 | |||
| 2794 | not_exist = item not in list | ||
| 2795 | |||
| 2796 | check = -> value not in table | ||
| 2797 | ``` | ||
| 2798 | |||
| 2799 | </YueDisplay> | ||
| 2800 | |||
| 2801 | 单元素列表或表会检查与该元素的相等性: | 1454 | 单元素列表或表会检查与该元素的相等性: |
| 2802 | 1455 | ||
| 2803 | ```yuescript | 1456 | ```yuescript |
| @@ -2812,22 +1465,6 @@ with tb | |||
| 2812 | c = a in [1] | 1465 | c = a in [1] |
| 2813 | ``` | 1466 | ``` |
| 2814 | 1467 | ||
| 2815 | <YueDisplay> | ||
| 2816 | |||
| 2817 | ```yue | ||
| 2818 | -- [1,] 检查 value == 1 | ||
| 2819 | c = a in [1,] | ||
| 2820 | |||
| 2821 | -- {1} 也是检查 value == 1 | ||
| 2822 | c = a in {1} | ||
| 2823 | |||
| 2824 | -- 没有逗号,[1] 是索引访问(tb[1]) | ||
| 2825 | with tb | ||
| 2826 | c = a in [1] | ||
| 2827 | ``` | ||
| 2828 | |||
| 2829 | </YueDisplay> | ||
| 2830 | |||
| 2831 | # for 循环 | 1468 | # for 循环 |
| 2832 | 1469 | ||
| 2833 |   Lua 中有两种 for 循环形式,数字型和通用型: | 1470 |   Lua 中有两种 for 循环形式,数字型和通用型: |
| @@ -2843,21 +1480,6 @@ for key, value in pairs object | |||
| 2843 | print key, value | 1480 | print key, value |
| 2844 | ``` | 1481 | ``` |
| 2845 | 1482 | ||
| 2846 | <YueDisplay> | ||
| 2847 | |||
| 2848 | ```yue | ||
| 2849 | for i = 10, 20 | ||
| 2850 | print i | ||
| 2851 | |||
| 2852 | for k = 1, 15, 2 -- 提供了一个遍历的步长 | ||
| 2853 | print k | ||
| 2854 | |||
| 2855 | for key, value in pairs object | ||
| 2856 | print key, value | ||
| 2857 | ``` | ||
| 2858 | |||
| 2859 | </YueDisplay> | ||
| 2860 | |||
| 2861 |   可以使用切片和 **\*** 操作符,就像在列表推导中一样: | 1483 |   可以使用切片和 **\*** 操作符,就像在列表推导中一样: |
| 2862 | 1484 | ||
| 2863 | ```yuescript | 1485 | ```yuescript |
| @@ -2865,15 +1487,6 @@ for item in *items[2, 4] | |||
| 2865 | print item | 1487 | print item |
| 2866 | ``` | 1488 | ``` |
| 2867 | 1489 | ||
| 2868 | <YueDisplay> | ||
| 2869 | |||
| 2870 | ```yue | ||
| 2871 | for item in *items[2, 4] | ||
| 2872 | print item | ||
| 2873 | ``` | ||
| 2874 | |||
| 2875 | </YueDisplay> | ||
| 2876 | |||
| 2877 |   当代码语句只有一行时,循环语句也都可以写作更短的语法: | 1490 |   当代码语句只有一行时,循环语句也都可以写作更短的语法: |
| 2878 | 1491 | ||
| 2879 | ```yuescript | 1492 | ```yuescript |
| @@ -2882,16 +1495,6 @@ for item in *items do print item | |||
| 2882 | for j = 1, 10, 3 do print j | 1495 | for j = 1, 10, 3 do print j |
| 2883 | ``` | 1496 | ``` |
| 2884 | 1497 | ||
| 2885 | <YueDisplay> | ||
| 2886 | |||
| 2887 | ```yue | ||
| 2888 | for item in *items do print item | ||
| 2889 | |||
| 2890 | for j = 1, 10, 3 do print j | ||
| 2891 | ``` | ||
| 2892 | |||
| 2893 | </YueDisplay> | ||
| 2894 | |||
| 2895 |   for 循环也可以用作表达式。for 循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。 | 1498 |   for 循环也可以用作表达式。for 循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。 |
| 2896 | 1499 | ||
| 2897 |   将每个偶数加倍: | 1500 |   将每个偶数加倍: |
| @@ -2904,18 +1507,6 @@ doubled_evens = for i = 1, 20 | |||
| 2904 | i | 1507 | i |
| 2905 | ``` | 1508 | ``` |
| 2906 | 1509 | ||
| 2907 | <YueDisplay> | ||
| 2908 | |||
| 2909 | ```yue | ||
| 2910 | doubled_evens = for i = 1, 20 | ||
| 2911 | if i % 2 == 0 | ||
| 2912 | i * 2 | ||
| 2913 | else | ||
| 2914 | i | ||
| 2915 | ``` | ||
| 2916 | |||
| 2917 | </YueDisplay> | ||
| 2918 | |||
| 2919 |   此外,for 循环还支持带返回值的 break 语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。for 循环表达式支持 `break` 返回多个值。 | 1510 |   此外,for 循环还支持带返回值的 break 语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。for 循环表达式支持 `break` 返回多个值。 |
| 2920 | 1511 | ||
| 2921 |   例如,查找第一个大于 10 的数字: | 1512 |   例如,查找第一个大于 10 的数字: |
| @@ -2925,29 +1516,11 @@ first_large = for n in *numbers | |||
| 2925 | break n if n > 10 | 1516 | break n if n > 10 |
| 2926 | ``` | 1517 | ``` |
| 2927 | 1518 | ||
| 2928 | <YueDisplay> | ||
| 2929 | |||
| 2930 | ```yue | ||
| 2931 | first_large = for n in *numbers | ||
| 2932 | break n if n > 10 | ||
| 2933 | ``` | ||
| 2934 | |||
| 2935 | </YueDisplay> | ||
| 2936 | |||
| 2937 | ```yuescript | 1519 | ```yuescript |
| 2938 | key, score = for k, v in pairs data | 1520 | key, score = for k, v in pairs data |
| 2939 | break k, v * 10 if k == "target" | 1521 | break k, v * 10 if k == "target" |
| 2940 | ``` | 1522 | ``` |
| 2941 | 1523 | ||
| 2942 | <YueDisplay> | ||
| 2943 | |||
| 2944 | ```yue | ||
| 2945 | key, score = for k, v in pairs data | ||
| 2946 | break k, v * 10 if k == "target" | ||
| 2947 | ``` | ||
| 2948 | |||
| 2949 | </YueDisplay> | ||
| 2950 | |||
| 2951 |   你还可以结合 for 循环表达式与 continue 语句来过滤值。 | 1524 |   你还可以结合 for 循环表达式与 continue 语句来过滤值。 |
| 2952 | 1525 | ||
| 2953 |   注意出现在函数体末尾的 for 循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回 nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加 for 循环表达式。 | 1526 |   注意出现在函数体末尾的 for 循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回 nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加 for 循环表达式。 |
| @@ -2960,18 +1533,6 @@ print func_a! -- 打印 nil | |||
| 2960 | print func_b! -- 打印 table 对象 | 1533 | print func_b! -- 打印 table 对象 |
| 2961 | ``` | 1534 | ``` |
| 2962 | 1535 | ||
| 2963 | <YueDisplay> | ||
| 2964 | |||
| 2965 | ```yue | ||
| 2966 | func_a = -> for i = 1, 10 do print i | ||
| 2967 | func_b = -> return for i = 1, 10 do i | ||
| 2968 | |||
| 2969 | print func_a! -- 打印 nil | ||
| 2970 | print func_b! -- 打印 table 对象 | ||
| 2971 | ``` | ||
| 2972 | |||
| 2973 | </YueDisplay> | ||
| 2974 | |||
| 2975 |   这样做是为了避免在不需要返回循环结果的函数,创建无效的返回值表格。 | 1536 |   这样做是为了避免在不需要返回循环结果的函数,创建无效的返回值表格。 |
| 2976 | 1537 | ||
| 2977 | # continue 语句 | 1538 | # continue 语句 |
| @@ -2986,18 +1547,6 @@ while i < 10 | |||
| 2986 | print i | 1547 | print i |
| 2987 | ``` | 1548 | ``` |
| 2988 | 1549 | ||
| 2989 | <YueDisplay> | ||
| 2990 | |||
| 2991 | ```yue | ||
| 2992 | i = 0 | ||
| 2993 | while i < 10 | ||
| 2994 | i += 1 | ||
| 2995 | continue if i % 2 == 0 | ||
| 2996 | print i | ||
| 2997 | ``` | ||
| 2998 | |||
| 2999 | </YueDisplay> | ||
| 3000 | |||
| 3001 |   继续语句也可以与各种循环表达式一起使用,以防止当前的循环迭代结果累积到结果列表中。以下示例将数组表过滤为仅包含偶数的数组: | 1550 |   继续语句也可以与各种循环表达式一起使用,以防止当前的循环迭代结果累积到结果列表中。以下示例将数组表过滤为仅包含偶数的数组: |
| 3002 | 1551 | ||
| 3003 | ```yuescript | 1552 | ```yuescript |
| @@ -3007,17 +1556,6 @@ odds = for x in *my_numbers | |||
| 3007 | x | 1556 | x |
| 3008 | ``` | 1557 | ``` |
| 3009 | 1558 | ||
| 3010 | <YueDisplay> | ||
| 3011 | |||
| 3012 | ```yue | ||
| 3013 | my_numbers = [1, 2, 3, 4, 5, 6] | ||
| 3014 | odds = for x in *my_numbers | ||
| 3015 | continue if x % 2 == 1 | ||
| 3016 | x | ||
| 3017 | ``` | ||
| 3018 | |||
| 3019 | </YueDisplay> | ||
| 3020 | |||
| 3021 | # switch 语句 | 1559 | # switch 语句 |
| 3022 | 1560 | ||
| 3023 |   switch 语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和 if 语句一样,switch 语句在最后可以接一个 else 代码块来处理没有匹配的情况。在生成的 Lua 代码中,进行比较是使用 == 操作符完成的。switch 语句中也可以使用赋值表达式来储存临时变量值。 | 1561 |   switch 语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和 if 语句一样,switch 语句在最后可以接一个 else 代码块来处理没有匹配的情况。在生成的 Lua 代码中,进行比较是使用 == 操作符完成的。switch 语句中也可以使用赋值表达式来储存临时变量值。 |
| @@ -3032,20 +1570,6 @@ switch name := "Dan" | |||
| 3032 | print "我不认识你,你的名字是#{name}" | 1570 | print "我不认识你,你的名字是#{name}" |
| 3033 | ``` | 1571 | ``` |
| 3034 | 1572 | ||
| 3035 | <YueDisplay> | ||
| 3036 | |||
| 3037 | ```yue | ||
| 3038 | switch name := "Dan" | ||
| 3039 | when "Robert" | ||
| 3040 | print "你是Robert" | ||
| 3041 | when "Dan", "Daniel" | ||
| 3042 | print "你的名字是Dan" | ||
| 3043 | else | ||
| 3044 | print "我不认识你,你的名字是#{name}" | ||
| 3045 | ``` | ||
| 3046 | |||
| 3047 | </YueDisplay> | ||
| 3048 | |||
| 3049 |   switch 语句的 when 子句中可以通过使用逗号分隔的列表来匹配多个值。 | 1573 |   switch 语句的 when 子句中可以通过使用逗号分隔的列表来匹配多个值。 |
| 3050 | 1574 | ||
| 3051 |   switch 语句也可以作为表达式使用,下面我们可以将 switch 语句返回的结果分配给一个变量: | 1575 |   switch 语句也可以作为表达式使用,下面我们可以将 switch 语句返回的结果分配给一个变量: |
| @@ -3061,21 +1585,6 @@ next_number = switch b | |||
| 3061 | error "数字数得太大了!" | 1585 | error "数字数得太大了!" |
| 3062 | ``` | 1586 | ``` |
| 3063 | 1587 | ||
| 3064 | <YueDisplay> | ||
| 3065 | |||
| 3066 | ```yue | ||
| 3067 | b = 1 | ||
| 3068 | next_number = switch b | ||
| 3069 | when 1 | ||
| 3070 | 2 | ||
| 3071 | when 2 | ||
| 3072 | 3 | ||
| 3073 | else | ||
| 3074 | error "数字数得太大了!" | ||
| 3075 | ``` | ||
| 3076 | |||
| 3077 | </YueDisplay> | ||
| 3078 | |||
| 3079 |   我们可以使用 then 关键字在 when 子句的同一行上编写处理代码。else 代码块的后续代码中要写在同一行上不需要额外的关键字。 | 1588 |   我们可以使用 then 关键字在 when 子句的同一行上编写处理代码。else 代码块的后续代码中要写在同一行上不需要额外的关键字。 |
| 3080 | 1589 | ||
| 3081 | ```yuescript | 1590 | ```yuescript |
| @@ -3085,17 +1594,6 @@ msg = switch math.random(1, 5) | |||
| 3085 | else "不太幸运" | 1594 | else "不太幸运" |
| 3086 | ``` | 1595 | ``` |
| 3087 | 1596 | ||
| 3088 | <YueDisplay> | ||
| 3089 | |||
| 3090 | ```yue | ||
| 3091 | msg = switch math.random(1, 5) | ||
| 3092 | when 1 then "你很幸运" | ||
| 3093 | when 2 then "你差点很幸运" | ||
| 3094 | else "不太幸运" | ||
| 3095 | ``` | ||
| 3096 | |||
| 3097 | </YueDisplay> | ||
| 3098 | |||
| 3099 |   如果在编写 switch 语句时希望少写一个缩进,那么你可以把第一个 when 子句放在 switch 开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。 | 1597 |   如果在编写 switch 语句时希望少写一个缩进,那么你可以把第一个 when 子句放在 switch 开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。 |
| 3100 | 1598 | ||
| 3101 | ```yuescript | 1599 | ```yuescript |
| @@ -3111,23 +1609,6 @@ else | |||
| 3111 | print "不太幸运" | 1609 | print "不太幸运" |
| 3112 | ``` | 1610 | ``` |
| 3113 | 1611 | ||
| 3114 | <YueDisplay> | ||
| 3115 | |||
| 3116 | ```yue | ||
| 3117 | switch math.random(1, 5) | ||
| 3118 | when 1 | ||
| 3119 | print "你很幸运" -- 两个缩进级别 | ||
| 3120 | else | ||
| 3121 | print "不太幸运" | ||
| 3122 | |||
| 3123 | switch math.random(1, 5) when 1 | ||
| 3124 | print "你很幸运" -- 一个缩进级别 | ||
| 3125 | else | ||
| 3126 | print "不太幸运" | ||
| 3127 | ``` | ||
| 3128 | |||
| 3129 | </YueDisplay> | ||
| 3130 | |||
| 3131 |   值得注意的是,在生成 Lua 代码时,我们要做检查的目标变量会放在 == 表达式的右侧。当你希望给 when 子句的比较对象定义一个 \_\_eq 元方法来重载判断逻辑时,可能会有用。 | 1612 |   值得注意的是,在生成 Lua 代码时,我们要做检查的目标变量会放在 == 表达式的右侧。当你希望给 when 子句的比较对象定义一个 \_\_eq 元方法来重载判断逻辑时,可能会有用。 |
| 3132 | 1613 | ||
| 3133 | ## 表格匹配 | 1614 | ## 表格匹配 |
| @@ -3149,25 +1630,6 @@ for item in *items | |||
| 3149 | print "尺寸 #{width}, #{height}" | 1630 | print "尺寸 #{width}, #{height}" |
| 3150 | ``` | 1631 | ``` |
| 3151 | 1632 | ||
| 3152 | <YueDisplay> | ||
| 3153 | |||
| 3154 | ```yue | ||
| 3155 | items = | ||
| 3156 | * x: 100 | ||
| 3157 | y: 200 | ||
| 3158 | * width: 300 | ||
| 3159 | height: 400 | ||
| 3160 | |||
| 3161 | for item in *items | ||
| 3162 | switch item | ||
| 3163 | when :x, :y | ||
| 3164 | print "Vec2 #{x}, #{y}" | ||
| 3165 | when :width, :height | ||
| 3166 | print "尺寸 #{width}, #{height}" | ||
| 3167 | ``` | ||
| 3168 | |||
| 3169 | </YueDisplay> | ||
| 3170 | |||
| 3171 |   你可以使用默认值来选择性地解构表格的某些字段。 | 1633 |   你可以使用默认值来选择性地解构表格的某些字段。 |
| 3172 | 1634 | ||
| 3173 | ```yuescript | 1635 | ```yuescript |
| @@ -3180,20 +1642,6 @@ switch item | |||
| 3180 | print "Vec2 #{x}, #{y}" -- 表格解构仍然会通过 | 1642 | print "Vec2 #{x}, #{y}" -- 表格解构仍然会通过 |
| 3181 | ``` | 1643 | ``` |
| 3182 | 1644 | ||
| 3183 | <YueDisplay> | ||
| 3184 | |||
| 3185 | ```yue | ||
| 3186 | item = {} | ||
| 3187 | |||
| 3188 | {pos: {:x = 50, :y = 200}} = item -- 获取错误:尝试索引nil值(字段'pos') | ||
| 3189 | |||
| 3190 | switch item | ||
| 3191 | when {pos: {:x = 50, :y = 200}} | ||
| 3192 | print "Vec2 #{x}, #{y}" -- 表格解构仍然会通过 | ||
| 3193 | ``` | ||
| 3194 | |||
| 3195 | </YueDisplay> | ||
| 3196 | |||
| 3197 |   你也可以匹配数组元素、表格字段,甚至使用数组或表格字面量来匹配嵌套的结构。 | 1645 |   你也可以匹配数组元素、表格字段,甚至使用数组或表格字面量来匹配嵌套的结构。 |
| 3198 | 1646 | ||
| 3199 |   匹配数组元素。 | 1647 |   匹配数组元素。 |
| @@ -3208,20 +1656,6 @@ switch tb | |||
| 3208 | print "1, 2, #{b}" | 1656 | print "1, 2, #{b}" |
| 3209 | ``` | 1657 | ``` |
| 3210 | 1658 | ||
| 3211 | <YueDisplay> | ||
| 3212 | |||
| 3213 | ```yue | ||
| 3214 | switch tb | ||
| 3215 | when [1, 2, 3] | ||
| 3216 | print "1, 2, 3" | ||
| 3217 | when [1, b, 3] | ||
| 3218 | print "1, #{b}, 3" | ||
| 3219 | when [1, 2, b = 3] -- 变量b有默认值 | ||
| 3220 | print "1, 2, #{b}" | ||
| 3221 | ``` | ||
| 3222 | |||
| 3223 | </YueDisplay> | ||
| 3224 | |||
| 3225 |   匹配表格字段。 | 1659 |   匹配表格字段。 |
| 3226 | 1660 | ||
| 3227 | ```yuescript | 1661 | ```yuescript |
| @@ -3234,20 +1668,6 @@ switch tb | |||
| 3234 | print "无效值" | 1668 | print "无效值" |
| 3235 | ``` | 1669 | ``` |
| 3236 | 1670 | ||
| 3237 | <YueDisplay> | ||
| 3238 | |||
| 3239 | ```yue | ||
| 3240 | switch tb | ||
| 3241 | when success: true, :result | ||
| 3242 | print "成功", result | ||
| 3243 | when success: false | ||
| 3244 | print "失败", result | ||
| 3245 | else | ||
| 3246 | print "无效值" | ||
| 3247 | ``` | ||
| 3248 | |||
| 3249 | </YueDisplay> | ||
| 3250 | |||
| 3251 |   匹配嵌套的表格结构。 | 1671 |   匹配嵌套的表格结构。 |
| 3252 | 1672 | ||
| 3253 | ```yuescript | 1673 | ```yuescript |
| @@ -3260,20 +1680,6 @@ switch tb | |||
| 3260 | print "无效值" | 1680 | print "无效值" |
| 3261 | ``` | 1681 | ``` |
| 3262 | 1682 | ||
| 3263 | <YueDisplay> | ||
| 3264 | |||
| 3265 | ```yue | ||
| 3266 | switch tb | ||
| 3267 | when data: {type: "success", :content} | ||
| 3268 | print "成功", content | ||
| 3269 | when data: {type: "error", :content} | ||
| 3270 | print "失败", content | ||
| 3271 | else | ||
| 3272 | print "无效值" | ||
| 3273 | ``` | ||
| 3274 | |||
| 3275 | </YueDisplay> | ||
| 3276 | |||
| 3277 |   匹配表格数组。 | 1683 |   匹配表格数组。 |
| 3278 | 1684 | ||
| 3279 | ```yuescript | 1685 | ```yuescript |
| @@ -3287,21 +1693,6 @@ switch tb | |||
| 3287 | print "匹配成功", fourth | 1693 | print "匹配成功", fourth |
| 3288 | ``` | 1694 | ``` |
| 3289 | 1695 | ||
| 3290 | <YueDisplay> | ||
| 3291 | |||
| 3292 | ```yue | ||
| 3293 | switch tb | ||
| 3294 | when [ | ||
| 3295 | {a: 1, b: 2} | ||
| 3296 | {a: 3, b: 4} | ||
| 3297 | {a: 5, b: 6} | ||
| 3298 | fourth | ||
| 3299 | ] | ||
| 3300 | print "匹配成功", fourth | ||
| 3301 | ``` | ||
| 3302 | |||
| 3303 | </YueDisplay> | ||
| 3304 | |||
| 3305 |   匹配一个列表并捕获特定范围内的元素。 | 1696 |   匹配一个列表并捕获特定范围内的元素。 |
| 3306 | 1697 | ||
| 3307 | ```yuescript | 1698 | ```yuescript |
| @@ -3313,19 +1704,6 @@ switch segments | |||
| 3313 | print "Action:", action -- 打印: "view" | 1704 | print "Action:", action -- 打印: "view" |
| 3314 | ``` | 1705 | ``` |
| 3315 | 1706 | ||
| 3316 | <YueDisplay> | ||
| 3317 | |||
| 3318 | ```yue | ||
| 3319 | segments = ["admin", "users", "logs", "view"] | ||
| 3320 | switch segments | ||
| 3321 | when [...groups, resource, action] | ||
| 3322 | print "Group:", groups -- 打印: {"admin", "users"} | ||
| 3323 | print "Resource:", resource -- 打印: "logs" | ||
| 3324 | print "Action:", action -- 打印: "view" | ||
| 3325 | ``` | ||
| 3326 | |||
| 3327 | </YueDisplay> | ||
| 3328 | |||
| 3329 | # while 循环 | 1707 | # while 循环 |
| 3330 | 1708 | ||
| 3331 |   在月之脚本中的 while 循环支持几种不同的写法: | 1709 |   在月之脚本中的 while 循环支持几种不同的写法: |
| @@ -3339,19 +1717,6 @@ while i > 0 | |||
| 3339 | while running == true do my_function! | 1717 | while running == true do my_function! |
| 3340 | ``` | 1718 | ``` |
| 3341 | 1719 | ||
| 3342 | <YueDisplay> | ||
| 3343 | |||
| 3344 | ```yue | ||
| 3345 | i = 10 | ||
| 3346 | while i > 0 | ||
| 3347 | print i | ||
| 3348 | i -= 1 | ||
| 3349 | |||
| 3350 | while running == true do my_function! | ||
| 3351 | ``` | ||
| 3352 | |||
| 3353 | </YueDisplay> | ||
| 3354 | |||
| 3355 | ```yuescript | 1720 | ```yuescript |
| 3356 | i = 10 | 1721 | i = 10 |
| 3357 | until i == 0 | 1722 | until i == 0 |
| @@ -3361,18 +1726,6 @@ until i == 0 | |||
| 3361 | until running == false do my_function! | 1726 | until running == false do my_function! |
| 3362 | ``` | 1727 | ``` |
| 3363 | 1728 | ||
| 3364 | <YueDisplay> | ||
| 3365 | |||
| 3366 | ```yue | ||
| 3367 | i = 10 | ||
| 3368 | until i == 0 | ||
| 3369 | print i | ||
| 3370 | i -= 1 | ||
| 3371 | until running == false do my_function! | ||
| 3372 | ``` | ||
| 3373 | |||
| 3374 | </YueDisplay> | ||
| 3375 | |||
| 3376 |   像 for 循环的语法一样,while 循环也可以作为一个表达式使用。while / until 循环表达式支持 `break` 返回多个值。 | 1729 |   像 for 循环的语法一样,while 循环也可以作为一个表达式使用。while / until 循环表达式支持 `break` 返回多个值。 |
| 3377 | 1730 | ||
| 3378 | ```yuescript | 1731 | ```yuescript |
| @@ -3381,16 +1734,6 @@ value, doubled = while true | |||
| 3381 | break n, n * 2 if n > 10 | 1734 | break n, n * 2 if n > 10 |
| 3382 | ``` | 1735 | ``` |
| 3383 | 1736 | ||
| 3384 | <YueDisplay> | ||
| 3385 | |||
| 3386 | ```yue | ||
| 3387 | value, doubled = while true | ||
| 3388 | n = get_next! | ||
| 3389 | break n, n * 2 if n > 10 | ||
| 3390 | ``` | ||
| 3391 | |||
| 3392 | </YueDisplay> | ||
| 3393 | |||
| 3394 |   为了使函数返回 while 循环的累积列表值,必须明确使用返回语句返回 while 循环表达式。 | 1737 |   为了使函数返回 while 循环的累积列表值,必须明确使用返回语句返回 while 循环表达式。 |
| 3395 | 1738 | ||
| 3396 | ## repeat 循环 | 1739 | ## repeat 循环 |
| @@ -3405,18 +1748,6 @@ repeat | |||
| 3405 | until i == 0 | 1748 | until i == 0 |
| 3406 | ``` | 1749 | ``` |
| 3407 | 1750 | ||
| 3408 | <YueDisplay> | ||
| 3409 | |||
| 3410 | ```yue | ||
| 3411 | i = 10 | ||
| 3412 | repeat | ||
| 3413 | print i | ||
| 3414 | i -= 1 | ||
| 3415 | until i == 0 | ||
| 3416 | ``` | ||
| 3417 | |||
| 3418 | </YueDisplay> | ||
| 3419 | |||
| 3420 |   repeat 循环表达式同样支持 `break` 返回多个值: | 1751 |   repeat 循环表达式同样支持 `break` 返回多个值: |
| 3421 | 1752 | ||
| 3422 | ```yuescript | 1753 | ```yuescript |
| @@ -3427,18 +1758,6 @@ value, scaled = repeat | |||
| 3427 | until false | 1758 | until false |
| 3428 | ``` | 1759 | ``` |
| 3429 | 1760 | ||
| 3430 | <YueDisplay> | ||
| 3431 | |||
| 3432 | ```yue | ||
| 3433 | i = 1 | ||
| 3434 | value, scaled = repeat | ||
| 3435 | break i, i * 100 if i > 3 | ||
| 3436 | i += 1 | ||
| 3437 | until false | ||
| 3438 | ``` | ||
| 3439 | |||
| 3440 | </YueDisplay> | ||
| 3441 | |||
| 3442 | # 函数存根 | 1761 | # 函数存根 |
| 3443 | 1762 | ||
| 3444 |   在编程中,将对象的方法作为函数类型的值进行传递是一种常见做法,尤其是在将实例方法作为回调函数传递给其他函数的情形中。当目标函数需要将该对象作为其第一个参数时,我们需要找到一种方式将对象和函数绑定在一起,以便能够正确地调用该函数。 | 1763 |   在编程中,将对象的方法作为函数类型的值进行传递是一种常见做法,尤其是在将实例方法作为回调函数传递给其他函数的情形中。当目标函数需要将该对象作为其第一个参数时,我们需要找到一种方式将对象和函数绑定在一起,以便能够正确地调用该函数。 |
| @@ -3466,29 +1785,6 @@ run_callback my_object.write | |||
| 3466 | run_callback my_object\write | 1785 | run_callback my_object\write |
| 3467 | ``` | 1786 | ``` |
| 3468 | 1787 | ||
| 3469 | <YueDisplay> | ||
| 3470 | |||
| 3471 | ```yue | ||
| 3472 | my_object = { | ||
| 3473 | value: 1000 | ||
| 3474 | write: => print "值为:", @value | ||
| 3475 | } | ||
| 3476 | |||
| 3477 | run_callback = (func) -> | ||
| 3478 | print "运行回调..." | ||
| 3479 | func! | ||
| 3480 | |||
| 3481 | -- 这样写不起作用: | ||
| 3482 | -- 函数没有引用my_object | ||
| 3483 | run_callback my_object.write | ||
| 3484 | |||
| 3485 | -- 函数存根语法 | ||
| 3486 | -- 让我们把对象捆绑到一个新函数中 | ||
| 3487 | run_callback my_object\write | ||
| 3488 | ``` | ||
| 3489 | |||
| 3490 | </YueDisplay> | ||
| 3491 | |||
| 3492 | # 反向回调 | 1788 | # 反向回调 |
| 3493 | 1789 | ||
| 3494 |   反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。 | 1790 |   反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。 |
| @@ -3498,15 +1794,6 @@ x <- f | |||
| 3498 | print "hello" .. x | 1794 | print "hello" .. x |
| 3499 | ``` | 1795 | ``` |
| 3500 | 1796 | ||
| 3501 | <YueDisplay> | ||
| 3502 | |||
| 3503 | ```yue | ||
| 3504 | x <- f | ||
| 3505 | print "hello" .. x | ||
| 3506 | ``` | ||
| 3507 | |||
| 3508 | </YueDisplay> | ||
| 3509 | |||
| 3510 |   月之脚本也提供了粗箭头反向回调函数。 | 1797 |   月之脚本也提供了粗箭头反向回调函数。 |
| 3511 | 1798 | ||
| 3512 | ```yuescript | 1799 | ```yuescript |
| @@ -3514,15 +1801,6 @@ print "hello" .. x | |||
| 3514 | print @value | 1801 | print @value |
| 3515 | ``` | 1802 | ``` |
| 3516 | 1803 | ||
| 3517 | <YueDisplay> | ||
| 3518 | |||
| 3519 | ```yue | ||
| 3520 | <= f | ||
| 3521 | print @value | ||
| 3522 | ``` | ||
| 3523 | |||
| 3524 | </YueDisplay> | ||
| 3525 | |||
| 3526 |   你可以通过一个占位符指定回调函数的传参位置。 | 1804 |   你可以通过一个占位符指定回调函数的传参位置。 |
| 3527 | 1805 | ||
| 3528 | ```yuescript | 1806 | ```yuescript |
| @@ -3530,15 +1808,6 @@ print @value | |||
| 3530 | x * 2 | 1808 | x * 2 |
| 3531 | ``` | 1809 | ``` |
| 3532 | 1810 | ||
| 3533 | <YueDisplay> | ||
| 3534 | |||
| 3535 | ```yue | ||
| 3536 | (x) <- map _, [1, 2, 3] | ||
| 3537 | x * 2 | ||
| 3538 | ``` | ||
| 3539 | |||
| 3540 | </YueDisplay> | ||
| 3541 | |||
| 3542 |   如果你希望在反向回调处理后继续编写更多其它的代码,可以使用 do 语句将不属于反向回调的代码分隔开。对于非粗箭头函数的反向回调,回调返回值的括号也是可以省略的。 | 1811 |   如果你希望在反向回调处理后继续编写更多其它的代码,可以使用 do 语句将不属于反向回调的代码分隔开。对于非粗箭头函数的反向回调,回调返回值的括号也是可以省略的。 |
| 3543 | 1812 | ||
| 3544 | ```yuescript | 1813 | ```yuescript |
| @@ -3550,19 +1819,6 @@ result, msg = do | |||
| 3550 | print result, msg | 1819 | print result, msg |
| 3551 | ``` | 1820 | ``` |
| 3552 | 1821 | ||
| 3553 | <YueDisplay> | ||
| 3554 | |||
| 3555 | ```yue | ||
| 3556 | result, msg = do | ||
| 3557 | data <- readAsync "文件名.txt" | ||
| 3558 | print data | ||
| 3559 | info <- processAsync data | ||
| 3560 | check info | ||
| 3561 | print result, msg | ||
| 3562 | ``` | ||
| 3563 | |||
| 3564 | </YueDisplay> | ||
| 3565 | |||
| 3566 | # 函数字面量 | 1822 | # 函数字面量 |
| 3567 | 1823 | ||
| 3568 |   所有函数都是使用月之脚本的函数表达式创建的。一个简单的函数可以用箭头表示为:**->**。 | 1824 |   所有函数都是使用月之脚本的函数表达式创建的。一个简单的函数可以用箭头表示为:**->**。 |
| @@ -3572,15 +1828,6 @@ my_function = -> | |||
| 3572 | my_function() -- 调用空函数 | 1828 | my_function() -- 调用空函数 |
| 3573 | ``` | 1829 | ``` |
| 3574 | 1830 | ||
| 3575 | <YueDisplay> | ||
| 3576 | |||
| 3577 | ```yue | ||
| 3578 | my_function = -> | ||
| 3579 | my_function() -- 调用空函数 | ||
| 3580 | ``` | ||
| 3581 | |||
| 3582 | </YueDisplay> | ||
| 3583 | |||
| 3584 |   函数体可以是紧跟在箭头后的一个语句,或者是在后面的行上使用同样缩进的一系列语句: | 1831 |   函数体可以是紧跟在箭头后的一个语句,或者是在后面的行上使用同样缩进的一系列语句: |
| 3585 | 1832 | ||
| 3586 | ```yuescript | 1833 | ```yuescript |
| @@ -3591,18 +1838,6 @@ func_b = -> | |||
| 3591 | print "这个值是:", value | 1838 | print "这个值是:", value |
| 3592 | ``` | 1839 | ``` |
| 3593 | 1840 | ||
| 3594 | <YueDisplay> | ||
| 3595 | |||
| 3596 | ```yue | ||
| 3597 | func_a = -> print "你好,世界" | ||
| 3598 | |||
| 3599 | func_b = -> | ||
| 3600 | value = 100 | ||
| 3601 | print "这个值是:", value | ||
| 3602 | ``` | ||
| 3603 | |||
| 3604 | </YueDisplay> | ||
| 3605 | |||
| 3606 |   如果一个函数没有参数,可以使用 **\!** 操作符调用它,而不是空括号。使用 **\!** 调用没有参数的函数是推荐的写法。 | 1841 |   如果一个函数没有参数,可以使用 **\!** 操作符调用它,而不是空括号。使用 **\!** 调用没有参数的函数是推荐的写法。 |
| 3607 | 1842 | ||
| 3608 | ```yuescript | 1843 | ```yuescript |
| @@ -3610,29 +1845,12 @@ func_a! | |||
| 3610 | func_b() | 1845 | func_b() |
| 3611 | ``` | 1846 | ``` |
| 3612 | 1847 | ||
| 3613 | <YueDisplay> | ||
| 3614 | |||
| 3615 | ```yue | ||
| 3616 | func_a! | ||
| 3617 | func_b() | ||
| 3618 | ``` | ||
| 3619 | |||
| 3620 | </YueDisplay> | ||
| 3621 | |||
| 3622 |   带有参数的函数可以通过在箭头前加上括号中的参数名列表来进行创建: | 1848 |   带有参数的函数可以通过在箭头前加上括号中的参数名列表来进行创建: |
| 3623 | 1849 | ||
| 3624 | ```yuescript | 1850 | ```yuescript |
| 3625 | sum = (x, y) -> print "数字的和", x + y | 1851 | sum = (x, y) -> print "数字的和", x + y |
| 3626 | ``` | 1852 | ``` |
| 3627 | 1853 | ||
| 3628 | <YueDisplay> | ||
| 3629 | |||
| 3630 | ```yue | ||
| 3631 | sum = (x, y) -> print "数字的和", x + y | ||
| 3632 | ``` | ||
| 3633 | |||
| 3634 | </YueDisplay> | ||
| 3635 | |||
| 3636 |   函数可以通过在函数名后列出参数来调用。当对函数做嵌套的调用时,后面列出的参数会应用于左侧最近的函数。 | 1854 |   函数可以通过在函数名后列出参数来调用。当对函数做嵌套的调用时,后面列出的参数会应用于左侧最近的函数。 |
| 3637 | 1855 | ||
| 3638 | ```yuescript | 1856 | ```yuescript |
| @@ -3642,31 +1860,12 @@ print sum 10, 20 | |||
| 3642 | a b c "a", "b", "c" | 1860 | a b c "a", "b", "c" |
| 3643 | ``` | 1861 | ``` |
| 3644 | 1862 | ||
| 3645 | <YueDisplay> | ||
| 3646 | |||
| 3647 | ```yue | ||
| 3648 | sum 10, 20 | ||
| 3649 | print sum 10, 20 | ||
| 3650 | |||
| 3651 | a b c "a", "b", "c" | ||
| 3652 | ``` | ||
| 3653 | |||
| 3654 | </YueDisplay> | ||
| 3655 | |||
| 3656 |   为了避免在调用函数时产生歧义,也可以使用括号将参数括起来。比如在以下的例子中是必需的,这样才能确保参数被传入到正确的函数。 | 1863 |   为了避免在调用函数时产生歧义,也可以使用括号将参数括起来。比如在以下的例子中是必需的,这样才能确保参数被传入到正确的函数。 |
| 3657 | 1864 | ||
| 3658 | ```yuescript | 1865 | ```yuescript |
| 3659 | print "x:", sum(10, 20), "y:", sum(30, 40) | 1866 | print "x:", sum(10, 20), "y:", sum(30, 40) |
| 3660 | ``` | 1867 | ``` |
| 3661 | 1868 | ||
| 3662 | <YueDisplay> | ||
| 3663 | |||
| 3664 | ```yue | ||
| 3665 | print "x:", sum(10, 20), "y:", sum(30, 40) | ||
| 3666 | ``` | ||
| 3667 | |||
| 3668 | </YueDisplay> | ||
| 3669 | |||
| 3670 |   注意:函数名与开始括号之间不能有任何空格。 | 1869 |   注意:函数名与开始括号之间不能有任何空格。 |
| 3671 | 1870 | ||
| 3672 |   函数会将函数体中的最后一个语句强制转换为返回语句,这被称作隐式返回: | 1871 |   函数会将函数体中的最后一个语句强制转换为返回语句,这被称作隐式返回: |
| @@ -3676,29 +1875,12 @@ sum = (x, y) -> x + y | |||
| 3676 | print "数字的和是", sum 10, 20 | 1875 | print "数字的和是", sum 10, 20 |
| 3677 | ``` | 1876 | ``` |
| 3678 | 1877 | ||
| 3679 | <YueDisplay> | ||
| 3680 | |||
| 3681 | ```yue | ||
| 3682 | sum = (x, y) -> x + y | ||
| 3683 | print "数字的和是", sum 10, 20 | ||
| 3684 | ``` | ||
| 3685 | |||
| 3686 | </YueDisplay> | ||
| 3687 | |||
| 3688 |   如果你需要做显式返回,可以使用 return 关键字: | 1878 |   如果你需要做显式返回,可以使用 return 关键字: |
| 3689 | 1879 | ||
| 3690 | ```yuescript | 1880 | ```yuescript |
| 3691 | sum = (x, y) -> return x + y | 1881 | sum = (x, y) -> return x + y |
| 3692 | ``` | 1882 | ``` |
| 3693 | 1883 | ||
| 3694 | <YueDisplay> | ||
| 3695 | |||
| 3696 | ```yue | ||
| 3697 | sum = (x, y) -> return x + y | ||
| 3698 | ``` | ||
| 3699 | |||
| 3700 | </YueDisplay> | ||
| 3701 | |||
| 3702 |   就像在Lua中一样,函数可以返回多个值。最后一个语句必须是由逗号分隔的值列表: | 1884 |   就像在Lua中一样,函数可以返回多个值。最后一个语句必须是由逗号分隔的值列表: |
| 3703 | 1885 | ||
| 3704 | ```yuescript | 1886 | ```yuescript |
| @@ -3706,15 +1888,6 @@ mystery = (x, y) -> x + y, x - y | |||
| 3706 | a, b = mystery 10, 20 | 1888 | a, b = mystery 10, 20 |
| 3707 | ``` | 1889 | ``` |
| 3708 | 1890 | ||
| 3709 | <YueDisplay> | ||
| 3710 | |||
| 3711 | ```yue | ||
| 3712 | mystery = (x, y) -> x + y, x - y | ||
| 3713 | a, b = mystery 10, 20 | ||
| 3714 | ``` | ||
| 3715 | |||
| 3716 | </YueDisplay> | ||
| 3717 | |||
| 3718 | ## 粗箭头 | 1891 | ## 粗箭头 |
| 3719 | 1892 | ||
| 3720 |   因为在 Lua 中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含 self 参数的函数。 | 1893 |   因为在 Lua 中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含 self 参数的函数。 |
| @@ -3723,14 +1896,6 @@ a, b = mystery 10, 20 | |||
| 3723 | func = (num) => @value + num | 1896 | func = (num) => @value + num |
| 3724 | ``` | 1897 | ``` |
| 3725 | 1898 | ||
| 3726 | <YueDisplay> | ||
| 3727 | |||
| 3728 | ```yue | ||
| 3729 | func = (num) => @value + num | ||
| 3730 | ``` | ||
| 3731 | |||
| 3732 | </YueDisplay> | ||
| 3733 | |||
| 3734 | ## 参数默认值 | 1899 | ## 参数默认值 |
| 3735 | 1900 | ||
| 3736 |   可以为函数的参数提供默认值。如果参数的值为 nil,则确定该参数为空。任何具有默认值的 nil 参数在函数体运行之前都会被替换。 | 1901 |   可以为函数的参数提供默认值。如果参数的值为 nil,则确定该参数为空。任何具有默认值的 nil 参数在函数体运行之前都会被替换。 |
| @@ -3741,16 +1906,6 @@ my_function = (name = "某物", height = 100) -> | |||
| 3741 | print "我的高度是", height | 1906 | print "我的高度是", height |
| 3742 | ``` | 1907 | ``` |
| 3743 | 1908 | ||
| 3744 | <YueDisplay> | ||
| 3745 | |||
| 3746 | ```yue | ||
| 3747 | my_function = (name = "某物", height = 100) -> | ||
| 3748 | print "你好,我是", name | ||
| 3749 | print "我的高度是", height | ||
| 3750 | ``` | ||
| 3751 | |||
| 3752 | </YueDisplay> | ||
| 3753 | |||
| 3754 |   函数参数的默认值表达式在函数体中会按参数声明的顺序进行计算。因此,在默认值的表达式中可以访问先前声明的参数。 | 1909 |   函数参数的默认值表达式在函数体中会按参数声明的顺序进行计算。因此,在默认值的表达式中可以访问先前声明的参数。 |
| 3755 | 1910 | ||
| 3756 | ```yuescript | 1911 | ```yuescript |
| @@ -3758,15 +1913,6 @@ some_args = (x = 100, y = x + 1000) -> | |||
| 3758 | print x + y | 1913 | print x + y |
| 3759 | ``` | 1914 | ``` |
| 3760 | 1915 | ||
| 3761 | <YueDisplay> | ||
| 3762 | |||
| 3763 | ```yue | ||
| 3764 | some_args = (x = 100, y = x + 1000) -> | ||
| 3765 | print x + y | ||
| 3766 | ``` | ||
| 3767 | |||
| 3768 | </YueDisplay> | ||
| 3769 | |||
| 3770 | ## 注意事项 | 1916 | ## 注意事项 |
| 3771 | 1917 | ||
| 3772 |   由于月之脚本支持无需括号的表达式式函数调用,因此为了避免因空白字符造成的解析歧义,需要进行一些限制。 | 1918 |   由于月之脚本支持无需括号的表达式式函数调用,因此为了避免因空白字符造成的解析歧义,需要进行一些限制。 |
| @@ -3780,17 +1926,6 @@ c = x -y | |||
| 3780 | d = x- z | 1926 | d = x- z |
| 3781 | ``` | 1927 | ``` |
| 3782 | 1928 | ||
| 3783 | <YueDisplay> | ||
| 3784 | |||
| 3785 | ```yue | ||
| 3786 | a = x - 10 | ||
| 3787 | b = x-10 | ||
| 3788 | c = x -y | ||
| 3789 | d = x- z | ||
| 3790 | ``` | ||
| 3791 | |||
| 3792 | </YueDisplay> | ||
| 3793 | |||
| 3794 |   当函数调用的第一个参数是字符串字面量时,可以通过空白控制其优先级。在 Lua 中,常见的写法是调用仅有一个字符串或表字面量参数的函数时省略括号。 | 1929 |   当函数调用的第一个参数是字符串字面量时,可以通过空白控制其优先级。在 Lua 中,常见的写法是调用仅有一个字符串或表字面量参数的函数时省略括号。 |
| 3795 | 1930 | ||
| 3796 |   当变量名和字符串字面量之间没有空格时,函数的调用优先级高于后续表达式,因此此时无法再传入其他参数。 | 1931 |   当变量名和字符串字面量之间没有空格时,函数的调用优先级高于后续表达式,因此此时无法再传入其他参数。 |
| @@ -3802,15 +1937,6 @@ x = func"hello" + 100 | |||
| 3802 | y = func "hello" + 100 | 1937 | y = func "hello" + 100 |
| 3803 | ``` | 1938 | ``` |
| 3804 | 1939 | ||
| 3805 | <YueDisplay> | ||
| 3806 | |||
| 3807 | ```yue | ||
| 3808 | x = func"hello" + 100 | ||
| 3809 | y = func "hello" + 100 | ||
| 3810 | ``` | ||
| 3811 | |||
| 3812 | </YueDisplay> | ||
| 3813 | |||
| 3814 | ## 多行参数 | 1940 | ## 多行参数 |
| 3815 | 1941 | ||
| 3816 |   当调用接收大量参数的函数时,将参数列表分成多行是很方便的。由于月之脚本语言对空白字符的敏感性,做参数列表的分割时务必要小心。 | 1942 |   当调用接收大量参数的函数时,将参数列表分成多行是很方便的。由于月之脚本语言对空白字符的敏感性,做参数列表的分割时务必要小心。 |
| @@ -3827,20 +1953,6 @@ cool_func 1, 2, | |||
| 3827 | 7, 8 | 1953 | 7, 8 |
| 3828 | ``` | 1954 | ``` |
| 3829 | 1955 | ||
| 3830 | <YueDisplay> | ||
| 3831 | |||
| 3832 | ```yue | ||
| 3833 | my_func 5, 4, 3, | ||
| 3834 | 8, 9, 10 | ||
| 3835 | |||
| 3836 | cool_func 1, 2, | ||
| 3837 | 3, 4, | ||
| 3838 | 5, 6, | ||
| 3839 | 7, 8 | ||
| 3840 | ``` | ||
| 3841 | |||
| 3842 | </YueDisplay> | ||
| 3843 | |||
| 3844 |   这种调用方式可以做嵌套。并通过缩进级别来确定参数属于哪一个函数。 | 1956 |   这种调用方式可以做嵌套。并通过缩进级别来确定参数属于哪一个函数。 |
| 3845 | 1957 | ||
| 3846 | ```yuescript | 1958 | ```yuescript |
| @@ -3850,17 +1962,6 @@ my_func 5, 6, 7, | |||
| 3850 | 5, 4 | 1962 | 5, 4 |
| 3851 | ``` | 1963 | ``` |
| 3852 | 1964 | ||
| 3853 | <YueDisplay> | ||
| 3854 | |||
| 3855 | ```yue | ||
| 3856 | my_func 5, 6, 7, | ||
| 3857 | 6, another_func 6, 7, 8, | ||
| 3858 | 9, 1, 2, | ||
| 3859 | 5, 4 | ||
| 3860 | ``` | ||
| 3861 | |||
| 3862 | </YueDisplay> | ||
| 3863 | |||
| 3864 |   因为 Lua 表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是 Lua 表的一部分。 | 1965 |   因为 Lua 表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是 Lua 表的一部分。 |
| 3865 | 1966 | ||
| 3866 | ```yuescript | 1967 | ```yuescript |
| @@ -3871,18 +1972,6 @@ x = [ | |||
| 3871 | ] | 1972 | ] |
| 3872 | ``` | 1973 | ``` |
| 3873 | 1974 | ||
| 3874 | <YueDisplay> | ||
| 3875 | |||
| 3876 | ```yue | ||
| 3877 | x = [ | ||
| 3878 | 1, 2, 3, 4, a_func 4, 5, | ||
| 3879 | 5, 6, | ||
| 3880 | 8, 9, 10 | ||
| 3881 | ] | ||
| 3882 | ``` | ||
| 3883 | |||
| 3884 | </YueDisplay> | ||
| 3885 | |||
| 3886 |   有个不常见的写法可以注意一下,如果我们将在后面使用较低的缩进,我们可以为函数参数提供更深的缩进来区分列表的归属。 | 1975 |   有个不常见的写法可以注意一下,如果我们将在后面使用较低的缩进,我们可以为函数参数提供更深的缩进来区分列表的归属。 |
| 3887 | 1976 | ||
| 3888 | ```yuescript | 1977 | ```yuescript |
| @@ -3892,17 +1981,6 @@ y = [ my_func 1, 2, 3, | |||
| 3892 | ] | 1981 | ] |
| 3893 | ``` | 1982 | ``` |
| 3894 | 1983 | ||
| 3895 | <YueDisplay> | ||
| 3896 | |||
| 3897 | ```yue | ||
| 3898 | y = [ my_func 1, 2, 3, | ||
| 3899 | 4, 5, | ||
| 3900 | 5, 6, 7 | ||
| 3901 | ] | ||
| 3902 | ``` | ||
| 3903 | |||
| 3904 | </YueDisplay> | ||
| 3905 | |||
| 3906 |   对于其它有代码块跟随的语句,比如条件语句,也可以通过小心安排缩进来做类似的事。比如我们可以通过调整缩进级别来控制一些值归属于哪个语句: | 1984 |   对于其它有代码块跟随的语句,比如条件语句,也可以通过小心安排缩进来做类似的事。比如我们可以通过调整缩进级别来控制一些值归属于哪个语句: |
| 3907 | 1985 | ||
| 3908 | ```yuescript | 1986 | ```yuescript |
| @@ -3919,24 +1997,6 @@ if func 1, 2, 3, | |||
| 3919 | print "我在if内部" | 1997 | print "我在if内部" |
| 3920 | ``` | 1998 | ``` |
| 3921 | 1999 | ||
| 3922 | <YueDisplay> | ||
| 3923 | |||
| 3924 | ```yue | ||
| 3925 | if func 1, 2, 3, | ||
| 3926 | "你好", | ||
| 3927 | "世界" | ||
| 3928 | print "你好" | ||
| 3929 | print "我在if内部" | ||
| 3930 | |||
| 3931 | if func 1, 2, 3, | ||
| 3932 | "你好", | ||
| 3933 | "世界" | ||
| 3934 | print "你好" | ||
| 3935 | print "我在if内部" | ||
| 3936 | ``` | ||
| 3937 | |||
| 3938 | </YueDisplay> | ||
| 3939 | |||
| 3940 | ## 参数解构 | 2000 | ## 参数解构 |
| 3941 | 2001 | ||
| 3942 |   月之脚本支持在函数形参位置对传入对象进行解构。适用两类解构表子面量: | 2002 |   月之脚本支持在函数形参位置对传入对象进行解构。适用两类解构表子面量: |
| @@ -3958,23 +2018,6 @@ arg1 = {a: 0} | |||
| 3958 | f2 arg1, arg2 | 2018 | f2 arg1, arg2 |
| 3959 | ``` | 2019 | ``` |
| 3960 | 2020 | ||
| 3961 | <YueDisplay> | ||
| 3962 | |||
| 3963 | ```yue | ||
| 3964 | f1 = (:a, :b, :c) -> | ||
| 3965 | print a, b, c | ||
| 3966 | |||
| 3967 | f1 a: 1, b: "2", c: {} | ||
| 3968 | |||
| 3969 | f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) -> | ||
| 3970 | print a1, b, c | ||
| 3971 | |||
| 3972 | arg1 = {a: 0} | ||
| 3973 | f2 arg1, arg2 | ||
| 3974 | ``` | ||
| 3975 | |||
| 3976 | </YueDisplay> | ||
| 3977 | |||
| 3978 | ## 前置返回表达式 | 2021 | ## 前置返回表达式 |
| 3979 | 2022 | ||
| 3980 |   在深度嵌套的函数体中,为了提升返回值的可读性及编写便利性,我们新增了 “前置返回表达式” 语法。其形式如下: | 2023 |   在深度嵌套的函数体中,为了提升返回值的可读性及编写便利性,我们新增了 “前置返回表达式” 语法。其形式如下: |
| @@ -3988,19 +2031,6 @@ findFirstEven = (list): nil -> | |||
| 3988 | return sub | 2031 | return sub |
| 3989 | ``` | 2032 | ``` |
| 3990 | 2033 | ||
| 3991 | <YueDisplay> | ||
| 3992 | |||
| 3993 | ```yue | ||
| 3994 | findFirstEven = (list): nil -> | ||
| 3995 | for item in *list | ||
| 3996 | if type(item) == "table" | ||
| 3997 | for sub in *item | ||
| 3998 | if sub % 2 == 0 | ||
| 3999 | return sub | ||
| 4000 | ``` | ||
| 4001 | |||
| 4002 | </YueDisplay> | ||
| 4003 | |||
| 4004 |   这个写法等价于: | 2034 |   这个写法等价于: |
| 4005 | 2035 | ||
| 4006 | ```yuescript | 2036 | ```yuescript |
| @@ -4013,20 +2043,6 @@ findFirstEven = (list) -> | |||
| 4013 | nil | 2043 | nil |
| 4014 | ``` | 2044 | ``` |
| 4015 | 2045 | ||
| 4016 | <YueDisplay> | ||
| 4017 | |||
| 4018 | ```yue | ||
| 4019 | findFirstEven = (list) -> | ||
| 4020 | for item in *list | ||
| 4021 | if type(item) == "table" | ||
| 4022 | for sub in *item | ||
| 4023 | if sub % 2 == 0 | ||
| 4024 | return sub | ||
| 4025 | nil | ||
| 4026 | ``` | ||
| 4027 | |||
| 4028 | </YueDisplay> | ||
| 4029 | |||
| 4030 |   唯一的区别在于:你可以将函数的返回值表达式提前写在 `->` 或 `=>` 前,用以指示该函数应隐式返回该表达式的值。这样即使在多层循环或条件判断的场景下,也无需编写尾行悬挂的返回表达式,逻辑结构会更加直观清晰。 | 2046 |   唯一的区别在于:你可以将函数的返回值表达式提前写在 `->` 或 `=>` 前,用以指示该函数应隐式返回该表达式的值。这样即使在多层循环或条件判断的场景下,也无需编写尾行悬挂的返回表达式,逻辑结构会更加直观清晰。 |
| 4031 | 2047 | ||
| 4032 | ## 命名变长参数 | 2048 | ## 命名变长参数 |
| @@ -4055,32 +2071,6 @@ process = (...args) -> | |||
| 4055 | process 1, nil, 3, nil, 5 | 2071 | process 1, nil, 3, nil, 5 |
| 4056 | ``` | 2072 | ``` |
| 4057 | 2073 | ||
| 4058 | <YueDisplay> | ||
| 4059 | |||
| 4060 | ```yue | ||
| 4061 | f = (...t) -> | ||
| 4062 | print "参数个数:", t.n | ||
| 4063 | print "表长度:", #t | ||
| 4064 | for i = 1, t.n | ||
| 4065 | print t[i] | ||
| 4066 | |||
| 4067 | f 1, 2, 3 | ||
| 4068 | f "a", "b", "c", "d" | ||
| 4069 | f! | ||
| 4070 | |||
| 4071 | -- 处理包含 nil 的情况 | ||
| 4072 | process = (...args) -> | ||
| 4073 | sum = 0 | ||
| 4074 | for i = 1, args.n | ||
| 4075 | if args[i] != nil and type(args[i]) == "number" | ||
| 4076 | sum += args[i] | ||
| 4077 | sum | ||
| 4078 | |||
| 4079 | process 1, nil, 3, nil, 5 | ||
| 4080 | ``` | ||
| 4081 | |||
| 4082 | </YueDisplay> | ||
| 4083 | |||
| 4084 | # 空白 | 2074 | # 空白 |
| 4085 | 2075 | ||
| 4086 |   月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 | 2076 |   月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 |
| @@ -4093,14 +2083,6 @@ process 1, nil, 3, nil, 5 | |||
| 4093 | a = 1; b = 2; print a + b | 2083 | a = 1; b = 2; print a + b |
| 4094 | ``` | 2084 | ``` |
| 4095 | 2085 | ||
| 4096 | <YueDisplay> | ||
| 4097 | |||
| 4098 | ```yue | ||
| 4099 | a = 1; b = 2; print a + b | ||
| 4100 | ``` | ||
| 4101 | |||
| 4102 | </YueDisplay> | ||
| 4103 | |||
| 4104 | ## 多行链式调用 | 2086 | ## 多行链式调用 |
| 4105 | 2087 | ||
| 4106 |   你可以使用相同的缩进来编写多行链式函数调用。 | 2088 |   你可以使用相同的缩进来编写多行链式函数调用。 |
| @@ -4114,19 +2096,6 @@ Rx.Observable | |||
| 4114 | \subscribe print | 2096 | \subscribe print |
| 4115 | ``` | 2097 | ``` |
| 4116 | 2098 | ||
| 4117 | <YueDisplay> | ||
| 4118 | |||
| 4119 | ```yue | ||
| 4120 | Rx.Observable | ||
| 4121 | .fromRange 1, 8 | ||
| 4122 | \filter (x) -> x % 2 == 0 | ||
| 4123 | \concat Rx.Observable.of 'who do we appreciate' | ||
| 4124 | \map (value) -> value .. '!' | ||
| 4125 | \subscribe print | ||
| 4126 | ``` | ||
| 4127 | |||
| 4128 | </YueDisplay> | ||
| 4129 | |||
| 4130 | # 注释 | 2099 | # 注释 |
| 4131 | 2100 | ||
| 4132 | ```yuescript | 2101 | ```yuescript |
| @@ -4142,23 +2111,6 @@ str = --[[ | |||
| 4142 | func --[[端口]] 3000, --[[ip]] "192.168.1.1" | 2111 | func --[[端口]] 3000, --[[ip]] "192.168.1.1" |
| 4143 | ``` | 2112 | ``` |
| 4144 | 2113 | ||
| 4145 | <YueDisplay> | ||
| 4146 | |||
| 4147 | ```yue | ||
| 4148 | -- 我是一个注释 | ||
| 4149 | |||
| 4150 | str = --[[ | ||
| 4151 | 这是一个多行注释。 | ||
| 4152 | 没问题。 | ||
| 4153 | ]] strA \ -- 注释 1 | ||
| 4154 | .. strB \ -- 注释 2 | ||
| 4155 | .. strC | ||
| 4156 | |||
| 4157 | func --[[端口]] 3000, --[[ip]] "192.168.1.1" | ||
| 4158 | ``` | ||
| 4159 | |||
| 4160 | </YueDisplay> | ||
| 4161 | |||
| 4162 | # 属性 | 2114 | # 属性 |
| 4163 | 2115 | ||
| 4164 |   月之脚本现在提供了 Lua 5.4 新增的叫做属性的语法支持。在月之脚本编译到的 Lua 目标版本低于 5.4 时,你仍然可以同时使用`const` 和 `close` 的属性声明语法,并获得常量检查和作用域回调的功能。 | 2116 |   月之脚本现在提供了 Lua 5.4 新增的叫做属性的语法支持。在月之脚本编译到的 Lua 目标版本低于 5.4 时,你仍然可以同时使用`const` 和 `close` 的属性声明语法,并获得常量检查和作用域回调的功能。 |
| @@ -4168,15 +2120,6 @@ const a = 123 | |||
| 4168 | close _ = <close>: -> print "超出范围。" | 2120 | close _ = <close>: -> print "超出范围。" |
| 4169 | ``` | 2121 | ``` |
| 4170 | 2122 | ||
| 4171 | <YueDisplay> | ||
| 4172 | |||
| 4173 | ```yue | ||
| 4174 | const a = 123 | ||
| 4175 | close _ = <close>: -> print "超出范围。" | ||
| 4176 | ``` | ||
| 4177 | |||
| 4178 | </YueDisplay> | ||
| 4179 | |||
| 4180 |   你可以对进行解构得到的变量标记为常量。 | 2123 |   你可以对进行解构得到的变量标记为常量。 |
| 4181 | 2124 | ||
| 4182 | ```yuescript | 2125 | ```yuescript |
| @@ -4184,15 +2127,6 @@ const {:a, :b, c, d} = tb | |||
| 4184 | -- a = 1 | 2127 | -- a = 1 |
| 4185 | ``` | 2128 | ``` |
| 4186 | 2129 | ||
| 4187 | <YueDisplay> | ||
| 4188 | |||
| 4189 | ```yue | ||
| 4190 | const {:a, :b, c, d} = tb | ||
| 4191 | -- a = 1 | ||
| 4192 | ``` | ||
| 4193 | |||
| 4194 | </YueDisplay> | ||
| 4195 | |||
| 4196 |   你也可以声明全局变量为常量。 | 2130 |   你也可以声明全局变量为常量。 |
| 4197 | 2131 | ||
| 4198 | ```yuescript | 2132 | ```yuescript |
| @@ -4200,15 +2134,6 @@ global const Constant = 123 | |||
| 4200 | -- Constant = 1 | 2134 | -- Constant = 1 |
| 4201 | ``` | 2135 | ``` |
| 4202 | 2136 | ||
| 4203 | <YueDisplay> | ||
| 4204 | |||
| 4205 | ```yue | ||
| 4206 | global const Constant = 123 | ||
| 4207 | -- Constant = 1 | ||
| 4208 | ``` | ||
| 4209 | |||
| 4210 | </YueDisplay> | ||
| 4211 | |||
| 4212 | # 操作符 | 2137 | # 操作符 |
| 4213 | 2138 | ||
| 4214 |   Lua 的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 | 2139 |   Lua 的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 |
| @@ -4218,15 +2143,6 @@ tb\func! if tb ~= nil | |||
| 4218 | tb::func! if tb != nil | 2143 | tb::func! if tb != nil |
| 4219 | ``` | 2144 | ``` |
| 4220 | 2145 | ||
| 4221 | <YueDisplay> | ||
| 4222 | |||
| 4223 | ```yue | ||
| 4224 | tb\func! if tb ~= nil | ||
| 4225 | tb::func! if tb != nil | ||
| 4226 | ``` | ||
| 4227 | |||
| 4228 | </YueDisplay> | ||
| 4229 | |||
| 4230 | ## 链式比较 | 2146 | ## 链式比较 |
| 4231 | 2147 | ||
| 4232 |   你可以在月之脚本中进行比较表达式的链式书写: | 2148 |   你可以在月之脚本中进行比较表达式的链式书写: |
| @@ -4240,19 +2156,6 @@ print 1 <= a <= 10 | |||
| 4240 | -- 输出:true | 2156 | -- 输出:true |
| 4241 | ``` | 2157 | ``` |
| 4242 | 2158 | ||
| 4243 | <YueDisplay> | ||
| 4244 | |||
| 4245 | ```yue | ||
| 4246 | print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 | ||
| 4247 | -- 输出:true | ||
| 4248 | |||
| 4249 | a = 5 | ||
| 4250 | print 1 <= a <= 10 | ||
| 4251 | -- 输出:true | ||
| 4252 | ``` | ||
| 4253 | |||
| 4254 | </YueDisplay> | ||
| 4255 | |||
| 4256 |   可以注意一下链式比较表达式的求值行为: | 2159 |   可以注意一下链式比较表达式的求值行为: |
| 4257 | 2160 | ||
| 4258 | ```yuescript | 2161 | ```yuescript |
| @@ -4278,33 +2181,6 @@ print v(1) > v(2) <= v(3) | |||
| 4278 | ]] | 2181 | ]] |
| 4279 | ``` | 2182 | ``` |
| 4280 | 2183 | ||
| 4281 | <YueDisplay> | ||
| 4282 | |||
| 4283 | ```yue | ||
| 4284 | v = (x) -> | ||
| 4285 | print x | ||
| 4286 | x | ||
| 4287 | |||
| 4288 | print v(1) < v(2) <= v(3) | ||
| 4289 | --[[ | ||
| 4290 | 输出: | ||
| 4291 | 2 | ||
| 4292 | 1 | ||
| 4293 | 3 | ||
| 4294 | true | ||
| 4295 | ]] | ||
| 4296 | |||
| 4297 | print v(1) > v(2) <= v(3) | ||
| 4298 | --[[ | ||
| 4299 | 输出: | ||
| 4300 | 2 | ||
| 4301 | 1 | ||
| 4302 | false | ||
| 4303 | ]] | ||
| 4304 | ``` | ||
| 4305 | |||
| 4306 | </YueDisplay> | ||
| 4307 | |||
| 4308 |   在上面的例子里,中间的表达式 `v(2)` 仅被计算一次,如果把表达式写成 `v(1) < v(2) and v(2) <= v(3)` 的方式,中间的 `v(2)` 才会被计算两次。在链式比较中,求值的顺序往往是未定义的。所以强烈建议不要在链式比较中使用具有副作用(比如做打印操作)的表达式。如果需要使用有副作用的函数,应明确使用短路 `and` 运算符来做连接。 | 2184 |   在上面的例子里,中间的表达式 `v(2)` 仅被计算一次,如果把表达式写成 `v(1) < v(2) and v(2) <= v(3)` 的方式,中间的 `v(2)` 才会被计算两次。在链式比较中,求值的顺序往往是未定义的。所以强烈建议不要在链式比较中使用具有副作用(比如做打印操作)的表达式。如果需要使用有副作用的函数,应明确使用短路 `and` 运算符来做连接。 |
| 4309 | 2185 | ||
| 4310 | ## 表追加 | 2186 | ## 表追加 |
| @@ -4316,15 +2192,6 @@ tab = [] | |||
| 4316 | tab[] = "Value" | 2192 | tab[] = "Value" |
| 4317 | ``` | 2193 | ``` |
| 4318 | 2194 | ||
| 4319 | <YueDisplay> | ||
| 4320 | |||
| 4321 | ```yue | ||
| 4322 | tab = [] | ||
| 4323 | tab[] = "Value" | ||
| 4324 | ``` | ||
| 4325 | |||
| 4326 | </YueDisplay> | ||
| 4327 | |||
| 4328 |   你还可以使用展开操作符 `...` 来将一个列表中的所有元素追加到另一个列表中: | 2195 |   你还可以使用展开操作符 `...` 来将一个列表中的所有元素追加到另一个列表中: |
| 4329 | 2196 | ||
| 4330 | ```yuescript | 2197 | ```yuescript |
| @@ -4334,17 +2201,6 @@ tbA[] = ...tbB | |||
| 4334 | -- tbA 现在为 [1, 2, 3, 4, 5, 6] | 2201 | -- tbA 现在为 [1, 2, 3, 4, 5, 6] |
| 4335 | ``` | 2202 | ``` |
| 4336 | 2203 | ||
| 4337 | <YueDisplay> | ||
| 4338 | |||
| 4339 | ```yue | ||
| 4340 | tbA = [1, 2, 3] | ||
| 4341 | tbB = [4, 5, 6] | ||
| 4342 | tbA[] = ...tbB | ||
| 4343 | -- tbA 现在为 [1, 2, 3, 4, 5, 6] | ||
| 4344 | ``` | ||
| 4345 | |||
| 4346 | </YueDisplay> | ||
| 4347 | |||
| 4348 | ## 表扩展 | 2204 | ## 表扩展 |
| 4349 | 2205 | ||
| 4350 |   你可以使用前置 `...` 操作符在 Lua 表中插入数组表或哈希表。 | 2206 |   你可以使用前置 `...` 操作符在 Lua 表中插入数组表或哈希表。 |
| @@ -4366,27 +2222,6 @@ b = {4, 5, y: 1} | |||
| 4366 | merge = {...a, ...b} | 2222 | merge = {...a, ...b} |
| 4367 | ``` | 2223 | ``` |
| 4368 | 2224 | ||
| 4369 | <YueDisplay> | ||
| 4370 | |||
| 4371 | ```yue | ||
| 4372 | parts = | ||
| 4373 | * "shoulders" | ||
| 4374 | * "knees" | ||
| 4375 | lyrics = | ||
| 4376 | * "head" | ||
| 4377 | * ...parts | ||
| 4378 | * "and" | ||
| 4379 | * "toes" | ||
| 4380 | |||
| 4381 | copy = {...other} | ||
| 4382 | |||
| 4383 | a = {1, 2, 3, x: 1} | ||
| 4384 | b = {4, 5, y: 1} | ||
| 4385 | merge = {...a, ...b} | ||
| 4386 | ``` | ||
| 4387 | |||
| 4388 | </YueDisplay> | ||
| 4389 | |||
| 4390 | ## 表反向索引 | 2225 | ## 表反向索引 |
| 4391 | 2226 | ||
| 4392 |   你可以使用 **#** 操作符来反向索引表中的元素。 | 2227 |   你可以使用 **#** 操作符来反向索引表中的元素。 |
| @@ -4397,16 +2232,6 @@ second_last = data.items[#-1] | |||
| 4397 | data.items[#] = 1 | 2232 | data.items[#] = 1 |
| 4398 | ``` | 2233 | ``` |
| 4399 | 2234 | ||
| 4400 | <YueDisplay> | ||
| 4401 | |||
| 4402 | ```yue | ||
| 4403 | last = data.items[#] | ||
| 4404 | second_last = data.items[#-1] | ||
| 4405 | data.items[#] = 1 | ||
| 4406 | ``` | ||
| 4407 | |||
| 4408 | </YueDisplay> | ||
| 4409 | |||
| 4410 | ## 元表 | 2235 | ## 元表 |
| 4411 | 2236 | ||
| 4412 |   **<>** 操作符可提供元表操作的快捷方式。 | 2237 |   **<>** 操作符可提供元表操作的快捷方式。 |
| @@ -4431,26 +2256,6 @@ print d.value | |||
| 4431 | close _ = <close>: -> print "超出范围" | 2256 | close _ = <close>: -> print "超出范围" |
| 4432 | ``` | 2257 | ``` |
| 4433 | 2258 | ||
| 4434 | <YueDisplay> | ||
| 4435 | |||
| 4436 | ```yue | ||
| 4437 | mt = {} | ||
| 4438 | add = (right) => <>: mt, value: @value + right.value | ||
| 4439 | mt.__add = add | ||
| 4440 | |||
| 4441 | a = <>: mt, value: 1 | ||
| 4442 | -- 使用与临时变量名相同的字段名,将临时变量赋值给元表 | ||
| 4443 | b = :<add>, value: 2 | ||
| 4444 | c = <add>: mt.__add, value: 3 | ||
| 4445 | |||
| 4446 | d = a + b + c | ||
| 4447 | print d.value | ||
| 4448 | |||
| 4449 | close _ = <close>: -> print "超出范围" | ||
| 4450 | ``` | ||
| 4451 | |||
| 4452 | </YueDisplay> | ||
| 4453 | |||
| 4454 | ### 元表访问 | 2259 | ### 元表访问 |
| 4455 | 2260 | ||
| 4456 |   使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。 | 2261 |   使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。 |
| @@ -4465,19 +2270,6 @@ tb.<> = __index: {item: "hello"} | |||
| 4465 | print tb.item | 2270 | print tb.item |
| 4466 | ``` | 2271 | ``` |
| 4467 | 2272 | ||
| 4468 | <YueDisplay> | ||
| 4469 | |||
| 4470 | ```yue | ||
| 4471 | -- 使用包含字段 "value" 的元表创建 | ||
| 4472 | tb = <"value">: 123 | ||
| 4473 | tb.<index> = tb.<> | ||
| 4474 | print tb.value | ||
| 4475 | tb.<> = __index: {item: "hello"} | ||
| 4476 | print tb.item | ||
| 4477 | ``` | ||
| 4478 | |||
| 4479 | </YueDisplay> | ||
| 4480 | |||
| 4481 | ### 元表解构 | 2273 | ### 元表解构 |
| 4482 | 2274 | ||
| 4483 |   使用被 **<>** 包围的元方法键解构元表。 | 2275 |   使用被 **<>** 包围的元方法键解构元表。 |
| @@ -4487,15 +2279,6 @@ print tb.item | |||
| 4487 | print item, new, close, getter | 2279 | print item, new, close, getter |
| 4488 | ``` | 2280 | ``` |
| 4489 | 2281 | ||
| 4490 | <YueDisplay> | ||
| 4491 | |||
| 4492 | ```yue | ||
| 4493 | {item, :new, :<close>, <index>: getter} = tb | ||
| 4494 | print item, new, close, getter | ||
| 4495 | ``` | ||
| 4496 | |||
| 4497 | </YueDisplay> | ||
| 4498 | |||
| 4499 | ## 存在性 | 2282 | ## 存在性 |
| 4500 | 2283 | ||
| 4501 |   **?** 运算符可以在多种上下文中用来检查存在性。 | 2284 |   **?** 运算符可以在多种上下文中用来检查存在性。 |
| @@ -4515,25 +2298,6 @@ with? io.open "test.txt", "w" | |||
| 4515 | \close! | 2298 | \close! |
| 4516 | ``` | 2299 | ``` |
| 4517 | 2300 | ||
| 4518 | <YueDisplay> | ||
| 4519 | |||
| 4520 | ```yue | ||
| 4521 | func?! | ||
| 4522 | print abc?["你好 世界"]?.xyz | ||
| 4523 | |||
| 4524 | x = tab?.value | ||
| 4525 | len = utf8?.len or string?.len or (o) -> #o | ||
| 4526 | |||
| 4527 | if print and x? | ||
| 4528 | print x | ||
| 4529 | |||
| 4530 | with? io.open "test.txt", "w" | ||
| 4531 | \write "你好" | ||
| 4532 | \close! | ||
| 4533 | ``` | ||
| 4534 | |||
| 4535 | </YueDisplay> | ||
| 4536 | |||
| 4537 | ## 管道 | 2301 | ## 管道 |
| 4538 | 2302 | ||
| 4539 |   与其使用一系列嵌套的函数调用,你还可以考虑使用运算符 **|>** 来传递值。 | 2303 |   与其使用一系列嵌套的函数调用,你还可以考虑使用运算符 **|>** 来传递值。 |
| @@ -4552,24 +2316,6 @@ readFile "example.txt" | |||
| 4552 | 2316 | ||
| 4553 | ``` | 2317 | ``` |
| 4554 | 2318 | ||
| 4555 | <YueDisplay> | ||
| 4556 | |||
| 4557 | ```yue | ||
| 4558 | "你好" |> print | ||
| 4559 | 1 |> print 2 -- 将管道项作为第一个参数插入 | ||
| 4560 | 2 |> print 1, _, 3 -- 带有占位符的管道 | ||
| 4561 | |||
| 4562 | -- 多行的管道表达式 | ||
| 4563 | readFile "example.txt" | ||
| 4564 | |> extract language, {} | ||
| 4565 | |> parse language | ||
| 4566 | |> emit | ||
| 4567 | |> render | ||
| 4568 | |||
| 4569 | ``` | ||
| 4570 | |||
| 4571 | </YueDisplay> | ||
| 4572 | |||
| 4573 | ## 空值合并 | 2319 | ## 空值合并 |
| 4574 | 2320 | ||
| 4575 |   如果其左操作数不是 **nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非 nil 的值,**??** 运算符将不再计算其右操作数。 | 2321 |   如果其左操作数不是 **nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非 nil 的值,**??** 运算符将不再计算其右操作数。 |
| @@ -4582,17 +2328,6 @@ func a ?? {} | |||
| 4582 | a ??= false | 2328 | a ??= false |
| 4583 | ``` | 2329 | ``` |
| 4584 | 2330 | ||
| 4585 | <YueDisplay> | ||
| 4586 | |||
| 4587 | ```yue | ||
| 4588 | local a, b, c, d | ||
| 4589 | a = b ?? c ?? d | ||
| 4590 | func a ?? {} | ||
| 4591 | a ??= false | ||
| 4592 | ``` | ||
| 4593 | |||
| 4594 | </YueDisplay> | ||
| 4595 | |||
| 4596 | ## 隐式对象 | 2331 | ## 隐式对象 |
| 4597 | 2332 | ||
| 4598 |   你可以在表格块内使用符号 **\*** 或是 **-** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。 | 2333 |   你可以在表格块内使用符号 **\*** 或是 **-** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。 |
| @@ -4639,52 +2374,6 @@ tb = | |||
| 4639 | tb: { } | 2374 | tb: { } |
| 4640 | ``` | 2375 | ``` |
| 4641 | 2376 | ||
| 4642 | <YueDisplay> | ||
| 4643 | |||
| 4644 | ```yue | ||
| 4645 | -- 赋值时使用隐式对象 | ||
| 4646 | list = | ||
| 4647 | * 1 | ||
| 4648 | * 2 | ||
| 4649 | * 3 | ||
| 4650 | |||
| 4651 | -- 函数调用时使用隐式对象 | ||
| 4652 | func | ||
| 4653 | * 1 | ||
| 4654 | * 2 | ||
| 4655 | * 3 | ||
| 4656 | |||
| 4657 | -- 返回时使用隐式对象 | ||
| 4658 | f = -> | ||
| 4659 | return | ||
| 4660 | * 1 | ||
| 4661 | * 2 | ||
| 4662 | * 3 | ||
| 4663 | |||
| 4664 | -- 表格时使用隐式对象 | ||
| 4665 | tb = | ||
| 4666 | name: "abc" | ||
| 4667 | |||
| 4668 | values: | ||
| 4669 | - "a" | ||
| 4670 | - "b" | ||
| 4671 | - "c" | ||
| 4672 | |||
| 4673 | objects: | ||
| 4674 | - name: "a" | ||
| 4675 | value: 1 | ||
| 4676 | func: => @value + 1 | ||
| 4677 | tb: | ||
| 4678 | fieldA: 1 | ||
| 4679 | |||
| 4680 | - name: "b" | ||
| 4681 | value: 2 | ||
| 4682 | func: => @value + 2 | ||
| 4683 | tb: { } | ||
| 4684 | ``` | ||
| 4685 | |||
| 4686 | </YueDisplay> | ||
| 4687 | |||
| 4688 | # 字面量 | 2377 | # 字面量 |
| 4689 | 2378 | ||
| 4690 |   Lua 中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和 **nil**。 | 2379 |   Lua 中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和 **nil**。 |
| @@ -4700,19 +2389,6 @@ some_string = "这是一个字符串 | |||
| 4700 | print "我有#{math.random! * 100}%的把握。" | 2389 | print "我有#{math.random! * 100}%的把握。" |
| 4701 | ``` | 2390 | ``` |
| 4702 | 2391 | ||
| 4703 | <YueDisplay> | ||
| 4704 | |||
| 4705 | ```yue | ||
| 4706 | some_string = "这是一个字符串 | ||
| 4707 | 并包括一个换行。" | ||
| 4708 | |||
| 4709 | -- 使用#{}语法可以将表达式插入到字符串字面量中。 | ||
| 4710 | -- 字符串插值只在双引号字符串中可用。 | ||
| 4711 | print "我有#{math.random! * 100}%的把握。" | ||
| 4712 | ``` | ||
| 4713 | |||
| 4714 | </YueDisplay> | ||
| 4715 | |||
| 4716 | ## 数字字面量 | 2392 | ## 数字字面量 |
| 4717 | 2393 | ||
| 4718 |   你可以在数字字面量中使用下划线来增加可读性。 | 2394 |   你可以在数字字面量中使用下划线来增加可读性。 |
| @@ -4723,16 +2399,6 @@ hex = 0xEF_BB_BF | |||
| 4723 | binary = 0B10011 | 2399 | binary = 0B10011 |
| 4724 | ``` | 2400 | ``` |
| 4725 | 2401 | ||
| 4726 | <YueDisplay> | ||
| 4727 | |||
| 4728 | ```yue | ||
| 4729 | integer = 1_000_000 | ||
| 4730 | hex = 0xEF_BB_BF | ||
| 4731 | binary = 0B10011 | ||
| 4732 | ``` | ||
| 4733 | |||
| 4734 | </YueDisplay> | ||
| 4735 | |||
| 4736 | ## YAML 风格字符串 | 2402 | ## YAML 风格字符串 |
| 4737 | 2403 | ||
| 4738 |   使用 `|` 前缀标记一个多行 YAML 风格字符串: | 2404 |   使用 `|` 前缀标记一个多行 YAML 风格字符串: |
| @@ -4745,18 +2411,6 @@ str = | | |||
| 4745 | - #{expr} | 2411 | - #{expr} |
| 4746 | ``` | 2412 | ``` |
| 4747 | 2413 | ||
| 4748 | <YueDisplay> | ||
| 4749 | |||
| 4750 | ```yue | ||
| 4751 | str = | | ||
| 4752 | key: value | ||
| 4753 | list: | ||
| 4754 | - item1 | ||
| 4755 | - #{expr} | ||
| 4756 | ``` | ||
| 4757 | |||
| 4758 | </YueDisplay> | ||
| 4759 | |||
| 4760 |   其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。 | 2414 |   其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。 |
| 4761 | 2415 | ||
| 4762 |   YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。 | 2416 |   YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。 |
| @@ -4769,18 +2423,6 @@ fn = -> | |||
| 4769 | return str | 2423 | return str |
| 4770 | ``` | 2424 | ``` |
| 4771 | 2425 | ||
| 4772 | <YueDisplay> | ||
| 4773 | |||
| 4774 | ```yue | ||
| 4775 | fn = -> | ||
| 4776 | str = | | ||
| 4777 | foo: | ||
| 4778 | bar: baz | ||
| 4779 | return str | ||
| 4780 | ``` | ||
| 4781 | |||
| 4782 | </YueDisplay> | ||
| 4783 | |||
| 4784 |   输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。 | 2426 |   输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。 |
| 4785 | 2427 | ||
| 4786 |   支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义: | 2428 |   支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义: |
| @@ -4791,16 +2433,6 @@ str = | | |||
| 4791 | note: 'He said: "#{Hello}!"' | 2433 | note: 'He said: "#{Hello}!"' |
| 4792 | ``` | 2434 | ``` |
| 4793 | 2435 | ||
| 4794 | <YueDisplay> | ||
| 4795 | |||
| 4796 | ```yue | ||
| 4797 | str = | | ||
| 4798 | path: "C:\Program Files\App" | ||
| 4799 | note: 'He said: "#{Hello}!"' | ||
| 4800 | ``` | ||
| 4801 | |||
| 4802 | </YueDisplay> | ||
| 4803 | |||
| 4804 | # 模块 | 2436 | # 模块 |
| 4805 | 2437 | ||
| 4806 | ## 导入 | 2438 | ## 导入 |
| @@ -4832,35 +2464,6 @@ do | |||
| 4832 | import "export" as {one, two, Something:{umm:{ch}}} | 2464 | import "export" as {one, two, Something:{umm:{ch}}} |
| 4833 | ``` | 2465 | ``` |
| 4834 | 2466 | ||
| 4835 | <YueDisplay> | ||
| 4836 | |||
| 4837 | ```yue | ||
| 4838 | -- 用作表解构 | ||
| 4839 | do | ||
| 4840 | import insert, concat from table | ||
| 4841 | -- 当给 insert, concat 变量赋值时,编译器会报告错误 | ||
| 4842 | import C, Ct, Cmt from require "lpeg" | ||
| 4843 | -- 快捷写法引入模块的子项 | ||
| 4844 | import x, y, z from 'mymodule' | ||
| 4845 | -- 使用Python风格的导入 | ||
| 4846 | from 'module' import a, b, c | ||
| 4847 | |||
| 4848 | -- 快捷地导入一个模块 | ||
| 4849 | do | ||
| 4850 | import 'module' | ||
| 4851 | import 'module_x' | ||
| 4852 | import "d-a-s-h-e-s" | ||
| 4853 | import "module.part" | ||
| 4854 | |||
| 4855 | -- 导入模块后起一个别名使用,或是进行导入模块表的解构 | ||
| 4856 | do | ||
| 4857 | import "player" as PlayerModule | ||
| 4858 | import "lpeg" as :C, :Ct, :Cmt | ||
| 4859 | import "export" as {one, two, Something:{umm:{ch}}} | ||
| 4860 | ``` | ||
| 4861 | |||
| 4862 | </YueDisplay> | ||
| 4863 | |||
| 4864 | ## 导入全局变量 | 2467 | ## 导入全局变量 |
| 4865 | 2468 | ||
| 4866 |   你可以使用 `import` 将指定的全局变量导入到本地变量中。当导入一系列对全局变量的链式访问时,最后一个访问的字段将被赋值给本地变量。 | 2469 |   你可以使用 `import` 将指定的全局变量导入到本地变量中。当导入一系列对全局变量的链式访问时,最后一个访问的字段将被赋值给本地变量。 |
| @@ -4872,17 +2475,6 @@ do | |||
| 4872 | print concat ["a", tostring 1] | 2475 | print concat ["a", tostring 1] |
| 4873 | ``` | 2476 | ``` |
| 4874 | 2477 | ||
| 4875 | <YueDisplay> | ||
| 4876 | |||
| 4877 | ```yue | ||
| 4878 | do | ||
| 4879 | import tostring | ||
| 4880 | import table.concat | ||
| 4881 | print concat ["a", tostring 1] | ||
| 4882 | ``` | ||
| 4883 | |||
| 4884 | </YueDisplay> | ||
| 4885 | |||
| 4886 | ### 自动全局变量导入 | 2478 | ### 自动全局变量导入 |
| 4887 | 2479 | ||
| 4888 |   在一个代码块的顶部写 `import global`,会将当前作用域中尚未显式声明或赋值过的变量名,自动导入为本地常量,并在该语句的位置绑定到同名的全局变量。 | 2480 |   在一个代码块的顶部写 `import global`,会将当前作用域中尚未显式声明或赋值过的变量名,自动导入为本地常量,并在该语句的位置绑定到同名的全局变量。 |
| @@ -4904,25 +2496,6 @@ do | |||
| 4904 | FLAG = 123 | 2496 | FLAG = 123 |
| 4905 | ``` | 2497 | ``` |
| 4906 | 2498 | ||
| 4907 | <YueDisplay> | ||
| 4908 | |||
| 4909 | ```yue | ||
| 4910 | do | ||
| 4911 | import global | ||
| 4912 | print "hello" | ||
| 4913 | math.random 3 | ||
| 4914 | -- print = nil -- 报错:自动导入的全局变量是常量 | ||
| 4915 | |||
| 4916 | do | ||
| 4917 | -- 被显式声明为全局的变量不会被自动导入 | ||
| 4918 | import global | ||
| 4919 | global FLAG | ||
| 4920 | print FLAG | ||
| 4921 | FLAG = 123 | ||
| 4922 | ``` | ||
| 4923 | |||
| 4924 | </YueDisplay> | ||
| 4925 | |||
| 4926 | ## 导出 | 2499 | ## 导出 |
| 4927 | 2500 | ||
| 4928 |   导出语句提供了一种简洁的方式来定义当前的模块。 | 2501 |   导出语句提供了一种简洁的方式来定义当前的模块。 |
| @@ -4947,26 +2520,6 @@ export class Something | |||
| 4947 | umm: "cool" | 2520 | umm: "cool" |
| 4948 | ``` | 2521 | ``` |
| 4949 | 2522 | ||
| 4950 | <YueDisplay> | ||
| 4951 | |||
| 4952 | ```yue | ||
| 4953 | export a, b, c = 1, 2, 3 | ||
| 4954 | export cool = "cat" | ||
| 4955 | |||
| 4956 | export What = if this | ||
| 4957 | "abc" | ||
| 4958 | else | ||
| 4959 | "def" | ||
| 4960 | |||
| 4961 | export y = -> | ||
| 4962 | hallo = 3434 | ||
| 4963 | |||
| 4964 | export class Something | ||
| 4965 | umm: "cool" | ||
| 4966 | ``` | ||
| 4967 | |||
| 4968 | </YueDisplay> | ||
| 4969 | |||
| 4970 |   使用解构进行命名导出。 | 2523 |   使用解构进行命名导出。 |
| 4971 | 2524 | ||
| 4972 | ```yuescript | 2525 | ```yuescript |
| @@ -4974,15 +2527,6 @@ export :loadstring, to_lua: tolua = yue | |||
| 4974 | export {itemA: {:fieldA = '默认值'}} = tb | 2527 | export {itemA: {:fieldA = '默认值'}} = tb |
| 4975 | ``` | 2528 | ``` |
| 4976 | 2529 | ||
| 4977 | <YueDisplay> | ||
| 4978 | |||
| 4979 | ```yue | ||
| 4980 | export :loadstring, to_lua: tolua = yue | ||
| 4981 | export {itemA: {:fieldA = '默认值'}} = tb | ||
| 4982 | ``` | ||
| 4983 | |||
| 4984 | </YueDisplay> | ||
| 4985 | |||
| 4986 |   从模块导出命名项目时,可以不用创建局部变量。 | 2530 |   从模块导出命名项目时,可以不用创建局部变量。 |
| 4987 | 2531 | ||
| 4988 | ```yuescript | 2532 | ```yuescript |
| @@ -4991,16 +2535,6 @@ export.<index> = items | |||
| 4991 | export["a-b-c"] = 123 | 2535 | export["a-b-c"] = 123 |
| 4992 | ``` | 2536 | ``` |
| 4993 | 2537 | ||
| 4994 | <YueDisplay> | ||
| 4995 | |||
| 4996 | ```yue | ||
| 4997 | export.itemA = tb | ||
| 4998 | export.<index> = items | ||
| 4999 | export["a-b-c"] = 123 | ||
| 5000 | ``` | ||
| 5001 | |||
| 5002 | </YueDisplay> | ||
| 5003 | |||
| 5004 | ### 未命名导出 | 2538 | ### 未命名导出 |
| 5005 | 2539 | ||
| 5006 |   未命名导出会将要导出的目标项目添加到导出表的数组部分。 | 2540 |   未命名导出会将要导出的目标项目添加到导出表的数组部分。 |
| @@ -5018,23 +2552,6 @@ export with tmp | |||
| 5018 | j = 2000 | 2552 | j = 2000 |
| 5019 | ``` | 2553 | ``` |
| 5020 | 2554 | ||
| 5021 | <YueDisplay> | ||
| 5022 | |||
| 5023 | ```yue | ||
| 5024 | d, e, f = 3, 2, 1 | ||
| 5025 | export d, e, f | ||
| 5026 | |||
| 5027 | export if this | ||
| 5028 | 123 | ||
| 5029 | else | ||
| 5030 | 456 | ||
| 5031 | |||
| 5032 | export with tmp | ||
| 5033 | j = 2000 | ||
| 5034 | ``` | ||
| 5035 | |||
| 5036 | </YueDisplay> | ||
| 5037 | |||
| 5038 | ### 默认导出 | 2555 | ### 默认导出 |
| 5039 | 2556 | ||
| 5040 |   在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。 | 2557 |   在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。 |
| @@ -5045,16 +2562,6 @@ export default -> | |||
| 5045 | 123 | 2562 | 123 |
| 5046 | ``` | 2563 | ``` |
| 5047 | 2564 | ||
| 5048 | <YueDisplay> | ||
| 5049 | |||
| 5050 | ```yue | ||
| 5051 | export default -> | ||
| 5052 | print "你好" | ||
| 5053 | 123 | ||
| 5054 | ``` | ||
| 5055 | |||
| 5056 | </YueDisplay> | ||
| 5057 | |||
| 5058 | # MIT 许可证 | 2565 | # MIT 许可证 |
| 5059 | 2566 | ||
| 5060 | 版权 (c) 2017-2026 李瑾 \<dragon-fly@qq.com\> | 2567 | 版权 (c) 2017-2026 李瑾 \<dragon-fly@qq.com\> |
