pdf文档 MoonBit月兔编程语言 现代编程思想 第七课 命令式编程:命令,可变数据结构,循环

780.46 KB 23 页 0 评论
语言
中文(简体)
格式
.pdf
评分
3
摘要
现代编程思想 命令式编程 Hongbo Zhang 1 函数式编程 到此为⽌,我们介绍的可以归类于函数式编程的范畴 对每⼀个输⼊,有着固定的输出 对于标识符,我们可以直接⽤它所对应的值进⾏替代⸺引⽤透明性 开发实⽤的程序,我们需要⼀些计算之外的�副作⽤� 进⾏输⼊输出 修改内存中的数据等 这些副作⽤可能导致多次执⾏的结果不⼀致 2 引⽤透明性 我们可以定义如下数据绑定和函数 1. let x: Int = 1 + 1 2. fn square(x: Int) -> Int { x * x } 3. let z: Int = square(x) // 4 我们可以将 square 与 x 直接⽤对应的值替换⽽不改变结果 1. let z: Int = { 2 * 2 } // 4 引⽤透明性可以易于理解 3 命令 函数 print 允许我们输出⼀个字符串,例如 print("hello moonbit") ⽉兔中可以通过 init 代码块来定义初始化指令 可以简单理解为程序主⼊⼝ 1. fn init { 2. println("hello moonbit") // 函数名中的ln代表换⾏ 3. } 4 命令与副作⽤ 输出命令可能会破坏引⽤透明性 1. fn square(x: Int) -> Int { x * x } 2. fn init { 3. let x: Int = { 4. println("hello moonbit") // <-- 我们⾸先执⾏命令,进⾏输出 5. 1 + 1 // <-- 之后,我们以表达式块最后的值作为表达式块的值 6. } 7. let z: Int = square(x) // 4, 输出⼀次 8. } 5 命令与副作⽤ 我们不⼀定可以放⼼替换,因此会增⼤程序理解难度 1. fn init { 2. let z: Int = { 3. println("hello moonbit"); // <-- 进⾏了第⼀次输出 4. 1 + 1 // <-- 获得值:2 5. } * { 6. println("hello moonbit"); // <-- 进⾏了第⼆次输出 7. 1 + 1 // <-- 获得值:2 8. } // 4,输出两次 9. } 6 单值类型 我们之前已经介绍过单值类型 Unit 它仅有⼀个值: () 以 Unit 为运算结果类型的函数或命令⼀般有副作⽤ fn print(String) -> Unit fn println(String) -> Unit 命令的类型也是单值类型 1. fn do_nothing() { // 返回值为单值类型时可以省略返回类型声明 2. let _x = 0 // 结果为单值类型,符合函数定义 3. } 7 变量 在⽉兔中,我们可以在代码块中⽤ let mut 定义临时变量 1. let mut x = 1 2. x = 10 // 赋值操作是⼀个命令 在⽉兔中,结构体的字段默认不可变,我们也允许可变的字段,需要⽤ mut 标识 1. struct Ref[T] { mut val : T } 2. 3. fn init { 4. let ref: Ref[Int] = { val: 1 } // ref 本身只是⼀个数据绑定 5. ref.val = 10 // 我们可以修改结构体的字段 6. println(ref.val.to_string()) // 输出 10 7. } 8 变量 我们可以将带有可变字段的结构体看作是引⽤ 1 var x = 1 x = 2 x 2 x let ref = { val : 1 } ref.val = 10 ref ref 1 10 val val mut ref = { val : 1 } ref = { val : 10 } ref ref 1 1 val val 10 val 9 别名 指向相同的可变数据结构的两个标识符可以看作是别名 1. fn alter(a: Ref[Int], b: Ref[Int]) { 2. a.val = 10 3. b.val = 20 4. } 5. 6. fn init { 7. let x: Ref[Int] = { val : 1 } 8. alter(x, x) 9. println(x.val.to_string()) // x.val的值将会被改变两次 10. } 10 别名 指向相同的可变数据结构的两个标识符可以看作是别名 x val 1 alter(x, x) a init b x val 10 alter(x, x) a init b x val 20 alter(x, x) a init b a.val = 10 b.val = 20 可变变量需要⼩⼼处理 11 循环 利⽤变量,我们可以定义循环 1. <定义变量及初始值> 2. while <针对变量判断是否继续循环>, <对变量进⾏迭代> { 3. <需要重复执⾏的命令> 4. } 例如,我们可以反复执⾏n次输出操作 1. let mut i = 0 2. while i < 2, i = i + 1 { 3. println("Output") 4. } // 重复输出2次 12 循环 我们进⼊循环时 判断是否满⾜继续循环的条件 执⾏命令 对变量进⾏迭代 重复以上过程 例如 1. let mut i = 0 // <-- 此时 i 等于 0 2. while i < 2, i = i + 1 { // <-- 此处,我们判断 i < 2 是否为真 3. println("Output") // <-- 0 < 2,因此继续执⾏,输出第⼀次 4. } // <-- 此时,我们执⾏i = i + 2 13 循环 我们进⼊循环时 判断是否满⾜继续循环的条件 执⾏命令 对变量进⾏迭代 重复以上过程 例如 1. // 此时 i 等于 1 2. while i < 2, i = i + 1 { // <-- 此处,我们判断 i < 2 是否为真 3. println("Output") // <-- 1 < 2,因此继续执⾏,输出第⼆次 4. } // <-- 此时,我们执⾏i = i + 2 14 循环 我们进⼊循环时 判断是否满⾜继续循环的条件 执⾏命令 对变量进⾏迭代 重复以上过程 例如 1. // 此时 i 等于 2 2. while i < 2, i = i + 1 { // <-- 此处,我们判断 i < 2 是否为真,结果为假 3. } // <-- 跳过 4. // <-- 继续后续执⾏ 15 调试器 ⽉兔的调试器允许我们在运⾏中看到实时的运⾏数据,更好理解运⾏过程 16 循环与递归 事实上,循环与递归是等价的 1. let mut <变量> = <初始值> 2. while <判断是否继续循环>, <对变量进⾏迭代> { 3. <需要重复执⾏的命令> 4. } 利⽤可变变量的情况下可以写成 1. fn loop_(<参数>) { 2. if <判断是否继续循环> { 3. <需要重复执⾏的命令> 4. loop_(<迭代后的参数>) 5. } else { () } 6. } 7. loop_(<初始值>) 17 循环与递归 例如下述两段代码执⾏效果相同 1. let mut i = 0 2. while i < 2, i = i + 1 { 3. println("Hello!") 4. } 1. fn loop_(i: Int) { 2. if i < 2 { 3. println("Hello!") 4. loop_(i + 1) 5. } else { () } 6. } 7. loop_(0) 18 循环流的控制 循环的时候,可以提前中⽌循环,或是跳过后续命令的执⾏ break 指令可以中⽌循环 continue 指令可以跳过后续运⾏,直接进⼊下⼀次循环 1. fn print_first_3() { 2. let mut i = 0 3. while i < 10, i = i + 1 { 4. if i == 3 { 5. break // 跳过从3开始的情况 6. } else { 7. println(i.to_string()) 8. } 9. } 10. } 19 循环流的控制 循环的时候,可以提前中⽌循环,或是跳过后续命令的执⾏ break 指令可以中⽌循环 continue 指令可以跳过后续运⾏,直接进⼊下⼀次循环 1. fn print_skip_3() { 2. let mut i = 0 3. while i < 10, i = i + 1 { 4. if i == 3 { 5. continue // 跳过3 6. } else { () } 7. println(i.to_string()) 8. } 9. } 20 ⽉兔的检查 ⽉兔会检查⼀个变量是否被修改,可以避免出现循环忘记加迭代条件 ⽉兔也会检查函数返回结果是否与类型声明相同,可以避免错误的返回类型声明 21 可变数据 使⽤场景⼴泛 直接操作程序外环境,如硬件等 ⼀些情况下性能更好,如随机访问数组等 可以构建部分复杂数据结构,如图 重复利⽤空间(原地修改) 可变数据并不总是与引⽤透明性冲突 1. fn fib_mut(n: Int) -> Int { // 对于相同输⼊,总是有相同输出 2. let mut acc1 = 0; let mut acc2 = 1; let mut i = 0 3. while i < n, i = i + 1 { 4. let t = acc1 + acc2 5. acc1 = acc2; acc2 = t 6. } 7. acc1 8. } 22 总结 本章节初步接触了命令式编程,包括 如何使⽤命令 如何使⽤变量 如何使⽤循环等 23...
来源 www.moonbitlang.cn
MoonBit月兔编程语言 现代编程思想 第七课 命令式编程:命令,可变数据结构,循环	 第2页
MoonBit月兔编程语言 现代编程思想 第七课 命令式编程:命令,可变数据结构,循环	 第3页
下载文档到本地,方便使用
共 23 页, 还有 5 页可预览, 继续阅读
文档评分
请文明评论,理性发言.