美文网首页iOS Developer
swift入门20 拓展

swift入门20 拓展

作者: C93zzo | 来源:发表于2017-04-26 16:27 被阅读14次

Extensions are similar to categories in Objective-C. (Unlike Objective-C categories, Swift extensions do not have names.)

swift的拓展有点像oc中的类别(categories),但是跟类别不同的是,swift拓展没有名字。

Extensions in Swift can:

Add computed instance properties and computed type properties

Define instance methods and type methods

Provide new initializers

Define subscripts

Define and use new nested types

Make an existing type conform to a protocol

swift拓展的功能:

增加组合实例属性和组合类型属性

定义实例方法和类型方法

提供新的初始化方法

定义订阅

定义和使用新的嵌套类型

使当前类型遵守某个协议

In Swift, you can even extend a protocol to provide implementations of its requirements or add additional functionality that conforming types can take advantage of.

在swift中,你甚至可以拓展一个协议,实现该协议要求的功能,或者增加额外的功能供遵循协议的类型来使用。

拓展语法

使用extension关键字声明拓展:

extension SomeType {
    // new functionality to add to SomeType goes here
}

An extension can extend an existing type to make it adopt one or more protocols. To add protocol conformance, you write the protocol names the same way as you write them for a class or structure:

拓展可以拓展一个已经存在的类型,使其能遵循一个或多个协议。 为了使其能遵循协议,只需把协议的名字写在该类型的后面,以冒号隔开:

extension SomeType: SomeProtocol, AnotherProtocol {
    // implementation of protocol requirements goes here
}

An extension can be used to extend an existing generic type

拓展可以用于拓展范型。

计算属性

Extensions can add computed instance properties and computed type properties to existing types. This example adds five computed instance properties to Swift’s built-in Double type, to provide basic support for working with distance units:

拓展可以为已有类型增加计算实例属性和计算类型属性。下面的例子给swift的double类型添加了五种实例类型。

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")
// Prints "One inch is 0.0254 meters"
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
// Prints "Three feet is 0.914399970739201 meters"

let aMarathon = 42.km + 195.m
print("A marathon is \(aMarathon) meters long")
// Prints "A marathon is 42195.0 meters long"

These computed properties express that a Double value should be considered as a certain unit of length. Although they are implemented as computed properties, the names of these properties can be appended to a floating-point literal value with dot syntax, as a way to use that literal value to perform distance conversions.

这些计算属性表示一个double值应当被看作一个长度单位。虽然它们被当作计算属性,但它们的名字可以用点语法加到一个浮点值之后,

In this example, a Double value of 1.0 is considered to represent “one meter”. This is why the m computed property returns self—the expression 1.m is considered to calculate a Double value of 1.0.

在此例子中,一个1.0的double值用来表示“1米”。这就是为什么计算属性m返回它本身(self)—表达式1.m表示一个double值1.0.

Other units require some conversion to be expressed as a value measured in meters. One kilometer is the same as 1,000 meters, so the km computed property multiplies the value by 1_000.00 to convert into a number expressed in meters. Similarly, there are 3.28084 feet in a meter, and so the ft computed property divides the underlying Double value by 3.28084, to convert it from feet to meters.

其他的单位需要一些转换来表示以米为单位的值。1千米One kilometer等同于1000米(1,000 meters),所以计算属性km把它的值乘以1000,以此转换为一个以米为单位的数。相似的,一米等于3.28084英尺,所以计算属性ft把它的值除以3.28084,以此把英尺转换为米。

These properties are read-only computed properties, and so they are expressed without the get keyword, for brevity. Their return value is of type Double, and can be used within mathematical calculations wherever a Double is accepted:

这些属性都是只读的计算属性,所以,为了简便,它们都没有get关键字。它们的返回值是double类型

let aMarathon = 42.km + 195.m
print("A marathon is \(aMarathon) meters long")
// Prints "A marathon is 42195.0 meters long"

初始化方法

Extensions can add new initializers to existing types. This enables you to extend other types to accept your own custom types as initializer parameters, or to provide additional initialization options that were not included as part of the type’s original implementation.

拓展可以给已存在的类型增加初始化方法。这使得你可以拓展其他类型把你的自定义类型当作初始化方法参数来接收,或者提供额外的初始化选项—不作为类的初始实现的一部分。

Extensions can add new convenience initializers to a class, but they cannot add new designated initializers or deinitializers to a class. Designated initializers and deinitializers must always be provided by the original class implementation.

拓展可以给一个类添加一个新的便捷初始化方法,但是拓展不能提供指定初始化方法或析构方法。指定初始化方法和析构方法必须由最初的类实现提供。

The example below defines a custom Rect structure to represent a geometric rectangle. The example also defines two supporting structures called Size and Point, both of which provide default values of 0.0 for all of their properties:

下面的例子定义了一个Rect结构,代表一个几何区域。例子还定义了两个结构Size 和Point,这两个结构都把它们的所有属性的默认值设为0.0:

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 Rect structure provides default values for all of its properties, it receives a default initializer and a memberwise initializer automatically, as described in Default Initializers. These initializers can be used to create new Rect instances:

由于Rect结构为它的所有属性提供默认值,他自动接收一个默认的初始化方法和一个逐一成员初始化方法。这些初始化方法可以用来创建一个新的Rect实例。

let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
                          size: Size(width: 5.0, height: 5.0))

You can extend the Rect structure to provide an additional initializer that takes a specific center point and size:

你可以拓展一个Rect结构,增加一个额外的初始化方法---接收一个特定的中心点(center point)和大小(size):

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)
    }
}

This new initializer starts by calculating an appropriate origin point based on the provided center point and size value. The initializer then calls the structure’s automatic memberwise initializer init(origin:size:), which stores the new origin and size values in the appropriate properties:

这个新的初始化方法由计算一个基于提供的中心点和大小值得到的合适的原始点(origin point)。这个初始化方法接着会调用该结构的自动的逐一成员初始化方法init(origin:size:),此方法把新的origin和size值保存到合适的属性:

let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
                      size: Size(width: 3.0, height: 3.0))
// centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)

方法

Extensions can add new instance methods and type methods to existing types. The following example adds a new instance method called repetitions to the Int type:

拓展可以为已存在的类型增加新的实例方法和类型方法。下面的例子为int类型添加了一个新的实例方法repetitions:

extension Int {
    func repetitions(task: () -> Void) {
        for _ in 0..<self {
            task()
        }
    }
}

The repetitions(task:) method takes a single argument of type () -> Void, which indicates a function that has no parameters and does not return a value.

repetitions(task:) 方法接收一个 () -> Void类型的参数,该参数是一个没有参数也没有返回值的函数。

After defining this extension, you can call the repetitions(task:) method on any integer to perform a task that many number of times:

定义了这个拓展之后,你可以在任何的整数(integer)上调用repetitions(task:) 方法:

3.repetitions {
    print("Hello!")
}
// Hello!
// Hello!
// Hello!

修改实例方法

Instance methods added with an extension can also modify (or mutate) the instance itself. Structure and enumeration methods that modify self or its properties must mark the instance method as mutating, just like mutating methods from an original implementation.

拓展中添加的实例方法也可以修改实例本身。修改self或属性的结构和枚举方法必须表明此实例方法是mutating的。

The example below adds a new mutating method called square to Swift’s Int type, which squares the original value:

下面的例子给swift的int类型添加了一个新的mutating方法square—用于计算初始值的平方:

extension Int {
    mutating func square() {
        self = self * self
    }
}
var someInt = 3
someInt.square()
// someInt is now 9

脚本

Extensions can add new subscripts to an existing type. This example adds an integer subscript to Swift’s built-in Int type. This subscript [n] returns the decimal digit n places in from the right of the number:

123456789[0] returns 9

123456789[1] returns 8

…and so on:

拓展可以给已存在的类型添加新的脚本。下面的例子给swift内置的int类型增加了一个整数脚本。subscript [n]返回数字右边第n位的十进制数:

123456789[0] 返回 9

123456789[1] 返回 8

以此类推

extension Int {
    subscript(digitIndex: Int) -> Int {
        var decimalBase = 1
        for _ in 0..<digitIndex {
            decimalBase *= 10
        }
        return (self / decimalBase) % 10
    }
}
746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7

If the Int value does not have enough digits for the requested index, the subscript implementation returns 0, as if the number had been padded with zeros to the left:

如果int值没有足够的值可供请求,那么脚本返回0,就像这个数字的左边添加了0:

746381295[9]
// returns 0, as if you had requested:
0746381295[9]

嵌套类型

Extensions can add new nested types to existing classes, structures, 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 example adds a new nested enumeration to Int. This enumeration, called Kind, expresses the kind of number that a particular integer represents. Specifically, it expresses whether the number is negative, zero, or positive.

这个例子给int添加了一个新的枚举。这个枚举称为Kind,表示此整数代表的类型。具体说来就是,它表示一个数是正的,0,或是负的。

This example also adds a new computed instance property to Int, called kind, which returns the appropriate Kind enumeration case for that integer.

这个例子还给int添加一个新的计算实例属性,kind,这个属性返回此整数的Kind枚举值。

The nested enumeration can now be used with any Int value:

这个嵌套枚举现在可以用于任何int值。

func printIntegerKinds(_ numbers: [Int]) {
    for number in numbers {
        switch number.kind {
        case .negative:
            print("- ", terminator: "")
        case .zero:
            print("0 ", terminator: "")
        case .positive:
            print("+ ", terminator: "")
        }
    }
    print("")
}
printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
// Prints "+ + - 0 - 0 + "

相关文章

网友评论

    本文标题:swift入门20 拓展

    本文链接:https://www.haomeiwen.com/subject/syaizttx.html