Five Swift Development Extensions (Extensions)//Extensions Add new functionality (functionality) to an existing class, struct, or enumeration type. This includes the ability to extend a type without having permission to get the original source code (that is, reverse modeling). Extensions are similar to classifications in Objective-c (categories). (unlike objective-c, however, Swift's extension has no name.) ) Swift The extension in can be: 1. Adding computed properties and calculating static properties 2. Define instance methods and type Methods 3. Provide a new constructor 4. Define subscript 5. Define and use the new nested type 6. To make an existing type conform to a protocol note: If you define an extension to add new functionality to an existing type, the new feature Instances are available, even if they are defined in front of your extension. I. Extension syntax (Extension Syntax) declares an extension that uses the keyword extension:extension SomeType {//Add to SomeType the new feature is written here} an extension can extend an existing type, Enable it to fit one or more protocols (protocol). When this happens, the name of the protocol should be written exactly as the name of the class or struct: extension sometype:someprotocol, Anotherproctocol {//protocol implementation write here} The Protocol followers (Protocol conformance) added in this way are referred to as adding the protocol followers in the extension two. Calculated attribute (Computed properties) extensions can add computed instance properties and computed type properties to existing types. Swift's built-in double type adds 5 computed instance properties to provide basic support for collaborating with distance units. Extension Double {var km:double {return self * 1_000.0} var m:double {return self} var cm:double {retur N self/100.0} var mm:double {return self/1_000.0} var ft:double {return self/3.28084}}let Oneinch = 25. 4.mmprintln ("one inch is \ (oneinch) meteRS ")//Print out:" One inch is 0.0254 meters "let Threefeet = 3.ftprintln (" Three Feet is \ (threefeet) meters ")//printout:" Three feet is 0.914399970739201 meters "These computed attribute representations mean that a double type value is considered to be a length value under a unit. Even though they are implemented as computed properties, these properties can still be followed by a floating-point literal with. Syntax, which is exactly how distance conversions are achieved using these floating-point literals. In the above example, a double value of 1.0 is used to denote "1 meters". This is why the M-computed property returns the self--expression 1.km is considered to be a double value of 1.0 (1*1000) These properties are read-only computed properties, all of which are simply considered without the GET keyword representation. Their return values are double and can be used for all mathematical calculations that accept a double: let Amarathon = 42.km + 195.mprintln ("A marathon is \ (Amarathon) meters long")//Print Output: "A Marathon is 42195.0 meters long" Note: The extension can add new computed properties, but it is not possible to add a storage property or add a property observer to an existing property observers. Three. The constructor (initializers) extension can add a new constructor to an existing type. This allows you to extend other types, use your own custom type as a constructor parameter, or provide additional initialization options that are not included in the original implementation of the type. Extensions can add new convenience constructors to classes, but they cannot add new specified constructors or destructors to the class. The specified constructor and destructor must always be provided by the original class implementation. Note: If you use an extension to add a constructor to a value type, you can call the default constructor in the extension constructor of the value type when the value type has supplied a default value to all the storage properties, and no custom initializers is defined (default initializers) and a member constructor (memberwise initializers). As described in the constructor proxy for value types, the above rules no longer apply if you have already written the constructor as part of the original implementation of the value type. The following example defines a custom structure rect that is used to describe a geometric rectangle. This example also defines two auxiliarystruct size and point, which all use 0.0 as the default value for all properties: struct Size {var width = 0.0, height = 0.0}struct point {var x = 0.0, y = 0.0}stru CT Rect {var origin = point () var size = size ()} because struct Rect provides default values for all its properties, as described in the default constructor, it can automatically accept a default constructor and a member-level constructor. These constructors can be used to construct a new Rect instance: let Defaultrect = Rect () lets memberwiserect = Rect (Origin:point (x:2.0, y:2.0), Size:size (width: 5.0, height:5.0) You can provide an additional constructor that uses a special center point and size to extend the rect struct: extension rect {//extension can add a new constructor to an existing type This allows you to extend other types, Use your own custom type as the constructor parameter init (Center:point, size:size) {Let Originx = center.x-(SIZE.WIDTH/2) Let Originy = Center.y-(SIZE.HEIGHT/2) Self.init (Origin:point (X:originx, Y:originy), Size:size)}} This new constructor is first based on the provided cent The ER and size values calculate an appropriate origin point. Then call the struct Auto member constructor init (origin:size:), which saves the new origin and size to the appropriate attribute: let Centerrect = Rect (Center:point (x:4.0, y:4.0), Size:siz E (width:3.0, height:3.0))//Centerrect The origin is (2.5, 2.5), size is (3.0, 3.0) Note: If you use extensions to provide a new constructor, you still have the responsibility to ensure that the construction process is fully initialized for all instances. Four. Method (Methods) extension to add a new instance method and type to an existing typeMethod. The following example adds a new instance method named repetitions to the int type: extension int {func repetitions (Task: ()) {for i in 0..<self { Task ()}} Func redefine (Task: ()) {For I in 0..<self{task ()} }}//This repetitions method uses a single ()-()-()-()-()-()-type parameter, which indicates that the function has no parameters and no return value. After you define the extension, you can call the repetitions method on any integer, and the function is to perform a task multiple times: 3.repetitions ({println ("hello!")}) hello!//can use trailing closures to make the call more concise: 3.repetitions{println ("goodbye!")} goodbye! Five. Modify the instance method (mutating Instance Methods) by extending an instance method that is added to the instance itself. A method that modifies self or its properties in a struct and enumeration type must label the instance method as mutating, just as the modification method from the original implementation. The following example adds a new modified method named Square to the Swift int type to implement a square calculation of the original value: extension Int {//squared mutating func square () {self = sel f * Self}//cubic mutating func cube () {self=self*self*self}}var Someint = 3someint.square () someint . Cube ()//Someint Now the value is 96. The subscript (subscripts) extension can add a new subscript to an existing type. This example adds an integer subscript to the Swift built-in type int. The subscript [n] Returns the decimal number from right-to-left number nth number 123456789[0] return 9123456789[1] return 8extension int {//digit digital subscript (var digitindex:int), int {//decimal decimal, var decimalb ASE = 1 while digitindex > 0 {decimalbase *=--digitindex} return (self /decimalbase)%}}746381295[0]//returns 5746381295[1]//returns 9746381295[2]//returns 2746381295[8]//returns 7 NOTE: If the int value does not have enough digits, that is, the subscript is out of bounds, the next bidding clubs of the above implementation returns 0 because it automatically 0:746381295[9]//returns 0 on the left side of the number, which is equivalent to: 0746381295[9] seven. Nested type (Nested Types) extensions can add new nested types to existing classes, structs, and enumerations: extension Character {enum Kind {case vowel, consonant, other} var Kind: Kind {switch String (self). lowercasestring {case "a", "E", "I", "O", "U": return. Vowel case "B", "C", "D", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "s", "T", "V", "w", "X", "Y "," Z ": Return. Consonant default:return. Other}} This example adds a new nested enumeration to character. The enumeration named kind represents the type of a particular character. Specifically, it means that the characters in a standard Latin script are vowels or consonants (regardless of spokenand local variants), or other types. This example also adds a new compute instance property to character, kind, to return the appropriate kind enumeration member. Now, this nested enumeration can be used in conjunction with a character value: Func printletterkinds (word:string) {println ("' \ (Word) ' is made up of the following kind S of letters: ") for character in Word {switch Character.kind {case. Vowel:print ("vowel") case. Consonant:print ("consonant") case. Other:print ("Other")}} print ("\ n")}printletterkinds ("Hello")//' Hello ' is made up of the Follo Wing kinds of letters://consonant vowel consonant consonant vowel the input of the Printletterkinds function is a string value and iterates over its characters. During each iteration, consider the kind computed property of the current character and print out the appropriate category description. So printletterkinds can be used to print the type of all letters in a complete word, as shown in the word "hello" above. Note: Since the known character.kind is a character.kind type, all member values in Character.kind can be abbreviated in the form of a switch statement, such as use. Vowel instead of Character.Kind.Vowel
Five Swift Development Extensions (Extension)