瑞丽住建局网站,wordpress前后台域名分离,住房和城乡建设部关于资质延期,如何做好公司网站建设49-拓展#xff08;1#xff09;
扩展概述
扩展可以为在当前 package 可见的类型#xff08;除函数、元组、接口#xff09;添加新功能。
当不能破坏被扩展类型的封装性#xff0c;但希望添加额外的功能时#xff0c;可以使用扩展。
可以添加的功能包括#xff1a; …49-拓展1
扩展概述
扩展可以为在当前 package 可见的类型除函数、元组、接口添加新功能。
当不能破坏被扩展类型的封装性但希望添加额外的功能时可以使用扩展。
可以添加的功能包括
添加成员函数添加操作符重载函数添加成员属性实现接口
扩展虽然可以添加额外的功能但不能变更被扩展类型的封装性因此扩展不支持以下功能
扩展不能增加成员变量。扩展的函数和属性必须拥有实现。扩展的函数和属性不能使用 open、override、 redef修饰。扩展不能访问被扩展类型中 private 修饰的成员。
根据扩展有没有实现新的接口扩展可以分为 直接扩展 和 接口扩展 两种用法直接扩展即不包含额外接口的扩展接口扩展即包含接口的扩展接口扩展可以用来为现有的类型添加新功能并实现接口增强抽象灵活性。
直接拓展
对类型直接进行拓展称为直接拓展。
简单拓展
这里演示一个比较简单的拓展类型的用法。 给String类型拓展一个printSize的方法。
需要注意的是String类型本身具有size属性所以 this.size不会出错
extend String {public func printSize() {println(the size is ${this.size})}
}main() {let a 123a.printSize() // the size is 3
}泛型拓展
当被拓展的类型是泛型时提供了两种方式对泛型类型进行拓展。
针对特定泛型实例化类型进行扩展extend 后面引入泛型形参的泛型扩展
两种区别主要在写法不同上
针对特定泛型实例化类型进行扩展
针对特定泛型实例化类型进行扩展关键字 extend 后允许带一个任意实例化完全的泛型类型。为这些类型增加的功能只有在类型完全匹配时才能使用且泛型类型的类型实参必须符合泛型类型定义处的约束要求。
如下列代码 A是B的父类。B必定包含A所有的实现所以where的约束生效。
open class A {func a() {return true}
}class B : A {func b() {return true}
}class FooT where T : A {}extend FooB {} main() {var a FooB()
}extend 后面引入泛型形参的泛型扩展
在 extend 后面引入泛型形参的泛型扩展。泛型扩展可以用来扩展未实例化或未完全实例化的泛型类型。在 extend 后声明的泛
型形参必须被直接或间接使用在被扩展的泛型类型上。为这些类型增加的功能只有在类型和约束完全匹配时才能使用。
class MyListT {public let data: ArrayT ArrayT()
}extendT MyListT {} // OK
extendR MyListR {} // OK
extendT, R MyList(T, R) {} // OK例如可以定义一个叫 Pair 的类型这个类型可以方便地存储两个元素类似于 Tuple。
希望 Pair 类型可以容纳任何类型因此两个泛型变元不应该有任何约束这样才能保证 Pair 能容纳所有类型。
但同时又希望当两个元素可以判等的时候让 Pair 也可以判等这时就可以用扩展来实现这个功能。
如下面的代码所示使用扩展语法约束了 T1 和 T2 在支持 equals 的情况下Pair 也可以实现 equals 函数。
class PairT1, T2 {var first: T1var second: T2public init(a: T1, b: T2) {first asecond b}
}interface EqT {func equals(other: T): Bool
}extendT1, T2 PairT1, T2 where T1 : EqT1, T2 : EqT2 {public func equals(other: PairT1, T2) {first.equals(other.first) second.equals(other.second)}
}class Foo : EqFoo {public func equals(other: Foo): Bool {true}
}main() {let a Pair(Foo(), Foo())let b Pair(Foo(), Foo())println(a.equals(b)) // true
}接口扩展
拓展泛型的同时一并实现泛型称为接口拓展。
interface PrintSizeable {func printSize(): Unit
}extendT ArrayT : PrintSizeable {public func printSize() {println(The size is ${this.size})}
}当使用扩展为 Array 实现 PrintSizeable 之后就相当于在 Array 定义时实现接口 PrintSizeable。
因此可以将 Array 作为 PrintSizeable 的实现类型来使用了如以下代码所示。
main() {let a: PrintSizeable ArrayInt64()a.printSize() // 0
}可以在同一个扩展内同时实现多个接口多个接口之间使用 分开接口的顺序没有先后关系。
如下面代码所示可以在扩展中为 Foo 同时实现 I1、I2、I3。
interface I1 {func f1(): Unit
}interface I2 {func f2(): Unit
}interface I3 {func f3(): Unit
}class Foo {}extend Foo : I1 I2 I3 {public func f1(): Unit {}public func f2(): Unit {}public func f3(): Unit {}
}也可以在接口扩展中声明额外的泛型约束来实现一些特定约束下才能满足的接口。
例如可以让上面的 Pair 类型实现 Eq 接口这样 Pair 自己也能成为一个符合 Eq 约束的类型如下代码所示。
class PairT1, T2 {var first: T1var second: T2public init(a: T1, b: T2) {first asecond b}
}interface EqT {func equals(other: T): Bool
}extendT1, T2 PairT1, T2 : EqPairT1, T2 where T1 : EqT1, T2 : EqT2 {public func equals(other: PairT1, T2) {first.equals(other.first) second.equals(other.second)}
}class Foo : EqFoo {public func equals(other: Foo): Bool {true}
}main() {let a Pair(Foo(), Foo())let b Pair(Foo(), Foo())println(a.equals(b)) // true
}