How to implement a custom type of for-in loop in the Swift programming language (based on Swift 2.2)

Source: Internet
Author: User



We often use the for-in loop in the Swift programming language (also known as For-each in programming language terminology). Also, from the Swift 2.2 release, the For loop will only support the For-in form, not for the For i = 0; I < n; I+=1 {} This form, in order to use this form, only use while or repeat-while instead, or find a way to for-in.



In Swift, the standard library has defined many types that can directly support the for-in loop form, such as range, Array, Set, dictionary, and so on. So can we define a class or struct ourselves to support this iterative form of for-in? Of course! We need to take two steps to achieve this goal.



In the first step, we need to implement the Sequencetype protocol for classes or structs that use for-in loops. Sequencetype contains many container-related interface methods, but if we simply implement the for-in loop, we only need to implement its public func generate ()-Self.generator interface method. Self can only be used in the definition of protocol, but it is not possible to use self because self is a reference to an object and the protocol is not an object, so the Swift programming language introduces self (note that S is uppercase) to refer to the types defined in this agreement. The Generate method is used to generate a list of each element of the desired iteration. In addition, the ontology of generator is Generatortype, which is also a protocol that represents each element object of the required iteration, so we're going to do the second step.



The second step is to implement the Generatortype protocol. This protocol is relatively simple, just a public mutating func next ()-Self.element interface method. This element can be used to specify the type of each element.



Let's take a look at an example code:


//
// ViewController.swift
// SwiftTest
//
// Created by Zenny Chen on 16/4/1.
// Copyright © 2016 GreenGames Studio. All rights reserved.
//

import Cocoa

class MyIterContainer <T>: SequenceType {
    
    // The container itself contains an array object mElemArray
    private var mElemArray: [T]?
    
    init () {
        mElemArray = [T] ()
    }
    
    init (elems: [T]) {
        mElemArray = elems;
    }
    
    func generate ()-> MyIterGenerator <T> {
        
        // here returns a GeneratorType object
        return MyIterGenerator (elems: mElemArray!)
    }
}

class MyIterGenerator <T>: GeneratorType {
    
    private var mCurrentIndex: Int = 0
    private var mElemArray: [T]?
    
    init (elems: [T]) {
        
        mElemArray = elems
    }
    
    func next ()-> T? {
        
        guard let list = mElemArray else {return nil}
        
        if mCurrentIndex <list.count {
            
            let element = list [mCurrentIndex]
            mCurrentIndex + = 1
            return element
            
        }
        else {
            return nil
        }
    }
}

class ViewController: NSViewController {
    
    override func viewDidLoad () {
        super.viewDidLoad ()
        
        // Do any additional setup after loading the view.
        
        let container = MyIterContainer (elems: [1, 2, 3, 4])
        
        var sum = 0
        for i in container {
            sum + = i
        }
        print ("sum = \ (sum)")
        
        sum = 0
        
        // The above for-in iteration is equivalent to the following code:
        let generator = container.generate ()
        var elem: Int? = nil
        
        repeat {
            elem = generator.next ()
            if let value = elem {
                sum + = value
            }
        }
        while elem! = nil
        
        print ("second sum = \ (sum)")
    }
    
    override var representedObject: AnyObject? {
        didSet {
            // Update the view, if already loaded.
        }
    }
} 


The example code above first defines a container class Myitercontainer<t>, and then defines the associated generator class Myitergenerator<t>, where generics are used to make later implementations more flexible. Then the method of using for-in is described in the Viewdidload method, and its internal implementation mechanism is described at the end.






How to implement a custom type of for-in loop in the Swift programming language (based on Swift 2.2)


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.