From f74d6ca34bf46b29912f683d86ec1c651d33b3a9 Mon Sep 17 00:00:00 2001 From: Tatooi Noyo Date: Sun, 23 Jun 2024 21:50:46 +0800 Subject: [PATCH 01/13] Update Manuals for Control Structures --- src/tutorials/lang/Manuals.md | 75 ++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index 4d071d3..0196cc8 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -71,7 +71,8 @@ Nix 只会将自动处理后的字符串当作输入,而不是原始字符串 ##### URI -为了书写简便, [RFC 2396](https://www.ietf.org/rfc/rfc2396.txt) 规定了对于 URI 可以不使用引号闭合: +为了书写简便, [RFC 2396](https://www.ietf.org/rfc/rfc2396.txt) 规定了对于 URI +可以不使用引号闭合: ```nix UriWithoutQuotes = http://example.org/foo.tar.bz2 @@ -84,7 +85,8 @@ UriWithQuotes = "http://example.org/foo.tar.bz2" 数字被分为浮点型(比如 `.114514`)与整型(比如 `2233`)。 -数字是类型兼容的:纯整数运算总是返回整数,而任何涉及至少一个浮点数的运算都会返回一个浮点数。 +数字是类型兼容的:纯整数运算总是返回整数,而任何涉及至少一个浮点数的运算都会返回 +一个浮点数。 #### 路径 @@ -124,7 +126,8 @@ UriWithQuotes = "http://example.org/foo.tar.bz2" 属性集是用大括号括起来的名称与值对(称为属性)的集合。 -属性名可以是标识符或字符串。标识符必须以字母或下划线开头,可以包含字母、数字、下划线、撇号(`'`)或连接符(`-`)。 +属性名可以是标识符或字符串。标识符必须以字母或下划线开头,可以包含字母、数字、下 +划线、撇号(`'`)或连接符(`-`)。 ```nix { @@ -165,7 +168,8 @@ let bar = "foo"; in 两者的值都是 123。 -在特殊情况下,如果集合声明中的属性名求值为 null(这是错误的,因为 null 不能被强制为字符串),那么该属性将不会被添加到集合中: +在特殊情况下,如果集合声明中的属性名求值为 null(这是错误的,因为 null 不能被强 +制为字符串),那么该属性将不会被添加到集合中: ```nix { ${if foo then "bar" else null} = true; } @@ -173,7 +177,9 @@ let bar = "foo"; in 如果 foo 的值为 `false`,则其值为 `{}`。 -如果一个集合的 `__functor` 属性的值是可调用的(即它本身是一个函数或是其中一个集合的 `__functor` 属性的值是可调用的),那么它就可以像函数一样被应用,首先传入的是集合本身,例如: +如果一个集合的 `__functor` 属性的值是可调用的(即它本身是一个函数或是其中一个集 +合的 `__functor` 属性的值是可调用的),那么它就可以像函数一样被应用,首先传入的 +是集合本身,例如: ```nix let add = { __functor = self: x: x + self.x; }; @@ -181,7 +187,8 @@ let add = { __functor = self: x: x + self.x; }; in inc 1 ``` -求值为 2。这可用于为函数附加元数据,而调用者无需对其进行特殊处理,也可用于实现面向对象编程等形式。 +求值为 2。这可用于为函数附加元数据,而调用者无需对其进行特殊处理,也可用于实现面 +向对象编程等形式。 ## 数据构造 @@ -195,6 +202,62 @@ in inc 1 ### 条件判断 +if-then-else块 + +```nix +# 函数定义时 +myFunction = x: if x > 0 then "Positive" else "Non-positive" +myFunction 0 # Non-positive +myFunction 1 # Positive +``` + +```nix +# 变量定义时 +no = 7 +gt7 = if no > 0 then "yes" else "no" +# gt7变量值为`"yes"` +``` + +亦可嵌套使用 + +```nix +# 函数定义时 +myPlan = target: if target == "fitness" then "I'm going swimming." + else if target == "purchase" then "I'm going shopping." + else if target == "learning" then "I'm going to read a book." + else "I'm not going anywhere." +myPlan "fitness" # "I'm going swimming." +myPlan null # "I'm not going anywhere." + +# 变量定义时 +x = null +text = + if x == "a" then + "hello" + else if x == "b" then + "hi" + else if x == "c" then + "ciao" + else + "x is invalid" +``` + +### 循环控制 + +在Nix语言中,没有传统编程语言中的循环控制结构。Nix 的设计思想是函数式编程范式, +它更倾向于使用递归和高阶函数来处理数据,而不是显式地使用循环。 + +可以使用以下方式来实现循环控制: + +- 递归函数: Nix 支持递归函数,你可以定义递归函数来处理需要重复执行的操作。 + +```nix +let + recurse = n: if n <= 0 then [] else recurse (n - 1) ++ [n]; +in + recurse 5 +``` + ### 断言 ### `with` 表达式 From 7441a8866a27c86ec96421e3b1d6f284a9aa9668 Mon Sep 17 00:00:00 2001 From: Tatooi Noyo Date: Mon, 24 Jun 2024 12:33:42 +0800 Subject: [PATCH 02/13] Update Manuals.md for Controls Structure and Condition Expression --- src/tutorials/lang/Manuals.md | 50 +++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index 0196cc8..c3361ff 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -202,7 +202,7 @@ in inc 1 ### 条件判断 -if-then-else块 +if-then-else 块 ```nix # 函数定义时 @@ -214,8 +214,10 @@ myFunction 1 # Positive ```nix # 变量定义时 no = 7 -gt7 = if no > 0 then "yes" else "no" -# gt7变量值为`"yes"` +gt0 = if no > 0 then "yes" else "no" +# gt0 变量值为`"yes"` +gt0 +=> "yes" ``` 亦可嵌套使用 @@ -245,11 +247,49 @@ text = ### 循环控制 在Nix语言中,没有传统编程语言中的循环控制结构。Nix 的设计思想是函数式编程范式, -它更倾向于使用递归和高阶函数来处理数据,而不是显式地使用循环。 +它更倾向于使用递归和内建以及官方包函数来处理数据,而不是显式地使用循环。 + +在理解Nix语言的 “循环控制” 时,请先思考何时需要循环控制。普遍操作场景是在**列 +表**与**属性集**的`属性操作`与`生成`上。该篇讲的并不是字面上的 “循环控制”, 而是 +为达成某些目的,以往需要使用 “循环控制” 的手段实现的,在Nix语言中则以函数的方式 +来实现其目的。 可以使用以下方式来实现循环控制: -- 递归函数: Nix 支持递归函数,你可以定义递归函数来处理需要重复执行的操作。 +#### 内建函数/官方库函数 + +Nix 语言支持高阶函数,即可以将函数作为参数传递给其他函数。利用高阶函数的特性,可 +以创建一些函数来处理列表或集合中的每个元素,从而达到迭代的效果。Nix语言提供了一 +些内建函数以及官方库来帮助实现需要循环控制才能做到的事情。 + +下面是个例子,目的是生成指定范围的列表(实际上使用的range函数并不是高阶函数,但它 +的确做到了循环才可以实现的事情): + +```nix +# 通过官方库函数 range,生成指定范围元素的列表 +nixpkgs = import {} +alist = nixpkgs.lib.range 4 7 +alist +=> [ 4 5 6 7 ] + +# 通过内建函数 filter,遍历列表中的元素并过滤 +builtins.filter (item: item == "hello") [ "hello" "world" ] +=> [ "hello" ] +``` + +具体请参考: + +- [属性集相关函数](https://nixos.org/manual/nixpkgs/stable/#sec-functions-library-attrsets) +- [列表相关函数](https://nixos.org/manual/nixpkgs/stable/#sec-functions-library-lists) + +#### 递归函数 + +Nix 支持递归函数,你可以定义递归函数来处理需要重复执行的操作。 + +> ⚠️注意:在Nix语言开发中,并不推荐自己实现递归函数来实现循环控制,更推荐使用官 +> 方提供的高阶函数来实现。 + +例子如下: ```nix let From 53d59d2c8097f814265e83b51493419295a0f79c Mon Sep 17 00:00:00 2001 From: Tatooi Noyo Date: Mon, 24 Jun 2024 15:11:38 +0800 Subject: [PATCH 03/13] Update Manuals.md for Condition Expression --- src/tutorials/lang/Manuals.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index c3361ff..b8730c3 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -202,20 +202,25 @@ in inc 1 ### 条件判断 -if-then-else 块 +if-then-else 表达式 + +基本结构为 `if then else `,此表达式在 +_exprCond_ 求值为 `true` 时,结果为 _exprThen_ ,否则结果为 _exprElse_ 。 + +定义时的使用例子如下: ```nix -# 函数定义时 +# 定义函数的实现过程中与条件表达式搭配: myFunction = x: if x > 0 then "Positive" else "Non-positive" myFunction 0 # Non-positive myFunction 1 # Positive ``` ```nix -# 变量定义时 +# 定义变量时与条件表达式搭配: no = 7 gt0 = if no > 0 then "yes" else "no" -# gt0 变量值为`"yes"` +# gt0 变量值为 "yes" gt0 => "yes" ``` From 5c60f6958ffd1155fa2cabd596cca7cc0fb07b50 Mon Sep 17 00:00:00 2001 From: Tatooi Noyo Date: Mon, 24 Jun 2024 15:40:57 +0800 Subject: [PATCH 04/13] revert part on f74d6ca34bf46b29912f683d86ec1c651d33b3a9 --- src/tutorials/lang/Manuals.md | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index b8730c3..e5028c5 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -71,8 +71,7 @@ Nix 只会将自动处理后的字符串当作输入,而不是原始字符串 ##### URI -为了书写简便, [RFC 2396](https://www.ietf.org/rfc/rfc2396.txt) 规定了对于 URI -可以不使用引号闭合: +为了书写简便, [RFC 2396](https://www.ietf.org/rfc/rfc2396.txt) 规定了对于 URI 可以不使用引号闭合: ```nix UriWithoutQuotes = http://example.org/foo.tar.bz2 @@ -85,8 +84,7 @@ UriWithQuotes = "http://example.org/foo.tar.bz2" 数字被分为浮点型(比如 `.114514`)与整型(比如 `2233`)。 -数字是类型兼容的:纯整数运算总是返回整数,而任何涉及至少一个浮点数的运算都会返回 -一个浮点数。 +数字是类型兼容的:纯整数运算总是返回整数,而任何涉及至少一个浮点数的运算都会返回一个浮点数。 #### 路径 @@ -126,8 +124,7 @@ UriWithQuotes = "http://example.org/foo.tar.bz2" 属性集是用大括号括起来的名称与值对(称为属性)的集合。 -属性名可以是标识符或字符串。标识符必须以字母或下划线开头,可以包含字母、数字、下 -划线、撇号(`'`)或连接符(`-`)。 +属性名可以是标识符或字符串。标识符必须以字母或下划线开头,可以包含字母、数字、下划线、撇号(`'`)或连接符(`-`)。 ```nix { @@ -168,8 +165,7 @@ let bar = "foo"; in 两者的值都是 123。 -在特殊情况下,如果集合声明中的属性名求值为 null(这是错误的,因为 null 不能被强 -制为字符串),那么该属性将不会被添加到集合中: +在特殊情况下,如果集合声明中的属性名求值为 null(这是错误的,因为 null 不能被强制为字符串),那么该属性将不会被添加到集合中: ```nix { ${if foo then "bar" else null} = true; } @@ -177,9 +173,7 @@ let bar = "foo"; in 如果 foo 的值为 `false`,则其值为 `{}`。 -如果一个集合的 `__functor` 属性的值是可调用的(即它本身是一个函数或是其中一个集 -合的 `__functor` 属性的值是可调用的),那么它就可以像函数一样被应用,首先传入的 -是集合本身,例如: +如果一个集合的 `__functor` 属性的值是可调用的(即它本身是一个函数或是其中一个集合的 `__functor` 属性的值是可调用的),那么它就可以像函数一样被应用,首先传入的是集合本身,例如: ```nix let add = { __functor = self: x: x + self.x; }; @@ -187,8 +181,7 @@ let add = { __functor = self: x: x + self.x; }; in inc 1 ``` -求值为 2。这可用于为函数附加元数据,而调用者无需对其进行特殊处理,也可用于实现面 -向对象编程等形式。 +求值为 2。这可用于为函数附加元数据,而调用者无需对其进行特殊处理,也可用于实现面向对象编程等形式。 ## 数据构造 From 49d8df71ce79a1ffe97b02b93dcc7db117b01fe4 Mon Sep 17 00:00:00 2001 From: Tatooi Noyo Date: Tue, 25 Jun 2024 11:40:17 +0800 Subject: [PATCH 05/13] Update revise condition expression --- src/tutorials/lang/Manuals.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index e5028c5..bb74d76 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -203,14 +203,14 @@ _exprCond_ 求值为 `true` 时,结果为 _exprThen_ ,否则结果为 _exprE 定义时的使用例子如下: ```nix -# 定义函数的实现过程中与条件表达式搭配: +# 使用 if-then-else 实现函数: myFunction = x: if x > 0 then "Positive" else "Non-positive" myFunction 0 # Non-positive myFunction 1 # Positive ``` ```nix -# 定义变量时与条件表达式搭配: +# 使用 if-then-else 为变量动态赋值: no = 7 gt0 = if no > 0 then "yes" else "no" # gt0 变量值为 "yes" @@ -221,7 +221,7 @@ gt0 亦可嵌套使用 ```nix -# 函数定义时 +# 使用 if-then-else 实现函数: myPlan = target: if target == "fitness" then "I'm going swimming." else if target == "purchase" then "I'm going shopping." else if target == "learning" then "I'm going to read a book." @@ -229,7 +229,7 @@ myPlan = target: if target == "fitness" then "I'm going swimming." myPlan "fitness" # "I'm going swimming." myPlan null # "I'm not going anywhere." -# 变量定义时 +# 使用 if-then-else 为变量动态赋值: x = null text = if x == "a" then @@ -244,7 +244,7 @@ text = ### 循环控制 -在Nix语言中,没有传统编程语言中的循环控制结构。Nix 的设计思想是函数式编程范式, +在Nix语言中,没有指令式编程语言中的循环控制结构。Nix 的设计思想是函数式编程范式, 它更倾向于使用递归和内建以及官方包函数来处理数据,而不是显式地使用循环。 在理解Nix语言的 “循环控制” 时,请先思考何时需要循环控制。普遍操作场景是在**列 From 6d188988844bb8eeb398cf796c35512474babd55 Mon Sep 17 00:00:00 2001 From: Tatooi Noyo <98942281+TatooiNoyo@users.noreply.github.com> Date: Tue, 25 Jun 2024 16:07:39 +0800 Subject: [PATCH 06/13] Apply suggestions from code review Co-authored-by: Yingchi Long --- src/tutorials/lang/Manuals.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index bb74d76..c46c19e 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -203,25 +203,25 @@ _exprCond_ 求值为 `true` 时,结果为 _exprThen_ ,否则结果为 _exprE 定义时的使用例子如下: ```nix -# 使用 if-then-else 实现函数: +# 利用 if-then-else 表达式实现函数: myFunction = x: if x > 0 then "Positive" else "Non-positive" myFunction 0 # Non-positive myFunction 1 # Positive ``` ```nix -# 使用 if-then-else 为变量动态赋值: +# 利用 if-then-else 表达式定义变量: no = 7 gt0 = if no > 0 then "yes" else "no" # gt0 变量值为 "yes" gt0 -=> "yes" +# => "yes" ``` 亦可嵌套使用 ```nix -# 使用 if-then-else 实现函数: +# 利用 if-then-else 表达式实现函数: myPlan = target: if target == "fitness" then "I'm going swimming." else if target == "purchase" then "I'm going shopping." else if target == "learning" then "I'm going to read a book." @@ -229,7 +229,7 @@ myPlan = target: if target == "fitness" then "I'm going swimming." myPlan "fitness" # "I'm going swimming." myPlan null # "I'm not going anywhere." -# 使用 if-then-else 为变量动态赋值: +# 利用 if-then-else 表达式定义变量: x = null text = if x == "a" then @@ -257,10 +257,10 @@ text = #### 内建函数/官方库函数 Nix 语言支持高阶函数,即可以将函数作为参数传递给其他函数。利用高阶函数的特性,可 -以创建一些函数来处理列表或集合中的每个元素,从而达到迭代的效果。Nix语言提供了一 +以创建一些函数来处理列表或集合中的每个元素,从而达到迭代的效果。Nix 语言提供了一 些内建函数以及官方库来帮助实现需要循环控制才能做到的事情。 -下面是个例子,目的是生成指定范围的列表(实际上使用的range函数并不是高阶函数,但它 +下面是个例子,目的是生成指定范围的列表(实际上使用的`range`函数并不是高阶函数,但它 的确做到了循环才可以实现的事情): ```nix @@ -268,11 +268,11 @@ Nix 语言支持高阶函数,即可以将函数作为参数传递给其他函 nixpkgs = import {} alist = nixpkgs.lib.range 4 7 alist -=> [ 4 5 6 7 ] +# => [ 4 5 6 7 ] # 通过内建函数 filter,遍历列表中的元素并过滤 builtins.filter (item: item == "hello") [ "hello" "world" ] -=> [ "hello" ] +# => [ "hello" ] ``` 具体请参考: From 46e775fe9ea42ce29c2328faa61cb9b3c70f190d Mon Sep 17 00:00:00 2001 From: Tatooi Noyo <98942281+TatooiNoyo@users.noreply.github.com> Date: Tue, 25 Jun 2024 22:02:16 +0800 Subject: [PATCH 07/13] Apply suggestions from code review --- src/tutorials/lang/Manuals.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index c46c19e..57ae3bc 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -256,12 +256,10 @@ text = #### 内建函数/官方库函数 -Nix 语言支持高阶函数,即可以将函数作为参数传递给其他函数。利用高阶函数的特性,可 -以创建一些函数来处理列表或集合中的每个元素,从而达到迭代的效果。Nix 语言提供了一 +Nix 语言提供了一 些内建函数以及官方库来帮助实现需要循环控制才能做到的事情。 -下面是个例子,目的是生成指定范围的列表(实际上使用的`range`函数并不是高阶函数,但它 -的确做到了循环才可以实现的事情): +例子如下: ```nix # 通过官方库函数 range,生成指定范围元素的列表 @@ -282,10 +280,10 @@ builtins.filter (item: item == "hello") [ "hello" "world" ] #### 递归函数 -Nix 支持递归函数,你可以定义递归函数来处理需要重复执行的操作。 +Nix 语言支持递归函数,你可以定义递归函数来处理需要重复执行的操作。 -> ⚠️注意:在Nix语言开发中,并不推荐自己实现递归函数来实现循环控制,更推荐使用官 -> 方提供的高阶函数来实现。 +> ⚠️注意:在Nix 语言开发中,并不推荐自己实现递归函数来实现循环控制,更推荐使用官 +> 方提供的函数来实现。 例子如下: From 7275724cd4d04b07a05e2d540ff7c62582cd0fc7 Mon Sep 17 00:00:00 2001 From: Tatooi Noyo <98942281+TatooiNoyo@users.noreply.github.com> Date: Wed, 26 Jun 2024 11:33:50 +0800 Subject: [PATCH 08/13] Apply suggestions from code review Co-authored-by: Ryan Yin --- src/tutorials/lang/Manuals.md | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index 57ae3bc..123b2ae 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -244,20 +244,22 @@ text = ### 循环控制 -在Nix语言中,没有指令式编程语言中的循环控制结构。Nix 的设计思想是函数式编程范式, -它更倾向于使用递归和内建以及官方包函数来处理数据,而不是显式地使用循环。 +Nix 是一种函数式编程语言,每一段 Nix 程序都是一个完整的表达式。 +这与流行的 Java, Python 等命令式编程语言有很大不同,命令式编程语言的程序往往是一段包含变量声明、赋值、跳转等指令的指令序列。 -在理解Nix语言的 “循环控制” 时,请先思考何时需要循环控制。普遍操作场景是在**列 -表**与**属性集**的`属性操作`与`生成`上。该篇讲的并不是字面上的 “循环控制”, 而是 -为达成某些目的,以往需要使用 “循环控制” 的手段实现的,在Nix语言中则以函数的方式 -来实现其目的。 +这里不展开说明函数式编程与命令式编程的区别,不了解这个的读者建议先阅读 [什么是函数式编程思维?- 知乎](https://www.zhihu.com/question/28292740) 与 [函数式编程 - WIkipedia](https://zh.wikipedia.org/wiki/%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B) 理清个中关系。 -可以使用以下方式来实现循环控制: +一言蔽之,Nix 语言中没有 while/for 循环这类控制结构,取而代之的是以递归为基础实现的一系列高阶函数。Nix 的标准库提供了一系列此类高阶函数用于对字符串、列表等可迭代对象进行操作。 -#### 内建函数/官方库函数 +#### `builtins` 函数与 `nixpkgs.lib` 函数库 -Nix 语言提供了一 -些内建函数以及官方库来帮助实现需要循环控制才能做到的事情。 +Nix 语言自身提供了一些精简的内建函数,可通过 `builtins.xxx` 这种方式使用,官方文档参见 [Built-in Functions - Nix Manual](https://nix.dev/manual/nix/2.22/language/builtins#built-in-functions). + +此外,官方函数库 [nixpkgs.lib](https://github.com/NixOS/nixpkgs/lib) 提供了比 builtins 更丰富的功能。 + +社区提供的 [Noogle Search](https://noogle.dev/) 可以相当容易地搜索上述两类函数,推荐一用。 + +下面针对 `builtins` 与 `nixpkgs.lib` 的用法各举一例: 例子如下: @@ -280,12 +282,13 @@ builtins.filter (item: item == "hello") [ "hello" "world" ] #### 递归函数 -Nix 语言支持递归函数,你可以定义递归函数来处理需要重复执行的操作。 +如前所述,Nix 语言作为一种函数式编程语言,它采用递归取代了命令式编程语言中的循环等控制结构。 -> ⚠️注意:在Nix 语言开发中,并不推荐自己实现递归函数来实现循环控制,更推荐使用官 -> 方提供的函数来实现。 +这里举个简单的例子来说明 Nix 语言中如何实现一个递归函数: -例子如下: +> ⚠️注意:`nixpkgs.lib` 提供的函数对新手基本够用了,需要自行实现递归函数的场景并不多,在决定自行实现前,建议先检索下官方函数库。 + +> ⚠️注意:对新手而言,`nixpkgs.lib` 中的函数基本够用了,建议优先查找使用 `nixpkgs.lib` 与 `builtins` 中的函数,如果找不到自己想要的功能再考虑自行实现。 ```nix let From 4f544b0bf408b8df1e96c4798a1c4a4017b54753 Mon Sep 17 00:00:00 2001 From: Tatooi Noyo <98942281+TatooiNoyo@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:32:16 +0800 Subject: [PATCH 09/13] Update src/tutorials/lang/Manuals.md --- src/tutorials/lang/Manuals.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index 123b2ae..3f8d9c5 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -286,7 +286,6 @@ builtins.filter (item: item == "hello") [ "hello" "world" ] 这里举个简单的例子来说明 Nix 语言中如何实现一个递归函数: -> ⚠️注意:`nixpkgs.lib` 提供的函数对新手基本够用了,需要自行实现递归函数的场景并不多,在决定自行实现前,建议先检索下官方函数库。 > ⚠️注意:对新手而言,`nixpkgs.lib` 中的函数基本够用了,建议优先查找使用 `nixpkgs.lib` 与 `builtins` 中的函数,如果找不到自己想要的功能再考虑自行实现。 From aa0b33964910cb572aa78ee980021e0bd9aea8df Mon Sep 17 00:00:00 2001 From: Tatooi Noyo <98942281+TatooiNoyo@users.noreply.github.com> Date: Wed, 26 Jun 2024 20:59:33 +0800 Subject: [PATCH 10/13] Update src/tutorials/lang/Manuals.md --- src/tutorials/lang/Manuals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index 3f8d9c5..1e1c44f 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -264,7 +264,7 @@ Nix 语言自身提供了一些精简的内建函数,可通过 `builtins.xxx` 例子如下: ```nix -# 通过官方库函数 range,生成指定范围元素的列表 +# 通过 nixpkgs.lib.range,生成指定范围元素的列表 nixpkgs = import {} alist = nixpkgs.lib.range 4 7 alist From 99f995bc52abdff4cbf1b971a352a62115675586 Mon Sep 17 00:00:00 2001 From: Ryan Yin Date: Thu, 27 Jun 2024 10:31:29 +0800 Subject: [PATCH 11/13] Update src/tutorials/lang/Manuals.md Co-authored-by: Yingchi Long --- src/tutorials/lang/Manuals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index 1e1c44f..19c2a52 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -251,7 +251,7 @@ Nix 是一种函数式编程语言,每一段 Nix 程序都是一个完整的 一言蔽之,Nix 语言中没有 while/for 循环这类控制结构,取而代之的是以递归为基础实现的一系列高阶函数。Nix 的标准库提供了一系列此类高阶函数用于对字符串、列表等可迭代对象进行操作。 -#### `builtins` 函数与 `nixpkgs.lib` 函数库 +#### 内建函数与 `nixpkgs.lib` 函数库 Nix 语言自身提供了一些精简的内建函数,可通过 `builtins.xxx` 这种方式使用,官方文档参见 [Built-in Functions - Nix Manual](https://nix.dev/manual/nix/2.22/language/builtins#built-in-functions). From 6fe514a7c38e717ccb4f4303e2b0033356a58964 Mon Sep 17 00:00:00 2001 From: Ryan Yin Date: Thu, 27 Jun 2024 10:31:43 +0800 Subject: [PATCH 12/13] Update src/tutorials/lang/Manuals.md Co-authored-by: Yingchi Long --- src/tutorials/lang/Manuals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index 19c2a52..e87e684 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -287,7 +287,7 @@ builtins.filter (item: item == "hello") [ "hello" "world" ] 这里举个简单的例子来说明 Nix 语言中如何实现一个递归函数: -> ⚠️注意:对新手而言,`nixpkgs.lib` 中的函数基本够用了,建议优先查找使用 `nixpkgs.lib` 与 `builtins` 中的函数,如果找不到自己想要的功能再考虑自行实现。 +> ⚠️注意:对新手而言,`nixpkgs.lib` 中的函数基本够用了,建议优先查找使用内建函数和 `nixpkgs.lib` 中的函数,如果找不到自己想要的功能再考虑自行实现。 ```nix let From 0566e446cccb37c441f76c0dd5f398f20c917be5 Mon Sep 17 00:00:00 2001 From: Ryan Yin Date: Thu, 27 Jun 2024 21:01:39 +0800 Subject: [PATCH 13/13] docs: conditionals --- src/tutorials/lang/Manuals.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index e87e684..c135efb 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -195,10 +195,14 @@ in inc 1 ### 条件判断 -if-then-else 表达式 +Nix 的条件判断表达式的结构类似于这样: -基本结构为 `if then else `,此表达式在 -_exprCond_ 求值为 `true` 时,结果为 _exprThen_ ,否则结果为 _exprElse_ 。 +```nix +if then else +``` + +其中 _exprCond_ 的求值结果必须为布尔值 `true` 或 `false`. +当 _exprCond_ 求值为 `true` 时,上述条件表达式的结果为 _exprThen_ ,否则结果为 _exprElse_. 定义时的使用例子如下: