aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2023-11-28 11:15:19 +0800
committerLi Jin <dragon-fly@qq.com>2023-11-28 11:15:19 +0800
commite89744c1a39bb3318b68e93265a68fd807e56a48 (patch)
treefb173a4d823fab346672ae674f26cc9c5652ec3a /doc
parent1288432c7cb5db2aff4fd6cf46ee8d8442913046 (diff)
downloadyuescript-e89744c1a39bb3318b68e93265a68fd807e56a48.tar.gz
yuescript-e89744c1a39bb3318b68e93265a68fd807e56a48.tar.bz2
yuescript-e89744c1a39bb3318b68e93265a68fd807e56a48.zip
update Chinese doc.
Diffstat (limited to 'doc')
-rwxr-xr-xdoc/docs/zh/doc/README.md83
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
1516func_a! 1516func_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
2006doubled = [item * 2 for item in *items] 2006doubled = [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
2085numbers = [1, 2, 3, 4] 2085numbers = [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
2178for item in *items[2, 4] 2178for 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
2724inv = Inventory! 2722inv = Inventory!
@@ -2726,6 +2724,7 @@ inv\add_item "t-shirt"
2726inv\add_item "pants" 2724inv\add_item "pants"
2727``` 2725```
2728<YueDisplay> 2726<YueDisplay>
2727
2729<pre> 2728<pre>
2730inv = Inventory! 2729inv = Inventory!
2731inv\add_item "t-shirt" 2730inv\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
2743class Person 2742class 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
2818class Shelf 2818class 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
2851class MyClass extends ParentClass 2849class 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
2913print BackPack.__name -- 打印 Backpack 2910print 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
2953class Counter 2950class 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
3158MyIndex = __index: var: 1 3155MyIndex = __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
3365my_object = { 3362my_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的变量作用域可以在减少我们编写的代码的复杂性上提供很大的帮助,但随着代码量的增加,事情可能会变得难以管理。考虑以下代码片段: 3402Lua 的变量作用域是降低代码复杂度的重要工具。然而,随着代码量的增加,维护这些变量可能变得更加困难。比如,看看下面的代码片段:
3406 3403
3407```moonscript 3404```moonscript
3408i = 100 3405i = 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
3444using语句让我们能够做到这一点。using nil确保在一个函数里的赋值中不会覆盖外部的变量。我们只要把using子句放在函数的参数列表之后,或者当函数没有参数,就直接放在括号里。 3441`using` 语句就是为此而生。`using nil` 确保函数内部的赋值不会意外地影响到外部作用域的变量。我们只需将 `using` 子句放在函数的参数列表之后;若函数没有参数,则直接放在括号内即可。
3445 3442
3446```moonscript 3443```moonscript
3447i = 100 3444i = 100