我需要验证字符串的长度。字符数的允许值为:
具有不同字符数的所有字符串都无效。因此,我想创建一个Swift函数,它接受许多范围并计算字符串:
extension String {
func evaluateLength(validCharacterCounts: Range<Int>...) -> Bool {
// Implementation
}
}
现在我可以为单个Int
范围调用该函数:
"Live long and prosper".evaluateLength(validCharacterCounts: 6..<10)
和多个Int
范围:
"Live long and prosper".evaluateLength(validCharacterCounts: 6..<10, 15..<20)
但我不能用单个孤立的整数值调用该函数:
"Live long and prosper".evaluateLength(validCharacterCounts: 6..<10, 12, 15)
因为12
和15
的输入为Int
而不是Range<Int>
。
Swift编译错误:无法转换类型&#39; Int&#39;预期参数类型&#39;范围&#39;
有没有办法在Swift中将单个整数视为Range
,比如将其自动投放到Range<Int>
?
(毕竟5
相当于5..<6
,所以在数学上说5
也是一个范围。)
答案 0 :(得分:0)
我想出了3个解决方案,但我不会像方法接受Int
或Range<Int>
那样令人满意,但我们走了吗?
1 - 你有类型安全但必须使用一些解决方法:
extension String {
func evaluateLength(validCharacterCounts: [Range<Int>]? = nil) -> Bool {
if let validCharCounts = validCharacterCounts {
for validCharCount in validCharCounts {
if validCharCount.contains(characters.count) {
return true
}
}
}
return false
}
}
extension Int {
var asRange: Range<Int> {
return self..<self+1 as Range<Int>
}
}
"Hello, playground".evaluateLength(validCharacterCounts: [17.asRange, 1, 25, 1..<45]) // true
2 - 您没有类型安全:
extension String {
func evaluateLength(validCharacterCounts: [Any]? = nil) -> Bool {
if let validCharCounts = validCharacterCounts {
for validCharCount in validCharCounts {
if let range = validCharCount as? Range<Int> {
if range.contains(characters.count) {
return true
}
} else if let range = validCharCount as? CountableRange<Int> {
if range.contains(characters.count) {
return true
}
} else if let range = validCharCount as? CountableClosedRange<Int> {
if range.contains(characters.count) {
return true
}
} else if let int = validCharCount as? Int {
if int.asRange.contains(characters.count) {
return true
}
} else {
fatalError("Unexpected type: \(type(of: validCharCount))")
}
}
}
return false
}
}
extension Int {
var asRange: Range<Int> {
return self..<self+1 as Range<Int>
}
}
"Hello, playground".evaluateLength(validCharacterCounts: [12, 1, 4, 6, 14...18]) // true
3 - 迄今为止最好的,但仍然不是完美的解决方案:
extension String {
func evaluateLength(validCharacterCounts: [Int]? = nil) -> Bool {
guard let validCharCounts = validCharacterCounts else {
return false
}
return validCharCounts.contains(characters.count)
}
}
"Hello, playground".evaluateLength(validCharacterCounts: [12, 1, 4, 6] + Array(14...18)) // true
答案 1 :(得分:0)
我就是这样做的。我只是创建一个带有相关初始化程序的Set扩展,而不是处理范围语义。
extension Set where Element == Int {
init(with elements: [Int] = [], and ranges: Range<Int>...) {
var allElements = [elements]
ranges.forEach {
allElements.append(Array($0.lowerBound..<$0.upperBound))
}
self.init(allElements.joined())
}
}
let newSet = Set(with: [1, 3, 328], and: 6..<10, 15..<20)
newSet.contains(3) //true
newSet.contains(4) //false
newSet.contains(16) //true
这允许您只传递单个值,仅传递范围或两者。唯一需要注意的是将它们分开的命名参数。
Set
语义也意味着你可以根据需要创建静态常量,并且也应该明显更快。