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

Swift中分割可变结构DeepLink避免索引越界的解决方案

问题描述

我需要处理格式如下的链接:

https://product/000000/product-name-type-color

使用split方法分割链接时遇到兼容性问题——链接可能缺少ID或描述信息,比如仅为https://product/。

当前使用的代码如下:

guard let separateLink = deeplink?.split(separator: "/") else { return }

let linkWithoutProductDetails = "\(separateLink[0] ?? \"")//\(separateLink[1] ?? \"")/\(separateLink[2] ?? \"")"

即便用了可选值和字符串插值,还是会触发「Fatal error: Index out of range」错误,怎么才能让代码兼容任意结构的链接而不崩溃?

解决方案

1. 安全检查数组下标再访问

直接通过下标访问split后的数组会因为元素数量不足崩溃,所以要先判断下标是否在有效范围内:

guard let deeplink = deeplink, !deeplink.isEmpty else { return }
let components = deeplink.split(separator: "/")

var parts = [String]()
if components.count > 0 {
    parts.append(String(components[0]))
}
if components.count > 1 {
    parts.append(String(components[1]))
}
if components.count > 2 {
    parts.append(String(components[2]))
}

// 匹配原代码的拼接逻辑
let linkWithoutProductDetails: String
switch parts.count {
case 0:
    linkWithoutProductDetails = ""
case 1:
    linkWithoutProductDetails = parts[0]
case 2:
    linkWithoutProductDetails = "\(parts[0])//\(parts[1])"
default:
    linkWithoutProductDetails = "\(parts[0])//\(parts[1])/\(parts[2])"
}

2. 用prefix截取前N个元素

如果只需要前3个部分,直接用prefix(3)获取,避免下标越界:

guard let deeplink = deeplink, !deeplink.isEmpty else { return }
let components = deeplink.split(separator: "/").prefix(3).map(String.init)

let linkWithoutProductDetails: String
switch components.count {
case 0:
    linkWithoutProductDetails = ""
case 1:
    linkWithoutProductDetails = components[0]
case 2:
    linkWithoutProductDetails = "\(components[0])//\(components[1])"
default:
    linkWithoutProductDetails = "\(components[0])//\(components[1])/\(components[2])"
}

3. 推荐:使用系统URL类解析(更可靠)

手动split容易忽略URL的标准格式细节,用系统API解析能自动处理各种边缘情况:

guard let deeplink = deeplink, let url = URL(string: deeplink) else { return }

let scheme = url.scheme ?? ""
let host = url.host ?? ""
let pathComponents = url.pathComponents.dropFirst() // 移除路径开头的空字符串

var parts = [scheme, host]
if let firstPath = pathComponents.first {
    parts.append(firstPath)
}

// 拼接成目标格式
let linkWithoutProductDetails: String
switch parts.count {
case 0:
    linkWithoutProductDetails = ""
case 1:
    linkWithoutProductDetails = parts[0]
case 2:
    linkWithoutProductDetails = "\(parts[0])//\(parts[1])"
default:
    linkWithoutProductDetails = "\(parts[0])//\(parts[1])/\(parts[2])"
}

原代码崩溃原因

split返回的是ArraySlice,其中的元素不是可选类型,所以separateLink[0] ?? ""这种写法无效——数组切片的下标访问是强制的,当下标超出元素数量时直接触发越界错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:45:30