Swift:枚举和结构体

Enumerations and Structures

github:Swift基础实例
github:SwiftBasicTableView

枚举
  1. 枚举
    enum 创建一个枚举,与类和所有其他指定的类型一样,枚举可以拥有和它相关联的方法:
enum Rank: Int {
    
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King   
}

让它包含一个和它关联的方法 simpleDescription()

enum Rank: Int {
    //enum case must declare a raw value when the preceding raw value is not an integer
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() ->String {
        switch self {
        case .Ace:
            return "ace"
        case .Jack:
            return "jack"
        case .Queen:
            return "queen"
        case .King:
            return "king"
        default:
            return String(self.rawValue)
        }
    }
}
let ace = Rank.Ace
let aceRawValue = ace.rawValue          //1
let aceString = ace.simpleDescription() //"ace"
  • 上面代码中 case Ace = 11Ace 的原始值,称为rawValue,类型是 Int,后面的枚举值依次递增,如Two就是2,依次类推。
  • 枚举的类型也可以 StringFloat类型,但是除了 Int类型之外,其他类型的rawValue 都不可以递增,每一个 enum case 都需要指定一个相应类型的值作为它的 rawValue
  1. 枚举构造器
    带有rawValueenum会自动接收一个可失败构造器 init?(rawValue:),它根据枚举其中一个 raw value,找到合适的case,生成枚举的实例对象;如果没有匹配到合适的case,则返回nil
let convertRank = Rank(rawValue: 3)
if  convertRank != nil {
      let threeDescription = convertRank.simpleDescription()
      print(threeDescription) //"3"
}
else {
      print("Have no this enum")
}
  1. 枚举的值
    在枚举中 case 后的值就是枚举实际的值,不仅仅是它们的raw value 的另一种写法。实际上,也可以不为枚举提供 raw value
enum Suit {
    case Spades, Hearts, Diamonds, Clubs
    func simpleDescription() ->String {
        switch self {
        case .Spades:
            return "spades"
        case .Hearts:
            return "hearts"
        case .Diamonds:
            return "diamonds"
        case .Clubs:
            return "clubs"
        }
    }
}
let hearts = Suit.Hearts
// 在这个枚举中,我们没有提供 `raw value` ,当强行调用 rawValue 时,编译器会把 `rawValue` 当做一个成员变量,因此会报错:找不到这个成员
// let rawValue = hearts.rawValue; 
let heartsDes = hearts.simpleDescription() //"hearts"

注意上面 Hearts 有两种被引用方式,第一种是在 switch 中,通过简写形式 .Hearts; 第二种是通过 Suit.Hearts,给 hearts赋值。第一种是因为通过 self 已经知道是 Suit,所以可以使用简写形式.Hearts;第二种由于 hearts 没有明确给出类型,所以只能写全名。因此,以下的写法也是对的:
switch self { case Suit.Hearts:......}
let heartAbb: Suit = .Hearts

  1. 枚举的关联值(associated values)
    枚举的 case 值可以存储一些和它相关的其他类型的值,称为关联值(associated values)。
    比如一个商品的条形码,条形码由4部分0-9的数字组成:第一部分是只有1个数字的数字位;第二部分是5个数字的制造位;第三部分是5个数字的产品位;第四部分是1个数字的校验位。一个二维码却可以包含所有一维码的信息,同时还可以包含一些其他信息。我们用枚举的形式来表现这个二维码:
enum Barcode {
    case UPCA(Int, Int, Int, Int)
    case QRCode(String)
}

上面代码可以理解为:一个枚举名字叫 Barcode,这个枚举包含一个值 UPCAUPCA有一个类型为(Int, Int, Int, Int) 的关联值,或者包含一个值 QRCode,QRCode 有一个类型为(String)的关联值。生成一个含有关联值的枚举对象:

var barcode = Barcode.UPCA(9, 72345, 77787, 8)
//barcode 被替换为QRCode(String),barcode 只能存储其中之一
barcode = .QRCode("abcdef")
switch barcode {
case .UPCA(let numberSystem, let manufacture, let product, let check):
       print("UPC-A: \(numberSystem) \(manufacture) \(product) \(check)")
case .QRCode(let productCode):
       print("QR Code: \(productCode)")
}
//prints "QR Code: abcdef"

如果关联值的类型都是常量(constant)变量(variable),那么只需要在 case 前写一个 letvar ,就可以了:

switch barcode {
case let .UPCA(numberSystem, manufacture, product, check):
       print("UPC-A: \(numberSystem) \(manufacture) \(product) \(check)")
case let .QRCode(productCode):
       print("QR Code: \(productCode)")
}
//prints "QR Code: abcdef"
结构体
  • 用关键字 struct 创建一个结构体。
    结构体(struct) 和 类(class)有很多相似的地方,也包含有属性、方法和初始化构造器。主要来看一下它们的不同点:
  • class 有继承,struct 没有
  • runtime 期间,根据 Type casting (类型转换),可以得知一个实例( instance)所属于的类
  • class 有析构函数,struct 没有
  • class 可以使用 ARC

最重要的,结构体属于值类型,在代码中传递的时候,每次都会被复制(copy)一份,而类是通过引用(reference)传递的:

struct Card {
    var score : Int
}

let cart      = Cart(score: 3)
var varCart   = cart
varCart.score = 5
print(cart.score) // 3
print(varCart.score) // 5

可以看到,我们把对象 cart 赋值给 varCart 后,修改 varCart 的属性值,并不会对 cart 的属性值造成影响。这和下面的 class 完全不同:

class testInit {
    
    var number = 0
    var point = 9
}

let testI    = testInit()
let testII   = testI
testII.point = 8
print(testI.point) // 8

当我们把对象 testI 赋值给 testII 后,修改 testII 的属性 point,由于类是引用类型(相应说明参考概念解释),

通过下面的代码,我们来认识 struct 中很重要的一个概念:成员构造器。(该构造器的说明请参考 概念解释)

struct Card {
    var rank : Rank
    var suit : Suit    

    func simpleDescription()-> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeDes = threeOfSpades.simpleDescription() //"The 3 of spades"

上面的代码中,我们使用了函数 Card(_: , _: ) 生成一个对象,此函数是 struct 自动接收的,称为 成员构造器 (Memberwise initializer)

需要注意到是,上面结构体内的两个属性 ranksuit 在声明时并没有初始化,而是在生成 threeOfSpades 实例对象的时候才初始化,因此,结构体只接收一个成员构造器。如果这两个属性在声明的时候已经初始化,那么,结构体将接收两个构造器:Card()Card(_: , _: ) 。少初始化任何一个属性,都只会接收一个构造器:Card(_: , _: )

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

推荐阅读更多精彩内容