Swift—扩展声明-备
声明扩展的语法格式如下:
extension 类型名 {
//添加新功能
}
声明扩展的关键字是extension,“类型名”是Swift中已有的类型,包括类、结构体和枚举,但是我们仍然可以扩展整型、浮点型、布尔型、字符串等基本数据类型,这是因为这些类型本质上也是结构体类型。打开Int的定义如下:
- struct Int : SignedInteger {
- init()
- init(_ value: Int)
- static func convertFromIntegerLiteral(value: Int) -> Int
- typealias ArrayBoundType = Int
- func getArrayBoundValue() -> Int
- static var max: Int { get }
- static var min: Int { get }
- }
从定义可见Int是结构体类型。不仅是Int类型,我们熟悉的整型、浮点型、布尔型、字符串等数据类型本质上都是结构体类型。
Swift中的扩展机制可以在原始类型中添加的新功能包括:
实例计算属性和类型计算属性
实例方法和类型方法
构造函数
下标
还有嵌套类型等内容也可以扩展,扩展还可以遵从协议。
===================================
可以在原始类型上扩展计算属性,包括实例计算属性和静态计算属性。添加计算属性的定义,与普通的计算属性的定义是一样的。
实例计算属性示例:在网络编程时,为了减少流量,从服务器端返回的不是信息描述,而是编码,然后在本地再将编码转换为描述信息。为此定义了如下Int类型扩展:
- extension Int { //定义Int类型的扩展
- var errorMessage : String { //只读计算属性
- var errorStr = ""
- switch (self) {
- case -7:
- errorStr = "没有数据。"
- case -6:
- errorStr = "日期没有输入。"
- case -5:
- errorStr = "内容没有输入。"
- case -4:
- errorStr = "ID没有输入。"
- case -3:
- errorStr = "据访问失败。"
- case -2:
- errorStr = "您的账号最多能插入10条数据。"
- case -1:
- errorStr = "用户不存在,请到http://51work6.com注册。"
- default:
- errorStr = ""
- }
- return errorStr
- }
- }
- let message = (-7).errorMessage //获得-7编码对应的描述信息
- print("Error Code : -7 , Error Message : \(message)")
注意整个-7包括负号是一个完整的实例,因此调用它的属性时需要将-7作为一个整体用小括号括起来。然而,如果是7则不需要括号。
下面再看一个静态属性的示例:
- struct Account { //定义Account结构体
- var amount : Double = 0.0 //账户金额
- var owner : String = "" //账户名
- }
- extension Account { //定义Account结构体的扩展静态
- static var interestRate : Double { //利率
- return 0.0668
- }
- }
- print(Account.interestRate) //打印输出interestRate属性
打印输出interestRate属性,访问方式与其他的静态计算属性一样,通过“类型名”加“.”来访问静态计算属性。
扩展方法
可以在原始类型上扩展方法,包括实例方法和静态方法。这些添加方法的定义与普通方法的定义是一样的。
下面先看一个示例:
- extension Double {//定义Double类型的扩展
- static var interestRate : Double = 0.0668 //利率
- func interestBy1() -> Double {
- return self * Double.interestRate //静态属性利率
- }
- mutating func interestBy2() { //定义实例方法interestBy2
- self = self * Double.interestRate
- }
- static func interestBy3(amount : Double) -> Double { //定义静态方法interestBy3
- return interestRate * amount //返回值是计算利息结果
- }
- }
- let interest1 = (10_000.00).interestBy1() //调用interestBy1方法计算利息
- print("利息1 : \(interest1)")
- var interest2 = 10_000.00 //调用interestBy2方法计算利息
- interest2.interestBy2()
- print("利息2 : \(interest2)")
- var interest3 = Double.interestBy3(10_000.00) //调用interestBy3方法计算利息
- print("利息3 : \(interest3)")
代码self = self *Double.interestRate,把计算结果直接赋值给当前实例self。在结构体和枚举类型中给self赋值会有编译错误,需要在方法前面加上mutating关键字,表明这是变异方法。
调用interestBy1方法计算利息,调用它的实例10_000.00,它的返回值被赋值给interest1常量,这是很常见的调用过程。
调用interestBy2方法计算利息,我们不能使用10_000.00实例调用,而是需要一个Double类型的变量interest2。interestBy2是变异方法,它会直接改变变量interest2的值,因此interest2.interestBy2()语句调用完成后,变量interest2的值就改变了。
调用interestBy3方法计算利息,它是静态方法,调用它需要以“类型名.”的方式即“Double.”的方式调用。
=================================
扩展类型的时候,也可以添加新的构造函数。值类型与引用类型扩展有所区别。值类型包括了除类以外的其他类型,主要是枚举类型和结构体类型。
值类型扩展构造函数
扩展结构体类型中定义构造函数的示例:
- struct Rectangle {
- var width : Double
- var height : Double
- init(width : Double, height : Double) {
- self.width = width
- self.height = height
- }
- }
- extension Rectangle { //定义了Rectangle的扩展类型
- init(length : Double) {
- self.init(width : length, height : length)
- }
- }
- var rect = Rectangle(width : 320.0, height : 480.0) //调用两个参数的构造函数,这个构造函数是原始类型提供, Rectangle类型已经是扩展类型
- print("长方形:\(rect.width) x \(rect.height)")
- var square = Rectangle(length: 500.0) //调用一个参数的构造函数,这个构造函数是扩展类型提供的
- print("正方形:\(square.width) x \(square.height)")
self.init是调用了原始类型的两个参数的构造函数。
引用类型扩展构造函数
扩展类中定义构造函数的示例:
- class Person {
- var name : String
- var age : Int
- func description() -> String {
- return "\(name) 年龄是: \(age)"
- }
- init (name : String, age : Int) {
- self.name = name
- self.age = age
- }
- }
- extension Person { //定义Person类的扩展类型
- convenience init (name : String) { //便利构造函数
- self.init(name : name, age : 8)
- }
- }
- let p1 = Person(name : "Mary") //调用两个参数的构造函数,这个构造函数是原始类型提供,这时候的Person类型已经是扩展类型。
- print("Person1 : \(p1.description())")
- let p2 = Person(name : "Tony", age : 28)// 调用一个参数的构造函数创建Person实例,这个构造函数是扩展类型提供的。
- print("Person2 : \(p2.description())")
代码self.init(name :name, age : 8)调用指定构造函数代理部分构造任务。
Swift—扩展声明-备的更多相关文章
- 《从零开始学Swift》学习笔记(Day 49)——扩展声明
原创文章,欢迎转载.转载请注明:关东升的博客 声明扩展的语法格式如下: extension 类型名 { //添加新功能 } 声明扩展的关键字是extension,“类型名”是Swift中已有的类型,包 ...
- 【iOS】Swift扩展extension和协议protocol
加上几个关节前Playground摘要码进入github在,凝视写了非常多,主要是为了方便自己的未来可以Fanfankan. Swift语法的主要部分几乎相同的. 当然也有通用的.运算符重载.ARC. ...
- Swift扩展
Swift中的「扩展」(extensions)和OC中的categories类似,只是Swift中的「扩展」没有名字.Swift中的「扩展」可以向一个已有的类/结构体/枚举类型添加新功能,这包括在没有 ...
- 27.怎样在Swift中声明typedef?
在OC中,我们经常会用typedef关键字来声明Block,例如: /** * 通用的空闭包类型,无参数,无返回值 */ typedef void (^GofVoidBlock)(void); 在Sw ...
- Swift扩展(Extension)
在现有类和结构体的类型基础上,扩展新的功能. 语法: extension SomeType{ // new functionality to add to SomeType goes here } A ...
- Swift—属性观察者-备
为了监听属性的变化,Swift提供了属性观察者.属性观察者能够监听存储属性的变化,即便变化前后的值相同,它们也能监听到. 属性观察者主要有以下两个: willSet:观察者在修改之前调用. didSe ...
- Swift 可选类型-备
我们先看看如下代码: var n1: Int = 10 n1 = nil //编译错误 let str: String = nil //编译错误 Int和String类型不能接受 ...
- Swift 可选链-备
在Swift程序表达式中会看到问号(?)和感叹号(!),它们代表什么含义呢?这些符号都与可选类型和可选链相关,下面来看看可选链. 可选链: 类图: 它们之间是典型的关联关系类图.这些类一般都是实体类, ...
- Swift中声明协议中的class关键字的作用
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 最近在Cocos2D编程for Swift中看到以下一个代码片 ...
随机推荐
- 4. c++ 静态 对象
参考自文章:http://blog.csdn.net/wpf_ml/article/details/7763534 1. 静态存储 变量定义在函数外或是用static 关键字修饰的变量存放在静态存储区 ...
- HDOJ(HDU) 2093 考试排名(Arrays.sort排序、类的应用)
Problem Description C++编程考试使用的实时提交系统,具有即时获得成绩排名的特点.它的功能是怎么实现的呢? 我们做好了题目的解答,提交之后,要么"AC",要么错 ...
- Java---IO加强(2)
转换流 ★转换流功能1:充当字节流与字符流之间的桥梁 需求:模拟英文聊天程序,要求: (1) 从键盘录入英文字符,每录一行就把它转成大写输出到控制台: (2) 保存聊天记录到字节流文件. 要求1的设计 ...
- Visual Studio创建跨平台移动应用_01.Cordova&Xamarin
目前开发移动应用有三种模式:Native.Hybird.Web,若要开发跨平台的移动应用,又希望与本地API交互,那么Hybird是一个非常好的选择. 作为一个.Net程序员, ...
- 【转】Derivation of the Normal Equation for linear regression
I was going through the Coursera "Machine Learning" course, and in the section on multivar ...
- Semaphore — Windows API
Semaphore是旗语的意思,在Windows中,Semaphore对象用来控制对资源的并发访问数.Semaphore对象具有一个计数值,当值大于0时,Semaphore被置信号,当计数值等于0时, ...
- E - Swap - hdu 2819(简单二分图匹配)
题意:如果可以交换行列,问主对角线能不能全为1 分析:要想主对角线全为1很明显要有N个行列不想同的点就行了,可以用二分图匹配计算出来多能有几个.如果小与N就不能.输出要是对的就行,不必和答案一样 ** ...
- xshell中启动linux图形界面
使用root用户执行xhost + IP为客户端机器IP,使用远程登录用户执行 DISPLAY=IP:0.0;export DISPLAY; 使用远程登录的用户执行: xhost +
- finally与return
finally关键字:和try块使用,一般做资源释放操作,比如关闭流.关闭数据库连接,释放锁. return:用于返回值. finally块可保证一定执行,当逻辑处理有返回值时,会首先执行finall ...
- AfxMessageBox和MessageBox差别
假设用MFC的话,请尽量使用afxmessagebox,由于这个全局的对话框最安全,也最方便. 可是在WIN32 SDK的情况下仅仅能使用MESSAGEBOX. MessageBox()是Win3 ...