首页 > 试题广场 >

下面一个函数的功能是计算两个double(optional)

[问答题]

Swift 2.0 or later

下面一个函数的功能是计算两个double(optional)类型的数的相除的结果。在执行除法之前,必须提前满足三个条件:

被除数必须包含nil值

除数必须为包含nil值

除数不能为零

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func divide(dividend: Double?, by divisor: Double?) -> Double? {
if dividend == .None {
return .None
}
if divisor == .None {
return .None
}
if divisor == 0 {
return .None
}
return dividend! / divisor!
}

上面的函数可以正常使用,但是会存在两个问题:

那些前提条件可以利用guard语句。

使用了强制拆包。

请使用guard语句和避免使用强制拆包来优化这个函数。

推荐

guard语句是在Swift 2.0中引进的,它是用途是在未满足某个条件时,提供一个退出的路径。对于检查是否满足先决条件来说,它是非常有用的。因为它可以使你更清晰的表达逻辑——而不是像i各种f语句嵌套实现那么复杂。下面就是一个例子:

1
guard dividend != .None else { return .None }

它也可以在optional binding(可选绑定)中使用。使用guard语句之后,使拆包后的变量可以被访问。

1
guard let dividend = dividend else { return .None }

所以divide函数被重写如下:

1
2
3
4
5
6
func divide(dividend: Double?, by divisor: Double?) -> Double? {
guard let dividend = dividend else { return .None }
guard let divisor = divisor else { return .None }
guard divisor != 0 else { return .None }
return dividend / divisor
}

我们发现隐身的可拆包的运算在代码的最后一行,因为dividend和divisor这两个参数已经被拆包并且以分别以一个常量来存储。

因此,你可以再次使用guard语句,使上面的函数更简洁:

1
2
3
4
func divide(dividend: Double?, by divisor: Double?) -> Double? {
guard let dividend = dividend, divisor = divisor where divisor != 0 else { return .None }
return dividend / divisor
}

上面的函数中使用了两个guard语句,因为使用了where语句指定了divisor不能为0的条件。

发表于 2018-07-12 20:39:49 回复(0)