Swift语言中,具有类特征的类型包含三种,即枚举类型、结构类型(包含基本类型,基本类型实际都是结构类型的特例)、类。当中枚举类型、结构类型是属于值类型,类属于引用类型。三种类型都可以加入�属性、方法、下标方法,可以使用扩展进行功能扩展,使用协议等。
一、 枚举
枚举定义了一种包括一组相关值的公共类型。枚举是Swift中的一种与类类似的类型,具有很多传统类才有的特征,比如计算属性、实例方法,可以通过扩展或协议增强功能等。
1.1 枚举定义
Swift 语言的枚举类型的定义语法例如以下:
enum CompassPoint { case North case South case East case West }
枚举语法以一个keywordenum来标识,enum后面包括一个枚举类型名字,枚举定义所有放到一对大括号里。
在枚举中定义的值称为枚举成员值,用casekeyword来指示一个新的枚举成员值。
与C和Objective-C语言的枚举类型不同的是:在Swift中不须要为枚举成员分配一个默认的整数值。
假设为枚举成员提供值,该值能够是一个字符串、一个字符或者是一个随意整数或浮点数。
枚举成员值能够定义到一行中,并用逗号切割。
enum Planet { case Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune }
每一个新定义的枚举都属于一种新的独立的类型。
1.2 枚举的使用
能够为一个常量或变量分配一种枚举类型的值,如:
var directionToHead =CompassPoint.West
以上定义的变量directionToHead能够判断为是一种CompassPoint类型的枚举变量,因此你能够设置该变量为CompassPoint类型的其他值,如:
directionToHead = .East //枚举类型被省略
枚举也可以在switch语句中使用,用来匹配独立的枚举值:
directionToHead = .South switch directionToHead { case .North: println(“Lots of planets have a north”) case .South: println(“Watch out for penguins”) case .East: println(“Where the sun rises”) case .West: println(“Where the skies are blue”) }
1.3 为枚举成员分配相关值
Swift中可以为每个枚举成员规定一个随意类型的相关值,而且为每个枚举成员规定的相关值的类型可以不同。
enum Barcode { case UPCA(Int,Int,Int) case QRCode(String) }
该样例定义了一个类型为Barcode的枚举类型,并定义了两个枚举值UPCA 和QRCode,并能够为枚举值UPCA 分配一个多元组类型的相关值,为QRCode分配一个字符串类型的相关值,该样例没有为枚举值本身指定不论什么类型的值。
能够使用以上定义的枚举为一个常量或变量赋值,如:
var productBarcode =Barcode.UPCA(8,85909_51226,3)
该样例为变量 productBarcode分配了一个Barcode.UPCA枚举值,为其分配的相关的多元组类型的值为(8,85909_51226,3)。
然后该变量productBarcode能够设置为带字符串类型相关值的另外的一个枚举值:
productBarcode = .QRCode(“ABCDEFGHIJKLMNOP”)
还能够在switch语句中使用该枚举,并通过绑定常量或变量的方式引出其带有的相关类型的值:
switch productBarcode { case .UPCA(let numberSystem,let identifier,let check): println(“UPC-A with value of(numberSystem),(identifier),(check).”) case .QRCode(let productCode): println(“QR code with value of(productCode).”) }
假设枚举成员的全部的相关值都作为常量被引出,或者全部的相关值都作为变量形式被引出,以上语法还能够简写为例如以下形式:
switch productBarcode { case let .UPCA(numberSystem,identifier,check): println(“UPC-A with value of(numberSystem),(identifier),(check).”) case let .QRCode(productCode): println(“QR code with value of(productCode).”) }
1.4 为枚举分配原始值
除了为枚举成员分配相关的值外,还能为每一个枚举成员预分配一个同类型的原始值。这与C 语言为枚举成员分配一个整数值类似,但Swift定义的原始值的类型能够是字符串、字符、或随意的整数或浮点数类型等,如:
enum ASCIIControlCharacter:Character { case Tab =“t” case LineFeed =“n” case CarriageReturn =“r” }
该样例中,定义了一个含有三个枚举成员的枚举类型ASCIIControlCharacter,并指定其原始类型为字符类型,并为每一个枚举成员分配一个字符类型的默认原始值。
与C语言为枚举成员指定值类似,Swift要求为枚举的每一个枚举成员分配的原始值必须在枚举声明内唯一。当使用整数类型的原始值时,枚举成员的其他原始值假设没有指定,其可以在第一个枚举成员定义值的基础上自己主动加1,例如以下所看到的:
enum Planet:Int { case Mercury =1,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune }
为枚举成员定义的原始值与为枚举成员分配的相关值不同,枚举成员的原始值是在枚举第一次定义时被分配的,而枚举成员的相关值尽管其类型也是在枚举定义时指定,但其值是在使用枚举类型创建一个常量或变量时设置的。
在Swift中,可以使用枚举成员的toRaw方法来获取枚举成员的原始值:
let earthsOrder = Planet.Earth.toRaw()
相反,也能够使用枚举类型的fromRaw方法来返回相应原始值的枚举成员,该方法返回的是一个选项,由于其值可能存在也可能不存在。例如以下所看到的。
let possiblePlanet =Planet.fromRaw(9)
// 返回相应原始值为9的枚举Planet的枚举成员。返回的是一个Planet? 选项类型,在样例所看到的情况下该值不存在,返回的是一个nil。
二 结构与类
2.1 两者比較
在Swift中,结构和类功能上差点儿同样,两者都具有例如以下同样的功能:
1) 能够定义属性,用来存储值; 2) 能够定义方法,用来提供功能; 3) 能够定义一个脚本方法,用来使用脚本语法来存取它们的值; 4) 可以定义初始化方法来设置它们的初始状态; 5) 可以扩展来添加�原先没有实现的功能; 6) 可以遵从相关协议来提供确定类型的标准功能。
类在下面方面与结构存在区别:
1) 类可以继承,一个类可以继承它的超类的特性,而结构不能继承; 2) 类同意在执行时检查和解释一个类实例的类型; 3) 类能够带有析构函数,同意类的实例释放它所分配的不论什么资源; 4) 引用计数同意一个类实例有多个引用。 5) 结构在代码中总是以复制方式来传递,而不使用引用计数。
2.2 类和结构的定义和实例化
类和结构的定义採用相似的语法,类使用classkeyword来指示,结构使用structkeyword来指示。
struct Resolution { var width =0 var height =0 } class VideoMode { var resolution =Resolution() var interlaced =false var frameRate =0.0 var name:String? }
每一个新定义的类或结构都定义了一种新的类型。
上面样例定义了一种称作Resolution的新的结构类型,当中包括和定义了两个变量类型的属性。还定义了一个称作VideoMode的新类,该类定义和包括四个变量类型的属性,其第一个属性resolution还使用了刚刚定义的结构Resolution的实例进行了初始化。
类和结构中定义的变量或常量类型的属性像通常变量和常量一样进行初始化和赋值,属性的类型能够依据为其提供的初始值进行判断。
为类和结构创建实例的语法同样:
let someResolution =Resolution() let someVideoMode =VideoMode()
该样例採用了结构和类初始化最简单的语法形式(结构和类的类型名面跟着一对圆括号)。该初始化语法为结构和类创建了一个新的各自的实例,并赋值给两个常量,两个实例的属性也在该初始化方法中被初始化为它们的默认值。
在Swift中,全部的结构类型都会自己主动产生一个參数初始化方法,能够使用该方法来初始化和创建结构的新的实例及其成员属性,新创建实例的属性的初始值使用该初始化方法的參数传进来的值,如:
let vga =Resolution(width:640,height:480)。
而类没有提供相相应的默认的參数初始化方法。
在Swift中,与脚本语言类似,能够使用点语法的形式来存取一个结构或类实例的属性以及子属性,即读取和设置其值:
读取属性的值:
println(“The width of someResolution is(someResolution.width)”)
println(“The width of someVideoMode is(someVideoMode.resolution.width)”) 设置一个属性的值:
someVideoMode.resolution.width = 1280
2.3 结构、类与枚举的类型
在Swift中,结构和枚举与其他基本类型(整型、浮点类型、布尔类型、字符串、数组和词典,这些类型事实上都是以结构类型实现的)一样属于值类型。这意味着它们在分配给一个变量或常量时或当它作为參数传送给一个函数时,它们的实例以及它们包括的全部作为值类型的属性一一被拷贝。
在Swift中,为了提供性能,拷贝採用延迟拷贝的机制,即在实际用到时才拷贝。
let hd = Resolution(width:1920, height:1080)
var cinema =hd
在该样例中,由于Resolution是一个结构类型,因此常量hd和变量cinema属于Resolution结构类型的不同实例,由于在为变量cinema赋值时发生了拷贝行为。
与结构和枚举不同,类的类型属于引用类型。引用类型的实例在分配给一个变量或常量时或当它作为參数传送给一个函数时,没有拷贝发生。
let tenEighty =VideoMode()
tenEighty.frameRate = 25.0
let alsoTenEighty =tenEighty
alsoTenEighty.frameRate =30.0
因为VideoMode属于类,因此如今两个常量tenEighty和alsoTenEighty引用的是同样的VideoMode实例,仅仅是相应同样实例的不同的名字,因此这两个常量的属性值frameRate如今都等于30.0。
注意上面的tenEighty和alsoTenEighty被声明为两个常量,而不是变量,这是由于tenEighty和alsoTenEighty本身存储的仅仅是VideoMode的实例的引用值,而不是VideoMode实例本身,因此你通过它们对引用的类实例的属性的改变,改变是类实例本身的属性,而不是引用本身。
因为类是引用类型,就如以上样例所看到的,多个变量或常量可能引用一个类的同样的实例。为了推断两个常量或变量是否引用的是一个类的同样实例,Swift提供了两个引用比較操作符: ‘===’与 ‘!==’。能够使用这两个操作符来检查两个常量或变量是否引用的是同样的实例:
if tenEighty ===alsoTenEighty { println(“tenEighty and alsoTenEighty refer to the same Resolution instance.”) }
在Swift中,一个常量或变量引用一个类的实例,这与C语言中的指针类似,但在Swift 中,引用不是直接指向内存中一个地址,因此不须要使用C语言中类似的指针符号’*’,用来代表一个引用或指针。
版权全部,请转载是清楚注明链接和出处,谢谢!
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/119158.html原文链接:https://javaforall.cn