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

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

枚举

枚举定义了一种包含一组相关值的公共类型。枚举是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")
}
  • 为枚举成员分配相关值
    Swift中能够为每一个枚举成员规定一个任意类型的相关值,并且为每个枚举成员规定的相关值的类型可以不同。
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).")
}
  • 为枚举分配原始值
    除了为枚举成员分配相关的值外,还能为每个枚举成员预分配一个同类型的原始值。这与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中,能够使用枚举成员的rawValue方法来获取枚举成员的原始值:

let earthsOrder = Planet.Earth.rawValue()

结构与类

  • 两者比较
    在Swift中,结构和类功能上几乎相同,两者都具有如下相同的功能:
    • 可以定义属性,用来存储值;
    • 可以定义方法,用来提供功能;
    • 可以定义一个脚本方法,用来使用脚本语法来存取它们的值;
    • 能够定义初始化方法来设置它们的初始状态;
    • 能够扩展来增加原先没有实现的功能;
    • 能够遵从相关协议来提供确定类型的标准功能。
      类在以下方面与结构存在差别:
    • 类能够继承,一个类能够继承它的超类的特性,而结构不能继承;
    • 类允许在运行时检查和解释一个类实例的类型;
    • 类可以带有析构函数,允许类的实例释放它所分配的任何资源;
    • 引用计数允许一个类实例有多个引用。
    • 结构在代码中总是以复制方式来传递,而不使用引用计数。
  • 类和结构的定义和实例化
    类和结构的定义采用相似的语法,类使用class关键字来指示,结构使用struct关键字来指示。
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
  • 结构、类与枚举的类型
    在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语言中类似的指针符号’*’,用来代表一个引用或指针。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容