添加"for in"支持以迭代Swift自定义类

yiz*_*lez 32 swift

我们知道,我们可以使用for..in循环迭代ArraysDictionaries.但是,我想像我CustomClass这样迭代我自己:

for i in CustomClass {
    someFunction(i)
}
Run Code Online (Sandbox Code Playgroud)

哪些操作/协议CustomClass必须支持这一点?

whi*_*and 33

假设您有一个类"汽车",您希望能够使用for..in循环迭代:

let cars = Cars()

for car in cars {
    println(car.name)
}
Run Code Online (Sandbox Code Playgroud)

最简单的方法是将AnyGenerator与这样的类一起使用:

class Car {
    var name : String
    init(name : String) {
        self.name = name
    }
}

class Cars : SequenceType {

    var carList : [Car] = []

    func generate() -> AnyGenerator<Car> {
        // keep the index of the next car in the iteration
        var nextIndex = carList.count-1

        // Construct a AnyGenerator<Car> instance, passing a closure that returns the next car in the iteration
        return anyGenerator {
            if (nextIndex < 0) {
                return nil
            }
            return self.carList[nextIndex--]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要尝试一个完整的工作示例,请添加上面的两个类,然后尝试像这样使用它们,添加几个测试项:

    let cars = Cars()

    cars.carList.append(Car(name: "Honda"))
    cars.carList.append(Car(name: "Toyota"))

    for car in cars {
        println(car.name)
    }
Run Code Online (Sandbox Code Playgroud)


就这么简单.

更多信息:http://lillylabs.no/2014/09/30/make-iterable-swift-collection-type-sequencetype


ArV*_*20u 12

所有上述答案都有点棘手.如果你的类中有一个你想要迭代的数组(比如@Lee Whitney的答案),那么有一个更简单的方法来实现它.您有以下类CustomClass:

class CustomClass: SequenceType {
    let array: [String]

    init(array: [String]) {
        self.array = array
    }

    func generate() -> IndexingGenerator<[String]> {
        return array.generate()
    }
}
Run Code Online (Sandbox Code Playgroud)

就那么简单.经过测试,可以使用最新的Xcode版本(编写本文时为6.1)和iOS 8.1.2.但是,此代码在未来的版本中应该是稳定的.

PS使用泛型,您可以通过遵循此模式轻松地创建自己的阵列副本,并且只实现所需的方法.