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
相关产品推荐
相关产品推荐

