强行展开是邪恶的,所以我正在使用警卫,或者尽可能让我尽力,但有时这真的让我头疼。
基于1的列表索引变量到函数中基于0的数组
//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]
....
}
编辑器标记错误“
行中的@ index: guard让newIndex = index - 1 else {可选类型Int的值未解包,您的意思是使用!要么 ?“
添加!索引结果导致另一个错误:
“条件绑定的初始化程序必须具有可选类型,而不是int”
所以我目前使用的解决方案是:
guard var newIndex = index else {
throw Abort.custom(status: .badRequest,
message: "blah blah")
}
newIndex -= 1
let result = myArray[newIndex]
....
它有效,但我认为它有点难看......
答案 0 :(得分:2)
您可以使用方法调用而不是运算符进行减法:
func someFunction (index : Int?) {
guard var newIndex = index?.advanced(by: -1) else {
throw Abort.custom(status: .badRequest,
message: "blah blah")
}
let result = myArray[newIndex]
....
}
一般不会回答这个问题,但是在你的具体情况下。
答案 1 :(得分: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 }
答案 2 :(得分: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]
答案 3 :(得分:0)
对于您的特定情况,您可以执行以下操作:
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的列表索引变量转换为函数中基于0的数组