You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode中Swift队列实现出现下标越界错误的排查及用户输入最佳方案咨询

排查下标越界错误&Swift用户输入最佳实践

错误原因拆解

你遇到的Index out of range崩溃主要来自两个核心问题:

  1. 强制解包的致命风险:代码里的readLine()!和Int(command[1])!都是强制解包操作——如果输入结束后readLine()返回nil,或者某个push命令后面没跟数字,甚至输入了空行,都会直接触发崩溃。
  2. 输入逻辑不匹配:你的代码预期是先输入命令总数,再分N行输入每条命令,但你提供的输入是把所有内容挤在同一行里。这会导致循环中后续的readLine()根本读不到有效命令,要么返回nil(强制解包崩溃),要么读到空字符串,split后得到空数组,访问command[0]就会触发下标越界。

修复后的代码

下面的版本解决了所有安全问题,同时兼容“一行式输入”和“分行输入”两种格式:

import Foundation

public struct Queue {
    private var data = [Int]()
    
    mutating func enqueue(element: Int) {
        data.append(element)
    }
    
    mutating func dequeue() {
        print(isEmpty ? "-1" : "\(data.removeFirst())")
    }
    
    var size: Int {
        data.count
    }
    
    var isEmpty: Bool {
        data.isEmpty // 直接复用数组原生的isEmpty,更简洁可靠
    }
    
    var front: Int {
        data.first ?? -1 // 用nil合并运算符简化空值处理
    }
    
    var back: Int {
        data.last ?? -1
    }
}

// 安全读取所有输入内容
guard let inputContent = readLine() else {
    print("未检测到有效输入")
    exit(0)
}

// 将输入拆分为单个命令/参数的数组
let allComponents = inputContent.split(separator: " ")
// 验证第一个元素是合法的命令总数,且输入长度足够
guard let totalCommands = Int(allComponents[0]), allComponents.count > totalCommands else {
    print("输入格式错误,请确保开头是命令总数,且后续命令数量足够")
    exit(0)
}

var queue = Queue()
var currentIndex = 1 // 跳过第一个元素(命令总数)

// 逐元素处理命令
while currentIndex < allComponents.count && currentIndex <= totalCommands {
    let currentCommand = allComponents[currentIndex]
    switch currentCommand {
    case "push":
        // 检查是否有后续的数字参数,且能转换为Int
        guard currentIndex + 1 < allComponents.count, let num = Int(allComponents[currentIndex + 1]) else {
            print("push命令格式错误,请输入「push 数字」")
            currentIndex += 1
            continue
        }
        queue.enqueue(element: num)
        currentIndex += 2 // 跳过push和对应的数字
    case "pop":
        queue.dequeue()
        currentIndex += 1
    case "size":
        print(queue.size)
        currentIndex += 1
    case "empty":
        print(queue.isEmpty ? "1" : "0")
        currentIndex += 1
    case "front":
        print(queue.front)
        currentIndex += 1
    case "back":
        print(queue.back)
        currentIndex += 1
    default:
        print("未知命令:\(currentCommand)")
        currentIndex += 1
    }
}

// 处理命令数量不足的情况
if currentIndex <= totalCommands {
    print("输入的命令数量不足,请检查输入内容")
}

Swift获取用户输入的最佳方式

  1. 绝对避免强制解包:永远不要用!处理readLine()的返回值,要用if let或guard let做可选绑定,安全处理nil情况。
  2. 统一处理输入流:把所有输入内容拆分为单个元素的数组,不管用户是一行输入还是分行输入,都能兼容处理,避免因输入格式导致的逻辑错误。
  3. 严格验证输入格式:对于需要参数的命令(比如push),一定要检查参数是否存在、格式是否合法,避免下标越界或类型转换失败。
  4. 利用Swift空安全特性:用?? nil合并运算符替代繁琐的guard let+返回逻辑,让代码更简洁易读。
  5. 覆盖边界场景:比如队列空时的dequeue、front操作,要确保返回符合要求的默认值(比如你的需求里的-1)。

内容的提问来源于stack exchange,提问作者sweetSwift

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 11:32:50