Swift4.2语言规范(二十二) 扩展
扩展为现有的类,结构,枚举或协议类型添加新功能。这包括扩展您无法访问原始源代码的类型的能力(称为追溯建模)。扩展类似于Objective-C中的类别。(与Objective-C类别不同,Swift扩展没有名称。) Swift中的扩展可以:
在Swift中,您甚至可以扩展协议以提供其需求的实现,或者添加符合类型可以利用的其他功能。有关更多详细信息,请参阅协议扩展。 注意 扩展可以为类型添加新功能,但它们不能覆盖现有功能。 扩展语法使用 1 extension SomeType { 2 // new functionality to add to SomeType goes here 3 } 扩展可以扩展现有类型以使其采用一个或多个协议。要添加协议一致性,请按照为类或结构编写协议名称的方式编写协议名称: 1 extension SomeType: SomeProtocol,AnotherProtocol { 2 // implementation of protocol requirements goes here 3 } 在添加协议与扩展的一致性中描述了以这种方式添加协议一致性。 扩展可用于扩展现有泛型类型,如扩展泛型类型中所述。您还可以扩展泛型类型以有条件地添加功能,如使用Generic Where子句的扩展中所述。 注意 如果定义扩展以向现有类型添加新功能,则新功能将在该类型的所有现有实例上可用,即使它们是在定义扩展之前创建的。 计算属性扩展可以将计算实例属性和计算类型属性添加到现有类型。此示例向Swift的内置 1 extension Double { 2 var km: Double { return self * 1_000.0 } 3 var m: Double { return self } 4 var cm: Double { return self / 100.0 } 5 var mm: Double { return self / 1_000.0 } 6 var ft: Double { return self / 3.28084 } 7 } 8 let oneInch = 25.4.mm 9 print("One inch is (oneInch) meters") 10 // Prints "One inch is 0.0254 meters" 11 let threeFeet = 3.ft 12 print("Three feet is (threeFeet) meters") 13 // Prints "Three feet is 0.914399970739201 meters" 这些计算的属性表示 在该示例中, 其他单位需要一些转换表示为以米为单位的值。一公里与1,000米相同,因此 这些属性是只读的计算属性,因此 1 let aMarathon = 42.km + 195.m 2 print("A marathon is (aMarathon) meters long") 3 // Prints "A marathon is 42195.0 meters long" 注意 扩展可以添加新的计算属性,但它们不能添加存储的属性,也不能将属性观察器添加到现有属性。 初始化器扩展可以为现有类型添加新的初始化程序。这使您可以扩展其他类型以接受您自己的自定义类型作为初始化参数,或者提供未包含在类型的原始实现中的其他初始化选项。 扩展可以为类添加新的便利初始化器,但是它们不能向类中添加新的指定初始化器或取消初始化器。指定的初始化程序和取消初始化程序必须始终由原始类实现提供。 如果使用扩展将初始值设定项添加到为其所有存储属性提供默认值的值类型,并且未定义任何自定义初始值设定项,则可以在扩展程序的初始值设定项中调用该值类型的默认初始化程序和成员初始值设定项。如果您已将初始化程序编写为值类型的原始实现的一部分,则不会出现这种情况,如值类型的初始化程序委派中所述。 如果使用扩展将初始化程序添加到在另一个模块中声明的结构,则新的初始化 下面的示例定义了一个 1 struct Size { 2 var width = 0.0,height = 0.0 3 } 4 struct Point { 5 var x = 0.0,y = 0.0 6 } 7 struct Rect { 8 var origin = Point() 9 var size = Size() 10 } 由于 1 let defaultRect = Rect() 2 let memberwiseRect = Rect(origin: Point(x: 2.0,y: 2.0),3 size: Size(width: 5.0,height: 5.0)) 您可以扩展 1 extension Rect { 2 init(center: Point,size: Size) { 3 let originX = center.x - (size.width / 2) 4 let originY = center.y - (size.height / 2) 5 self.init(origin: Point(x: originX,y: originY),size: size) 6 } 7 } 这个新的初始化程序首先根据提供的 1 let centerRect = Rect(center: Point(x: 4.0,y: 4.0),2 size: Size(width: 3.0,height: 3.0)) 3 // centerRect‘s origin is (2.5,2.5) and its size is (3.0,3.0) 注意 如果您提供带有扩展的新初始化程序,则您仍然有责任确保在初始化程序完成后每个实例都已完全初始化。 方法扩展可以向现有类型添加新的实例方法和类型方法。以下示例添加了一个调用 1 extension Int { 2 func repetitions(task: () -> Void) { 3 for _ in 0..<self { 4 task() 5 } 6 } 7 } 该 定义此扩展后,您可以 1 3.repetitions { 2 print("Hello!") 3 } 4 // Hello! 5 // Hello! 6 // Hello! 变异实例方法添加扩展的实例方法也可以修改(或改变)实例本身。修改的结构和枚举方法 下面的例子添加了一个名为 1 extension Int { 2 mutating func square() { 3 self = self * self 4 } 5 } 6 var someInt = 3 7 someInt.square() 8 // someInt is now 9 标扩展可以向现有类型添加新下标。此示例向Swift的内置
…等等: 1 extension Int { 2 subscript(digitIndex: Int) -> Int { 3 var decimalBase = 1 4 for _ in 0..<digitIndex { 5 decimalBase *= 10 6 } 7 return (self / decimalBase) % 10 8 } 9 } 10 746381295[0] 11 // returns 5 12 746381295[1] 13 // returns 9 14 746381295[2] 15 // returns 2 16 746381295[8] 17 // returns 7 如果该 1 746381295[9] 2 // returns 0,as if you had requested: 3 0746381295[9] 嵌套类型扩展可以向现有类,结构和枚举添加新的嵌套类型 1 extension Int { 2 enum Kind { 3 case negative,zero,positive 4 } 5 var kind: Kind { 6 switch self { 7 case 0: 8 return .zero 9 case let x where x > 0: 10 return .positive 11 default: 12 return .negative 13 } 14 } 15 } 此示例将新的嵌套枚举添加到 此示例还为 嵌套枚举现在可以与任何 1 func printIntegerKinds(_ numbers: [Int]) { 2 for number in numbers { 3 switch number.kind { 4 case .negative: 5 print("- ",terminator: "") 6 case .zero: 7 print("0 ",terminator: "") 8 case .positive: 9 print("+ ",terminator: "") 10 } 11 } 12 print("") 13 } 14 printIntegerKinds([3,19,-27,0,-6,7]) 15 // Prints "+ + - 0 - 0 + " 此函数 注意
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |