我正在尝试实现一个简单的泛型方法: func findMaxT: Comparable(numbers_array : [T]) - ( min_tuple : T , max_tuple : T ){ var max_number : T? var min_number : T? for i in numbers_array { if(max_number i) { max_number = i } if(
func findMax<T: Comparable>(numbers_array : [T]) -> ( min_tuple : T , max_tuple : T ) { var max_number : T? var min_number : T? for i in numbers_array { if(max_number < i) { max_number = i } if(min_number > i) { min_number = i } } return (min_number! , max_number!) }
我试图访问这样的方法:
let result = findMax([3.4, 5, -7, -7.8])
但每当我运行此代码时,我收到以下错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
我想那是因为我没有为var max_number赋值:T?和var min_number:T?
我不能为它们赋值,因为它们是泛型的,我认为垃圾值正在搞乱这个函数的逻辑……我可能错了,但这是我能够从调试会话中评估的.
在此先感谢,非常感谢任何帮助.
Swift与其他一些基于C语言的不同之处在于它不允许您使用可能包含垃圾的未初始化变量.如果您声明但不初始化变量,那么在保证初始化之前使用它(基于可能的代码路径),就会出现编译器错误.但var选项会被隐式初始化为nil.所以这里的问题是你最后被迫解包(例如min_number!).有一些代码路径会导致nils没有被重新赋值给实际值,然后当你打开nil时!你收到一个错误.
原因是这一行:
if(min_number > i)
有一个版本的>这需要选项.如果这两个值都是非零值,那么它会比较它们.但如果一个是零,它总是小于非零版本.所以在你的循环中,你从min_number开始为nil,所以你的if语句永远不会评估为true.
这是另一种编写它的方法,它可以解释空数组的可能性:
func findMax<T: Comparable>(numbers_array : [T]) -> ( min_tuple : T , max_tuple : T ) { if let first_number = numbers_array.first { var min_number = first_number, max_number = first_number for i in dropFirst(numbers_array) { max_number = max(max_number, i) min_number = min(min_number, i) } return (min_number,max_number) } else { // the user has passed in an empty array... // so there is no minimum, you must take some // action like: fatalError("empty array passed") } }
或者,代替fatalError,您可以让函数返回一个可选项,如果序列为空则返回nil.在Swift 2.0中,minElement和maxElement方法从执行前者切换到后者.