diff options
author | Li Jin <dragon-fly@qq.com> | 2023-11-28 11:15:19 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2023-11-28 11:15:19 +0800 |
commit | e89744c1a39bb3318b68e93265a68fd807e56a48 (patch) | |
tree | fb173a4d823fab346672ae674f26cc9c5652ec3a /doc | |
parent | 1288432c7cb5db2aff4fd6cf46ee8d8442913046 (diff) | |
download | yuescript-e89744c1a39bb3318b68e93265a68fd807e56a48.tar.gz yuescript-e89744c1a39bb3318b68e93265a68fd807e56a48.tar.bz2 yuescript-e89744c1a39bb3318b68e93265a68fd807e56a48.zip |
update Chinese doc.
Diffstat (limited to 'doc')
-rwxr-xr-x | doc/docs/zh/doc/README.md | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md index 69f5e68..7e17b80 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
@@ -1150,7 +1150,7 @@ print first, second, color | |||
1150 | </pre> | 1150 | </pre> |
1151 | </YueDisplay> | 1151 | </YueDisplay> |
1152 | 1152 | ||
1153 | 有时候我们会需要从Lua表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用**:**前缀操作符: | 1153 | 有时候我们会需要从Lua表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: |
1154 | 1154 | ||
1155 | ```moonscript | 1155 | ```moonscript |
1156 | {:concat, :insert} = table | 1156 | {:concat, :insert} = table |
@@ -1510,7 +1510,7 @@ func_b = -> | |||
1510 | </pre> | 1510 | </pre> |
1511 | </YueDisplay> | 1511 | </YueDisplay> |
1512 | 1512 | ||
1513 | 如果一个函数没有参数,可以使用**!**操作符调用它,而不是空括号。使用**!**调用没有参数的函数是推荐的写法。 | 1513 | 如果一个函数没有参数,可以使用 **\!** 操作符调用它,而不是空括号。使用 **\!** 调用没有参数的函数是推荐的写法。 |
1514 | 1514 | ||
1515 | ```moonscript | 1515 | ```moonscript |
1516 | func_a! | 1516 | func_a! |
@@ -2000,7 +2000,7 @@ slice = [item for i, item in iter when i > 1 and i < 3] | |||
2000 | </pre> | 2000 | </pre> |
2001 | </YueDisplay> | 2001 | </YueDisplay> |
2002 | 2002 | ||
2003 | 因为我们常常需要迭代数值索引表的值,所以引入了**\***操作符来做语法简化。doubled示例可以重写为: | 2003 | 因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled示例可以重写为: |
2004 | 2004 | ||
2005 | ```moonscript | 2005 | ```moonscript |
2006 | doubled = [item * 2 for item in *items] | 2006 | doubled = [item * 2 for item in *items] |
@@ -2079,7 +2079,7 @@ no_color = {k, v for k, v in pairs thing when k != "color"} | |||
2079 | </pre> | 2079 | </pre> |
2080 | </YueDisplay> | 2080 | </YueDisplay> |
2081 | 2081 | ||
2082 | **\***操作符在表格推导式中能使用。在下面的例子里,我们为几个数字创建了一个平方根查找表。 | 2082 | **\*** 操作符在表格推导式中能使用。在下面的例子里,我们为几个数字创建了一个平方根查找表。 |
2083 | 2083 | ||
2084 | ```moonscript | 2084 | ```moonscript |
2085 | numbers = [1, 2, 3, 4] | 2085 | numbers = [1, 2, 3, 4] |
@@ -2172,7 +2172,7 @@ for key, value in pairs object | |||
2172 | </pre> | 2172 | </pre> |
2173 | </YueDisplay> | 2173 | </YueDisplay> |
2174 | 2174 | ||
2175 | 可以使用切片和**\***操作符,就像在列表推导中一样: | 2175 | 可以使用切片和 **\*** 操作符,就像在列表推导中一样: |
2176 | 2176 | ||
2177 | ```moonscript | 2177 | ```moonscript |
2178 | for item in *items[2, 4] | 2178 | for item in *items[2, 4] |
@@ -2710,15 +2710,13 @@ class Inventory | |||
2710 | </pre> | 2710 | </pre> |
2711 | </YueDisplay> | 2711 | </YueDisplay> |
2712 | 2712 | ||
2713 | 月之脚本面向对象的写法是使用类的声明语句,然后跟一个Lua表格字面量的声明来声明一个类,并在表格定义中列出所有的方法和属性。 | 2713 | 在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合Lua表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为“new”的成员扮演了一个重要的角色,是作为构造函数来使用。 |
2714 | 2714 | ||
2715 | 键名为new的成员在这里很特殊,因为它会被用作构造函数。 | 2715 | 值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为“self”的参数。 |
2716 | 2716 | ||
2717 | 注意类中的所有方法都使用了粗箭头函数语法。在调用类的实例上的方法时,实例本身会作为第一个参数传入。所以粗箭头的函数负责创建一个self参数。 | 2717 | 此外,“@”前缀在变量名上起到了简化作用,代表“self”。例如,`@items` 就等同于 `self.items`。 |
2718 | 2718 | ||
2719 | 变量名上的@前缀是self的简写。@items会变为self.items。 | 2719 | 为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。 |
2720 | |||
2721 | 在创建类的实例时,可以通过把类的名称作为函数进行调用,并获得新的实例。 | ||
2722 | 2720 | ||
2723 | ```moonscript | 2721 | ```moonscript |
2724 | inv = Inventory! | 2722 | inv = Inventory! |
@@ -2726,6 +2724,7 @@ inv\add_item "t-shirt" | |||
2726 | inv\add_item "pants" | 2724 | inv\add_item "pants" |
2727 | ``` | 2725 | ``` |
2728 | <YueDisplay> | 2726 | <YueDisplay> |
2727 | |||
2729 | <pre> | 2728 | <pre> |
2730 | inv = Inventory! | 2729 | inv = Inventory! |
2731 | inv\add_item "t-shirt" | 2730 | inv\add_item "t-shirt" |
@@ -2733,11 +2732,11 @@ inv\add_item "pants" | |||
2733 | </pre> | 2732 | </pre> |
2734 | </YueDisplay> | 2733 | </YueDisplay> |
2735 | 2734 | ||
2736 | 因为需要将类的实例传入到它们被调用的方法,所以使用了\操作符。 | 2735 | 在月之脚本的类中,由于需要将类的实例作为参数传入到调用的方法中,因此使用了 **\\** 操作符做类的成员函数调用。 |
2737 | 2736 | ||
2738 | 类的所有属性在实例之间是共享的。对于函数来说一般没有问题,但是对于其他类型的属性,可能会出现不希望的结果。 | 2737 | 需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 |
2739 | 2738 | ||
2740 | 比如下面的例子,clothes属性在所有实例之间是共享的,所以在一个实例中对它的修改会影响到另一个实例: | 2739 | 例如,在下面的示例中,clothes属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。 |
2741 | 2740 | ||
2742 | ```moonscript | 2741 | ```moonscript |
2743 | class Person | 2742 | class Person |
@@ -2808,11 +2807,12 @@ class BackPack extends Inventory | |||
2808 | </pre> | 2807 | </pre> |
2809 | </YueDisplay> | 2808 | </YueDisplay> |
2810 | 2809 | ||
2811 | 这里我们扩展了Inventory类,并限制了它可以携带的物品数量。 | ||
2812 | 2810 | ||
2813 | 在这个例子中,我们没有在子类上定义构造函数,所以当我们创建一个新实例时,会调用父类的构造函数。如果我们定义了构造函数,那么我们可以使用super方法来调用父类的构造函数。 | 2811 | 在这一部分,我们对月之脚本中的`Inventory`类进行了扩展,加入了对可以携带物品数量的限制。 |
2814 | 2812 | ||
2815 | 每当一个类从另一个类继承时,它会通过调用父类上的`__inherited`方法(如果存在)向父类发送消息。该函数接收两个参数,被继承的类和子类。 | 2813 | 在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用`super`方法来调用并执行父类的构造函数。 |
2814 | |||
2815 | 此外,当一个类继承自另一个类时,它会尝试调用父类上的`__inherited`方法(如果这个方法存在的话),以此来向父类发送通知。这个`__inherited`函数接受两个参数:被继承的父类和继承的子类。 | ||
2816 | 2816 | ||
2817 | ```moonscript | 2817 | ```moonscript |
2818 | class Shelf | 2818 | class Shelf |
@@ -2835,17 +2835,15 @@ class Cupboard extends Shelf | |||
2835 | 2835 | ||
2836 | ### super 关键字 | 2836 | ### super 关键字 |
2837 | 2837 | ||
2838 | **super** 是一个特殊的关键字,可以用两种不同的方式使用:它可以被视为一个对象,或者可以像函数一样被调用。它只在类的内部出现时有特殊功能。 | 2838 | `super`是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 |
2839 | |||
2840 | 当作为函数调用时,它会调用父类中同名的函数。当前的 self 会自动作为第一个参数进行传递。(如上面的继承示例所示) | ||
2841 | 2839 | ||
2842 | 当 super 被用作普通值时,它是对父类对象的引用。 | 2840 | 当`super`被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的`self`会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。 |
2843 | 2841 | ||
2844 | 它可以像访问任何普通对象一样来检索父类中可能被子类覆盖的值。 | 2842 | 在将`super`当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。 |
2845 | 2843 | ||
2846 | 当使用 \ 调用操作符与 super 一起使用时,self 会被插入为第一个参数,而不是 super 本身的值。当使用 . 来检索函数时,会返回父类中的原始函数。 | 2844 | 此外,当使用`\`操作符与`super`一起使用时,`self`将被插入为第一个参数,而不是使用`super`本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。 |
2847 | 2845 | ||
2848 | 是使用 super 的几同方式的示例: | 2846 | 下面是些用`super`的不同方法的示例: |
2849 | 2847 | ||
2850 | ```moonscript | 2848 | ```moonscript |
2851 | class MyClass extends ParentClass | 2849 | class MyClass extends ParentClass |
@@ -2895,19 +2893,18 @@ print BackPack.size -- 打印 10 | |||
2895 | 2893 | ||
2896 | ### 类对象 | 2894 | ### 类对象 |
2897 | 2895 | ||
2898 | 当我们使用类的定义语句时,我们创建的是类对象。类对象存储在与类同名的变量中。 | ||
2899 | 2896 | ||
2900 | 类对象可以像函数一样被调用,以创建新的实例。这就是我们在上面的例子中如何创建类的实例的。 | 2897 | 在月之脚本中,当我们编写类的定义语句时,实际上是在创建一个类对象。这个类对象被保存在一个与该类同名的变量中。 |
2901 | 2898 | ||
2902 | 一个类由两个表组成。类表本身和基表。基表用作所有实例的元表。在类声明中列出的所有属性都会被放在基表中。 | 2899 | 类对象具有函数的特性,可以被调用来创建新的实例。这正是我们在之前示例中所展示的创建类实例的方式。 |
2903 | 2900 | ||
2904 | 如果类对象的元表中不存在属性,它会从基表中读取属性。这意味着我们可以直接从类中访问函数和属性。 | 2901 | 一个类由两个表构成:类表本身和一个基表。基表作为所有实例的元表。在类声明中列出的所有属性都存放在基表中。 |
2905 | 2902 | ||
2906 | 重要的是要注意,赋值给类对象并不会赋值给基表,所以这不是向实例添加新方法的有效方式。相反,必须明确地更改基表。参见下面的 \_\_base 字段。 | 2903 | 如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。 |
2907 | 2904 | ||
2908 | 类对象有几个特殊的属性: | 2905 | 需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的“__base”字段。 |
2909 | 2906 | ||
2910 | 当它被声明时,类的名称存储为类对象的 \_\_name 字段中的字符串。 | 2907 | 此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的“__name”字段中。 |
2911 | 2908 | ||
2912 | ```moonscript | 2909 | ```moonscript |
2913 | print BackPack.__name -- 打印 Backpack | 2910 | print BackPack.__name -- 打印 Backpack |
@@ -2918,9 +2915,9 @@ print BackPack.__name -- 打印 Backpack | |||
2918 | </pre> | 2915 | </pre> |
2919 | </YueDisplay> | 2916 | </YueDisplay> |
2920 | 2917 | ||
2921 | 基对象存储在 \_\_base 中。我们可以修改这个表,为已经创建的实例和尚未创建的实例添加功能。 | 2918 | 基础对象被保存在一个名为 `__base` 的特殊表中。我们可以编辑这个表,以便为那些已经创建出来的实例和还未创建的实例增加新的功能。 |
2922 | 2919 | ||
2923 | 如果类从其他类扩展,父类对象存储在 \_\_parent 中。 | 2920 | 另外,如果一个类是从另一个类派生而来的,那么其父类对象则会被存储在名为 `__parent` 的地方。这种机制允许在类之间实现继承和功能扩展。 |
2924 | 2921 | ||
2925 | ### 类变量 | 2922 | ### 类变量 |
2926 | 2923 | ||
@@ -2947,7 +2944,7 @@ assert Things().some_func == nil | |||
2947 | </pre> | 2944 | </pre> |
2948 | </YueDisplay> | 2945 | </YueDisplay> |
2949 | 2946 | ||
2950 | 在表达式中,我们可以使用 @@ 来访问存储在 self.__class 中的值。因此,@@hello 是 self.__class.hello 的简写。 | 2947 | 在表达式中,我们可以使用 @@ 来访问存储在 `self.__class` 中的值。因此,`@@hello` 是 `self.__class.hello` 的简写。 |
2951 | 2948 | ||
2952 | ```moonscript | 2949 | ```moonscript |
2953 | class Counter | 2950 | class Counter |
@@ -3152,7 +3149,7 @@ x = class | |||
3152 | 3149 | ||
3153 | ### 类混合 | 3150 | ### 类混合 |
3154 | 3151 | ||
3155 | 您可以使用关键字 `using` 进行类混合,从一个普通表或预定义的类对象中复制函数到您的新类中。当使用普通表进行混合时,您可以将比如类的索引方法(元方法 `__index`)重写为您的自定义实现。当混合使用的目标是一个类对象时,类对象的元方法不会被复制到新的类中。 | 3152 | 您可以通过使用 `using` 关键字来实现类混合。这意味着您可以从一个普通 Lua 表格或已定义的类对象中,复制函数到您创建的新类中。当您使用普通 Lua 表格进行类混合时,您有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当您从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 |
3156 | 3153 | ||
3157 | ```moonscript | 3154 | ```moonscript |
3158 | MyIndex = __index: var: 1 | 3155 | MyIndex = __index: var: 1 |
@@ -3355,11 +3352,11 @@ tbl = { | |||
3355 | 3352 | ||
3356 | ## 函数存根 | 3353 | ## 函数存根 |
3357 | 3354 | ||
3358 | 将对象的函数作为值传递是很常见的,例如,将实例方法传递给函数作为回调。如果函数期望它操作的对象作为第一个参数,那么您必须以某种方式将该对象与函数捆绑在一起,以便可以正确地调用它。 | 3355 | 在编程中,将对象的方法作为函数类型的值进行传递是一种常见做法,尤其是在将实例方法作为回调函数传递给其他函数的情形中。当目标函数需要将该对象作为其第一个参数时,我们需要找到一种方式将对象和函数绑定在一起,以便能够正确地调用该函数。 |
3359 | 3356 | ||
3360 | 函数存根语法是创建一个新的闭包函数的简写,该函数将对象和函数都捆绑在一起。这个新函数在对象的正确上下文中调用被包装的函数。 | 3357 | 函数存根(stub)语法提供了一种便捷的方法来创建一个新的闭包函数,这个函数将对象和原函数绑定在一起。这样,当调用这个新创建的函数时,它会在正确的对象上下文中执行原有的函数。 |
3361 | 3358 | ||
3362 | 其语法与使用\操作符调用实例方法相同,但不用在后面接着提供参数列表。 | 3359 | 这种语法类似于使用 \ 操作符调用实例方法的方式,区别在于,这里不需要在 \ 操作符后面附加参数列表。 |
3363 | 3360 | ||
3364 | ```moonscript | 3361 | ```moonscript |
3365 | my_object = { | 3362 | my_object = { |
@@ -3400,9 +3397,9 @@ run_callback my_object\write | |||
3400 | </pre> | 3397 | </pre> |
3401 | </YueDisplay> | 3398 | </YueDisplay> |
3402 | 3399 | ||
3403 | ## using 语句:免破坏性的赋值 | 3400 | ## 使用 using 语句:破坏性赋值 |
3404 | 3401 | ||
3405 | 虽然Lua的变量作用域可以在减少我们编写的代码的复杂性上提供很大的帮助,但随着代码量的增加,事情可能会变得难以管理。考虑以下代码片段: | 3402 | Lua 的变量作用域是降低代码复杂度的重要工具。然而,随着代码量的增加,维护这些变量可能变得更加困难。比如,看看下面的代码片段: |
3406 | 3403 | ||
3407 | ```moonscript | 3404 | ```moonscript |
3408 | i = 100 | 3405 | i = 100 |
@@ -3437,11 +3434,11 @@ print i -- 将打印 0 | |||
3437 | </pre> | 3434 | </pre> |
3438 | </YueDisplay> | 3435 | </YueDisplay> |
3439 | 3436 | ||
3440 | 在my_func中,我们错误地覆盖了i的值。在例子中的这个问题很明显,但考虑一个大的或外部的代码库,会很容易不清楚之前已经声明了哪些名称。 | 3437 | 在 `my_func` 中,我们不小心覆盖了变量 `i` 的值。虽然在这个例子中这个问题很明显,但在一个庞大的或者是由多人共同维护的代码库中,很难追踪每个变量的声明情况。 |
3441 | 3438 | ||
3442 | 如果能指定我们只打算更改的封闭作用域中的变量,并防止我们意外地更改其他作用域的同名变量,那将会很有帮助。 | 3439 | 如果我们可以明确指出哪些变量是我们想在当前作用域内修改的,并且防止我们不小心更改了其他作用域中同名的变量,那将大有裨益。 |
3443 | 3440 | ||
3444 | using语句让我们能够做到这一点。using nil确保在一个函数里的赋值中不会覆盖外部的变量。我们只要把using子句放在函数的参数列表之后,或者当函数没有参数,就直接放在括号里。 | 3441 | `using` 语句就是为此而生。`using nil` 确保函数内部的赋值不会意外地影响到外部作用域的变量。我们只需将 `using` 子句放在函数的参数列表之后;若函数没有参数,则直接放在括号内即可。 |
3445 | 3442 | ||
3446 | ```moonscript | 3443 | ```moonscript |
3447 | i = 100 | 3444 | i = 100 |