diff --git a/src/tutorials/lang/Manuals.md b/src/tutorials/lang/Manuals.md index 4d071d3..c135efb 100644 --- a/src/tutorials/lang/Manuals.md +++ b/src/tutorials/lang/Manuals.md @@ -195,6 +195,111 @@ in inc 1 ### 条件判断 +Nix 的条件判断表达式的结构类似于这样: + +```nix +if then else +``` + +其中 _exprCond_ 的求值结果必须为布尔值 `true` 或 `false`. +当 _exprCond_ 求值为 `true` 时,上述条件表达式的结果为 _exprThen_ ,否则结果为 _exprElse_. + +定义时的使用例子如下: + +```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" +gt0 +# => "yes" +``` + +亦可嵌套使用 + +```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." + else "I'm not going anywhere." +myPlan "fitness" # "I'm going swimming." +myPlan null # "I'm not going anywhere." + +# 利用 if-then-else 表达式定义变量: +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 程序都是一个完整的表达式。 +这与流行的 Java, Python 等命令式编程语言有很大不同,命令式编程语言的程序往往是一段包含变量声明、赋值、跳转等指令的指令序列。 + +这里不展开说明函数式编程与命令式编程的区别,不了解这个的读者建议先阅读 [什么是函数式编程思维?- 知乎](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 的标准库提供了一系列此类高阶函数用于对字符串、列表等可迭代对象进行操作。 + +#### 内建函数与 `nixpkgs.lib` 函数库 + +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` 的用法各举一例: + +例子如下: + +```nix +# 通过 nixpkgs.lib.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 语言中如何实现一个递归函数: + + +> ⚠️注意:对新手而言,`nixpkgs.lib` 中的函数基本够用了,建议优先查找使用内建函数和 `nixpkgs.lib` 中的函数,如果找不到自己想要的功能再考虑自行实现。 + +```nix +let + recurse = n: if n <= 0 then [] else recurse (n - 1) ++ [n]; +in + recurse 5 +``` + ### 断言 ### `with` 表达式