Swift中将函数的返回值隐式转换为Optional类型的特性

一个函数A的参数是返回值为Optional类型的函数,如果你传入了一个返回值不是Optional的函数,那么函数A会自动将传入函数的返回值转换为Optional类型,来看代码示例:


// 函数B的返回值为Int类型
func B()->Int {
return 1;
}

// 函数A的参数是返回值为Optional(Int)类型
func A(fun: ()->Int?) {
println(fun());
}

// 把函数B作为参数传入函数A,输出结果为Optional(1)
A(B);

更棒的是你还可以使用经过转换后的函数,比如:


// 让函数A返回作为参数的函数
func A(fun: ()->Int?)->()->Int? {
return fun;
}

var i = 0
let j = { ++i }

j() // returns 1
j() // returns 2

let h = A(j)

h() // returns {Some 3}
h() // returns {Some 4}
j() // returns 5

这种特性只能作用于函数的返回值,如果是下面这种情况,就不好使了:


func B(i: Int)->Int {
return i;
}

func A(fun: (Int?)->Int?) {
println(fun(1));
}

// 编译失败,不能将B函数参数的Int类型隐式转换为Int?类型
A(B);

这是因为函数B希望它的参数永远不能为nil,当接收到值为nil的参数后它就不知道该怎么办了。但如果函数B的参数为Optional类型,而函数A希望传入的函数参数为非Optional呢?我们来看看:


func B(i: Int?)->Int {
return i ?? 0
}

func A(fun: (Int?)->Int?) {
println(fun(1));
}

// 编译成功,并做了隐式转换,
A(B);

上面的特新其实可以理解为,编译器使用了一个闭包,调用了你传入的函数并进行了封包操作:


func B()->Int {
return 1;
}

func A(fun: ()->Int?) {
println(fun());
}

A( { Optional(B()) } );

这是Swift很有意思也很有用的一个特性。

分享到: