Optional vs Bound value assigning var from array

谁说我不能喝 提交于 2019-12-25 03:43:14

问题


I want to check if there is a value in a array and if so assign to a String using a if-left statement:

if let scoreValue = scoreValueArray[element!]{
               // do something with scoreValue 
            }

Error: Bound value in a conditional binding must be of optional type

So tried changing the ! to ? but error persists.

Any input appreciated.

scoreValueArray is an array of strings, where a String value is appended to array if a condition is met, then array is saved to NSUserdefaults.

So element is a int which corresponds to a index in the array, bt only if the index is occupied with a String, so

scoreValueArray[element!]

could return an 'Index out of bounds', hence want to use the if-let.


回答1:


It's not clear what type your scoreValueArray is, but for the sake of this answer, I'm going to assume it's an array of Int.

var scoreValueArray: Array<Int>

Now, if we look the definition of the Array struct, we'll find this:

struct Array<T> : MutableCollectionType, Sliceable {
    // other stuff...

    subscript (index: Int) -> T

    // more stuff
}

So, calling the subscript method on our array (which is what we do when we say scoreValueArray) returns a non-optional. And non-optionals cannot be used in the conditional binding if let/if var statements.

We can duplicate this error message in a more simple example:

let foo: Int = 3

if let bar = foo {
    // same error
}

This produces the same error. If we instead do something more like the following, we can avoid the error:

let foo: Int? = 3

if let bar = foo {
    // perfectly valid
}

This is different from a dictionary, whose subscript method does return an optional (T?). A dictionary will return a value if the key passed in the subscript is found or nil if there is no value for the passed key.

We must avoid array-index-out-of-bounds exceptions in the same way we always do... by checking the array's length:

if element < scoreValueArray.count {
    scoreValue = scoreValueArray[element]
}



回答2:


Although the accepted answer clearly puts why optional binding is not available in the current implementation, it doesn't provide with a solution.

As it is shown in this answer, protocols provide an elegant way of safely checking the bounds of an array. Here's the Swift 2.0 version:

extension Array {
    subscript (safe index: Int) -> Element? {
        return indices ~= index ? self[index] : nil
    }
}

Which you can use like this:

let fruits = ["Apple", "Banana", "Cherry"]

if let fruit = fruits[safe: 4] {
   // Do something with the fruit
}


来源:https://stackoverflow.com/questions/29422361/optional-vs-bound-value-assigning-var-from-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!