Int 类型不符合协议序列
Posted
技术标签:
【中文标题】Int 类型不符合协议序列【英文标题】:Type Int does not conform to protocol sequence 【发布时间】:2017-06-22 20:17:26 【问题描述】:我在 Swift 3 中有以下代码:
var numbers = [1,2,1]
for number in numbers.count - 1 // error
if numbers[number] < numbers[number + 1]
print(number)
我正在检查索引 [number] 上的值是否总是高于索引 [number + 1] 上的值。我收到一个错误:
Int 类型不符合协议顺序
有什么想法吗?
【问题讨论】:
numbers.count - 1
不是一个序列,它是一个整数。所以不能迭代。你需要像for number in numbers
这样的东西。顺便说一句,这是什么语言?
Swift 3,我知道这行不通,但我需要一个命令,它将这个代码循环为 numbers.count - 1 次。
for index in numbers.indices
BTW 在尝试访问数组中的下一个元素之前,您需要检查实际索引 if index + 1 < numbers.count
之后是否还有另一个元素
【参考方案1】:
可能很快。 您可以使用此迭代。
for number in 0..<(numbers.count-1)
【讨论】:
【参考方案2】:错误是因为Int
不是Sequence
。您可以按照已经建议的方式创建一个范围,该范围确实符合一个序列并允许使用 for in
进行迭代。
使Int
符合序列的一种方法是:
extension Int: Sequence
public func makeIterator() -> CountableRange<Int>.Iterator
return (0..<self).makeIterator()
这将允许将其用作带有for in
的序列。
for i in 5
print(i)
但我不建议这样做。这只是为了展示协议的强大功能,但在实际代码库中可能会造成混淆。
从您的示例来看,您似乎正在尝试比较集合的连续元素。自定义迭代器可以做到这一点,同时保持代码的可读性:
public struct ConsecutiveSequence<T: IteratorProtocol>: IteratorProtocol, Sequence
private var base: T
private var index: Int
private var previous: T.Element?
init(_ base: T)
self.base = base
self.index = 0
public typealias Element = (T.Element, T.Element)
public mutating func next() -> Element?
guard let first = previous ?? base.next(), let second = base.next() else
return nil
previous = second
return (first, second)
extension Sequence
public func makeConsecutiveIterator() -> ConsecutiveSequence<Self.Iterator>
return ConsecutiveSequence(self.makeIterator())
可以用作:
for (x, y) in [1,2,3,4].makeConsecutiveIterator()
if (x < y)
print(x)
在上面的示例中,迭代器将遍历以下对:
(1, 2)
(2, 3)
(3, 4)
【讨论】:
【参考方案3】:这可能有点晚了,但你可以这样做:
for number in numbers
代替:
for number in numbers.count - 1
要使 for 循环工作,需要一个序列(范围)。一个序列由一个声明值、一个结束值以及介于两者之间的所有内容组成。这意味着可以告诉 for 循环使用以太循环遍历一个范围
for number in 0...numbers.count-1 `or` for number in numbers
两个例子都给出了 nesasery 序列。其中:
for number in numbers.count - 1
只给出一个可能是开始值或结束值的值,因此无法计算出 for 循环必须运行多少次。
欲了解更多信息,请参阅Apple's swift control flow documnetation
【讨论】:
【参考方案4】:如果您尝试枚举数组而不是枚举数组,也会出现此错误。例如:
for (index, element) in [0, 3, 4]
应该是:
for (index, element) in [0, 3, 4].enumerated()
【讨论】:
【参考方案5】:所以首先你需要了解什么是序列.. 一种提供对其元素的顺序、迭代访问的类型。
序列是一个值列表,您可以一次遍历一个值。遍历序列元素的最常见方法是使用 for-in 循环:
让 oneTwoThree = 1...3。 // 序列
for循环其实是指
对于序列中的数字
所以你需要使用 对于 0 中的数字..
【讨论】:
【参考方案6】:错误是因为 number 不是索引,而是每次迭代时数组的元素。你可以像这样修改你的代码:
var numbers = [1,2,1,0,3]
for number in 0..<numbers.count - 1
if numbers[number] < numbers[number + 1]
print(numbers[number])
或者有一个使用 sort 方法的技巧,但这是一种 hack(是的,子索引是正确的,但看起来像倒置的;你可以直接在 Playground 上尝试这个):
var numbers = [1,2,1,0,3]
numbers.sort
if $0.1 < $0.0
print ($0.1)
return false
【讨论】:
【参考方案7】:对我来说,这个错误发生在我尝试编写 for 循环时,不是针对数组而是针对数组的单个元素。
例如:
let array = [1,2,3,4]
let item = array[0]
for its in item
print(its)
这会产生一个错误,例如:Type Int
does not conform to protocol 'sequence'
所以,如果你在for循环中遇到这个错误,请检查你是否在循环数组。
【讨论】:
以上是关于Int 类型不符合协议序列的主要内容,如果未能解决你的问题,请参考以下文章
泛型类型在不透明类型的帮助下符合序列:一些 IteratorProtocol