仓颉—控制流

内容纲要

@[toc]

控制流

控制流用于控制程序的执行逻辑,仓颉使用if表达式实现根据某个条件是否成立决定是否执行某段代码的功能,使用表达式实现某个条件为真时重复执行某段代码的功能。其中,循环表达式可细分为for in表达式,while表达式和do while表达式。

if 表达式

if表达式可以实现“如果条件成立,则执行这段代码;如果条件不成立,不执行”。

if 和 else

func main()
{
        let num = 8

        if (num > 0)
        {
                println("The value of num is greater than 0")
        }
        else
        {
                println("The value of num is not greater than 0")
        }
}

所有if表达式均以if关键字开头,后跟一个定义在一对圆括号内的条件,接着是定义在一对花括号内的if分支。

需要注意的是,if之后的条件必须时一个Bool类型表达式,否则编译报错:

func main()
{
        let num = 8

        if (num)
        {
                println("The value of num is greater than 0")
        }
        else
        {
                println("The value of num is not greater than 0")
        }
}

不同于Ruby、JS等,仓颉不会自动将整数类型转换为布尔类型,因此if中条件必须且只能是Bool类型表达式。

使用else if

func main()
{
        let num = 0

        if (num > 0)
        {
                print("The value of num is greater than 0")
        }
        else if (num < 0)
        {
                print("The value of num is less than 0")
        }
        else
        {
                print("The value of num is 0")
        }
}

if 表达式的类型

func f1()
{
    var num = 8

    if (num % 2 == 0)
    {
        num += 1
    }
    else
    {
        num
    }
}

若分支的最后一项为变量定义或函数声明,或分支为空,则分支的类型为Unit。例如,对于下例中函数f2内的if表达式,if分支和else分支的最后一项都是变量定义,所以两个分支的类型都是Unit

func f2()
{
    let num = 8

    if (num % 2 == 0)
    {
        let t1 = num + 1
    }
    else
    {
        let t2 = num
    }
}
拥有 else 分支的 if 表达式的类型

对于拥有else分支的if表达式,考虑到编译时可能无法确定哪条分支会被执行,所以:

  • 上下文有明确类型要求时,两个分支的类型均应是上下文所要求的类型的子类型
  • 上下文没有明确类型要求时,if表达式的类型是if分支的类型和else分支的类型的最小公共父类型。
    let num = 8
    let r: Int64 = if (num > 0) {1} else {0}

    上面例子中,定义变量r时,显式地标注了其类型为Int64,属于上下文类型明确的情况,因此要求if分支和else分支的类型均是Int64的子类型,显然10满足要求。

    let num = 8
    let r = if (num > 0) {1} else {0}

    上例中,未显式标注r的类型,因为if分支和else分支的类型均是Int64,所以if表达式的类型是Int64,从而r的类型也是Int64

没有 else 分支的 if 表达式的类型

对于没有else分支的if表达式,因为if分支有可能完全执行不到,因此其类型是Unit

let num = 8
let r = if (num < 0) {1}

r的类型是Unit,值是()

循环表达式

仓颉提供3种循环表达式:for inwhiledo while

上述类型都是Unit,值都是()

for in 表达式

for in表达式主要用来遍历一个序列(区间、数组、列表等)。

func main()
{
        for (i in 0..3)
        {
                println(i)
        }
}

for in表达式以关键字for开头,接着是定义在一对圆括号内的循环条件,使用关键字in分隔序列元素的绑定和要遍历的序列,最后是定义在一对花括号内的循环体。

执行结果为:

0
1
2

in之后的序列为空时,循环体将不会被执行:

func main()
{
        for (i in 0..0)
        {
                println(i)
        }
}

需要注意,循环条件中绑定的变量,在循环体中不能被修改:

func main()
{
    for (i in 0..3)
    {
        i = i * 10
        println(i)
    }
}

最后,可以在循环条件和循环体之间加上一个 guard 条件,实现对序列中元素的过滤:

{
        for (i in 0..3) if (i < 2)
        {
                println(i)
        }
}

只有当i的值小于2时才会被输出:

0
1
遍历由元组组成的序列

for in表达式的循环条件中还可以一次性完成对一个元组的解构:

func main()
{
        let a = [(1, 2), (3, 4), (5, 6)]
        for ((x, y) in a)
        {
                println(x + y)
        }
}

上例中,首先定义了一个列表,其元素是一系列Int64 * Int64类型的元组,在for in表达式中,依次遍历每个元组并将元组的元素分别与xy进行绑定,循环体中将x + y的结果依次输出。

3
7
11

while 表达式

func main()
{
        var a = 3
        while (a > 0)
        {
                println(a)
                a -= 1
        }
}

while表达式以关键字while开头,接着是定义在一对圆括号之内的循环条件(Bool表达式),最后是定义在一对花括号内的循环体。

do while 表达式

do while表达式总是会先执行一遍循环体,再根据循环条件成立与否确定是否再次执行循环体。

func main()
{
        var a = 3
        do {
                println(a)
                a -= 1
        } while (a > 0)
}

break 表达式

break表达式只能出现在循环表达式的循环体内,用于终止当前循环表达式的执行。

func main()
{
        for (i in 0..3)
        {
                if (i == 1)
                {
                        println(i)
                        break
                }
                println(i)
        }
}
func main()
{
        var a = 1
        while (true)
        {
                if ((a % 4 == 0) && (a % 6 == 0))
                {
                        println(a)
                        break
                }
                a += 1
        }
}
表达式类型

Nothing类型。

continue 表达式

continue表达式只能出现在循环表达式的循环体内,用于提前结束当前循环表达式的当前迭代,再开始新一轮循环。

func main()
{
        var a = 0
        while (a < 10)
        {
                a += 1
                if (a % 2 == 0)
                {
                        continue
                }
                println(a)
        }
}
表达式类型

Nothing类型。

留下评论

您的电子邮箱地址不会被公开。