swift学习-枚举、结构体、类

2015-08-13  本文已影响427人  JaneJie

Swift语言中,具有类特征的类型包括三种,即枚举类型、结构类型(包括基本类型,基本类型实际都是结构类型的特例)、类。其中枚举类型、结构类型是属于值类型,类属于引用类型。三种类型都可以添加属性、方法、下标方法,能够使用扩展进行功能扩展,使用协议等。

枚举

枚举定义了一种包含一组相关值的公共类型。枚举是Swift中的一种与类类似的类型,具有许多传统类才有的特征,例如计算属性、实例方法,能够通过扩展或协议增强功能等。

enum CompassPoint {
   case North
   case South
   case East
   case West
}

枚举语法以一个关键字enum来标识,enum后面包含一个枚举类型名字,枚举定义全部放到一对大括号中。 在枚举中定义的值称为枚举成员值,用case关键字来指示一个新的枚举成员值。 与C和Objective-C语言的枚举类型不同的是:在Swift中不需要为枚举成员分配一个默认的整数值。 如果为枚举成员提供值,该值可以是一个字符串、一个字符或者是一个任意整数或浮点数。枚举成员值可以定义到一行中,并用逗号分割。

enum Planet {
   case Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune
}
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")
}
enum Barcode {
   case UPCA(Int,Int,Int)
   case QRCode(String)
}

该例子定义了一个类型为Barcode的枚举类型,并定义了两个枚举值UPCA 和QRCode,并可以为枚举值UPCA 分配一个多元组类型的相关值,为QRCode分配一个字符串类型的相关值,该例子没有为枚举值本身指定任何类型的值。
可以使用以上定义的枚举为一个常量或变量赋值,如:

var productBarcode =Barcode.UPCA(8,85909_51226,3)

还可以在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).")
}
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中,能够使用枚举成员的rawValue方法来获取枚举成员的原始值:

let earthsOrder = Planet.Earth.rawValue()

结构与类

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
 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语言中类似的指针符号’*’,用来代表一个引用或指针。

上一篇 下一篇

猜你喜欢

热点阅读