首页 文章

可选的可变力展开,我还没有看到解决方案

提问于
浏览
0

强行展开是邪恶的,所以我正在使用后卫,或者尽可能让我尽力,但有时这真的让我头疼 .

1 based list index variable to 0 based array in a function

//index is an integer from a 1 based list, so it can be 1, 2, 3,... (index is coming from an external API)
func someFunction (index : Int?) {
guard let newIndex = index - 1 else {
            throw Abort.custom(status: .badRequest,
                               message: "blah blah")
        }
 let result = myArray[newIndex]
 ....
}

编辑器标记错误“

可选类型Int的值未解包,您是不是要使用!要么 ?”

@ index in the line:guard let newIndex = index - 1 else {

添加一个!索引结果导致另一个错误:

“条件绑定的初始化程序必须具有可选类型,而不是int”

所以我目前使用的解决方案是:

guard var newIndex = index else {
            throw Abort.custom(status: .badRequest,
                               message: "blah blah")
        }

     newIndex -= 1
     let result = myArray[newIndex]
     ....

它有效,但我认为它有点丑陋的编码......

4 回答

  • 0

    您可以使用方法调用而不是运算符进行减法:

    func someFunction (index : Int?) {
        guard var newIndex = index?.advanced(by: -1) else {
            throw Abort.custom(status: .badRequest,
                               message: "blah blah")
        }
    
        let result = myArray[newIndex]
        ....
    }
    

    一般不会回答这个问题,但在具体情况下 .

  • 0

    最安全的方法是使用可选绑定来解包索引,然后检查(从1开始)索引是否在数组中项目数的范围内(〜=是模式匹配运算符)

    guard var newIndex = index, // unwraps the optional
        1...myArray.count ~= newIndex // is index in the range 1 ... number of items in the array
            else {
                throw Abort.custom(status: .badRequest,
                               message: "blah blah")
                return }
    newIndex -= 1
    let result = myArray[newIndex]
    

    有效的索引范围是

    0-based : 0..<myArray.count
    1-based : 1...myArray.count
    

    如果检查成功,则减少索引并获取该项目 .


    或者如果以后不使用 newIndex 则更简单:

    guard let newIndex = index, // unwraps the optional
        1...myArray.count ~= newIndex // is index in the range 1 ... number of items in the array
            else {
                throw Abort.custom(status: .badRequest,
                               message: "blah blah")
                return }
    let result = myArray[newIndex - 1]
    
  • 2

    对于您的特定情况,您可以执行以下操作:

    func someFunction (index : Int?) throws {
        guard let newIndex = Optional( (index ?? 0) - 1 ), newIndex >= 0 else {
            throw Abort.custom(status: .badRequest, message: "blah blah")
        }
    
        let result = myArray[newIndex]
        ....
    }
    
    • (index ?? 0) ,你告诉 index 不是 nil 然后 index = index! 否则0

    • 因此,您拥有未包装的值,并从中减去1 . 但您必须使用 Optional 类型进行可选绑定 . 所以通过 Optional( (index ?? 0) - 1 ) 使其可选

    • 到现在为止,您已经获得了 newIndex 并通过提供 newIndex >= 0 检查确认您不会对负索引值执行任何操作 .

    所以你可以转换 1 based list index variable to 0 based array in a function

  • 0
    guard let newIndex = index - 1
    

    guard let 仅用于展开 Optional . 在这里,您混淆了展开的操作,以及将1移除到整数的操作 .

    你分两步做到这一点是对的,而不是一步 . 它根本不丑陋!例如 :

    func someFunction (index : Int?) throws {
        guard let unwrappedIndex = index else {
            //The given index is nil, abort.
            throw Abort.custom(status: .badRequest,
                              message: "Index is nil")
        }
    
        //Now everything is fine, unwrappedIndex is not an Optional anymore.
        guard unwrappedIndex - 1 > 0 else {
            throw Abort.custom(status: .badRequest,
                              message: "Wrong index")
        }
    
        //Happy scenario... Do you things...
        let result = myArray[newIndex]
        ...
    }
    

    更好的是,你不必被迫声明另一个变量名来解开它!做一个像这样的警卫:

    guard let index = index else { throw Error }
    

相关问题