当前位置 : 主页 > 手机开发 > ios >

ios – Swift Generic Variables致命错误:在展开Optional值时意外发现nil

来源:互联网 收集:自由互联 发布时间:2021-06-11
我正在尝试实现一个简单的泛型方法: 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方法从执行前者切换到后者.

网友评论