Details turn from: http://wiki.jikexueyuan.com/project/swift/chapter2/07_Closures.html
An extension is the addition of a new feature (functionality) to an existing class, struct, enumeration type, or protocol 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.) )
The extensions in Swift can:
- Adding computed and computed static properties
- Defining instance methods and type methods
- To provide a new constructor
- Define Subscript
- Defining and using a new nested type
- Make an existing type conform to a protocol
In Swift, you can even extend a protocol (PROTOCOL) to provide the implementation required by the Protocol, or add additional functionality that brings additional benefits to the appropriate type. You can get more details from the protocol extension.
Attention:
Extensions can add new functionality to a type, but cannot override existing functionality.
Extended syntax (Extension Syntax)
Declare an extension using the keywordextension:
extension SomeType {
// New features added to SomeType are written here
}
An extension can extend an existing type so that it can be adapted to one or more protocols (protocol). When this happens, the name of the protocol should be written exactly in the same way as the class or struct's name:
extension SomeType: SomeProtocol, AnotherProctocol {
// Protocol implementation is written here
}
The Protocol followers (Protocol conformance) added in this way are referred to as adding protocol members in the extension
Attention:
If you define an extension to add new functionality to an existing type, this new feature is available for all existing instances of that type, even if they are defined earlier in your extension.
Computed attributes (Computed properties)
An extension can add a computed instance property and a computed Type property to an existing type. The following exampleDoubleadds 5 compute instance properties to Swift's built-in type, providing 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 {return self / 100.0}
var mm: Double {return self / 1_000.0}
var ft: Double {return self / 3.28084}
}
let oneInch = 25.4.mm
print ("One inch is \ (oneInch) meters")
// Print output: "One inch is 0.0254 meters"
let threeFeet = 3.ft
print ("Three feet is \ (threeFeet) meters")
// Print output: "Three feet is 0.914399970739201 meters"
The meaning of these computed attribute representations is to thinkDoubleof a type's value as 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 dot syntax, which is precisely how distance conversions are achieved using these floating-point literals.
In the above example,Doublethe value of a type1.0is used to denote "1 meters". This is why themcomputed property returnsself-the expression is1.mconsidered1.0to be the computedDoublevalue.
Other units require some conversion to represent the values measured under the meter. 1-kilometer equals 1,000 meters, so thekmcomputed attribute is multiplied by the value to convert it to the value of1_000.00the unit meter. Similarly, 1 meters is 3.28024 feet, so theftcomputed attribute divides the correspondingDoublevalue3.28024to achieve the unit conversion of feet to meters.
These properties are read-only computed properties, and all are simple to consider that they are notgetrepresented by keywords. Their return values areDoubletype and can be used in all acceptedDoublemathematical calculations:
let aMarathon = 42.km + 195.m
print ("A marathon is \ (aMarathon) meters long")
// Print output: "A marathon is 42195.0 meters long"
Attention:
Extensions can add new computed properties, but you cannot add storage properties or add property observers to existing properties.
Constructor (initializers)
An 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 a new specified constructor or destructor to a class. Specifies that constructors and destructors must always be provided by the original class implementation.
Attention:
If you use an extension to add a constructor to a value type, you can call the default constructor in the extension constructor of a value type when the value type has provided default values to all storage properties, and no custom initializers has been 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 used to describe a geometric rectangleRect. This example also defines two helper structuresSizeand allPoint0.0of them as default values for all properties:
struct Size { var width = 0.0, height = 0.0
} struct Point { var x = 0.0, y = 0.0
} struct Rect { var origin = Point() var size = Size()
}
Because the structRectprovides default values for all its properties, as described in the default constructor, it can automatically accept a default constructor and one-by-member constructors. These constructors can be used to construct a newRectinstance:
let defaultRect = Rect() let 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 theRectstructure:
extension Rect {
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)
}
}
The new constructor firstcentercalculates an appropriate origin based on the provided value and thesizevalues. It then calls the struct's auto-member constructorinit(origin:size:), which saves the new origin and size to the appropriate properties:
let centerRect = Rect (center: Point (x: 4.0, y: 4.0),
size: Size (width: 3.0, height: 3.0))
// The origin of centerRect is (2.5, 2.5) and the size is (3.0, 3.0)
Attention:
If you use extensions to provide a new constructor, you still have the responsibility to ensure that all instances are fully initialized by the construction process.
Method (Methods)
Extensions can add new instance methods and type methods to existing types. The following exampleIntadds arepetitionsnew instance method named to the type:
extension Int {
func repetitions(task: () -> ()) { for i in 0..<self {
task()
}
}
}
Thisrepetitionsmethod uses a() -> ()single parameter of type argument, which indicates that the function has no parameters and no return value.
After you define the extension, you can call the method on any integerrepetitions, and the function is to perform a task multiple times:
3.repetitions({
print("Hello!")
})
// Hello!
// Hello!
// Hello!
You can use trailing closures to make calls more concise:
3.repetitions{
print("Goodbye!")
}
// Goodbye!
// Goodbye!
// Goodbye!
Variable instance method (mutating Instance Methods)
An instance method that is added by extension can also modify the instance itself. A method that modifies or its properties in a struct and enumeration typeselfmust label the instance method as if it weremutatingmodified from the original implementation.
The following exampleIntadds a new named modification method to the type of swiftsquareto implement a square calculation of the original value:
extension Int {
mutating func square () {
self = self * self
}
}
var someInt = 3
someInt.square ()
// someInt is now 9
Subscript (subscripts)
An extension can add a new subscript to an existing type. This exampleIntadds an integer subscript to the Swift built-in type. The subscript returns the nth[n]digit of a decimal number from right to left.
- 123456789[0] returns 9
- 123456789[1] returns 8
... Wait a minute
extension Int {
subscript(var digitIndex: Int) -> Int {
var decimalBase = 1
while digitIndex > 0 {
decimalBase *= 10
--digitIndex
}
return (self / decimalBase) % 10
}
}
746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7
If theIntvalue 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 complements 0 on the left side of the number:
746381295 [9]
// returns 0, which is equivalent to:
0746381295 [9]
Nested types (Nested Types)
Extensions can add new nested types to existing classes, structs, and enumerations:
extension Int {
enum Kind {
case Negative, Zero, Positive
}
var kind: Kind {
switch self {
case 0:
return .Zero
case let x where x > 0:
return .Positive
default:
return .Negative
}
}
}
This exampleIntadds a new nested enumeration to the. This namedKindenumeration represents the type of a particular integer. Specifically, it means that integers are positive, 0, or negative.
This example alsoIntadds a new compute instance property, that is, tokindreturn the appropriateKindenumeration member.
Now, this nested enumeration can beIntused in conjunction with a value:
func printIntegerKinds(numbers: [Int]) {
for number in numbers {
switch number.kind {
case .Negative:
print("- ", appendNewline: false)
case .Zero:
print("0 ", appendNewline: false)
case .Positive:
print("+ ", appendNewline: false)
}
}
print("")
}
printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
// prints "+ + - 0 - 0 +"
printIntegerKindsthe input to the function is anIntarray value and iterates over its characters. During each iteration, consider the computed properties of the current characterkindand print out the appropriate category description.
Note: Because of the knownnumber.kindInt.Kindtype,Int.Kindall the member values in the statement can be abbreviated in theswitchform of statements, such as Use. NegativeinsteadInt.Kind.Negative.
Attack on the swift-------------extension