一.枚举简介
原始值不会占用枚举的内存空间的,即原始值不会存储在枚举里面(是在编译期间就确定了值并存储在了静态区)
关联值会存储在枚举里面,即真正使用了枚举的内存空间
enum Sorce {
case num(Int) //后面直接带(Int)的叫关联值, enum Sorce : Int 这种叫原始值
case char(Character)
case other(Int, String)
}
var s = Sorce.num(1)
s = .char("B")
s = .other(18, "小芳")
switch s {
case let .num(i):
print(i)
case let .char(i):
print(i)
case .other(let i, var str):
print(i, str)
}
// :(冒号)用来指定原始值的类型
// 如果枚举的原始值类型是Int或者String,那么Swift会自动分配原始值
enum RawEnum : Character {
case one = "A"
case two = "B"
case three = "c"
}
let aRawEnum = RawEnum.one
print("-----------\(aRawEnum)")
print(aRawEnum.rawValue)
print(RawEnum.three.rawValue)
// 如果想要得到oc那种int类型并且自动增加,那么加上 :Int ----> 如果枚举的原始值类型是Int或者String,那么Swift会自动分配原始值
enum Oc : Int{
case one
case two
case three
}
print("+++++++++++++\(Oc.two.rawValue)")//自动赋值了1
二.挖一下
定义一个简单的枚举
enum Oc : Int{
case one = 10
case two
}
print(Oc.one) //one
print(Oc.one.rawValue) //10
}
看下它的sil
enum Oc : Int {
case one
case two
init?(rawValue: Int)
typealias RawValue = Int
var rawValue: Int { get }
}
在init方法里面已经确定了one的rawValue为10,也就是说原始值是在编译期已经决定了它的值
图片.png
图片.png
三.关联值的大小
// demo
enum Password{
case num(Int, Int, Int, Int)
case other
}
var pwd = Password.num(1, 2, 3, 4)
MemoryLayout.size(ofValue: pwd) //33
pwd = .other
MemoryLayout.size(ofValue: pwd) //33
MemoryLayout<Password>.size //33 -> 实际使用的大小
MemoryLayout<Password>.stride //40 -> 实际分配的大小 经过了内存对齐
MemoryLayout<Password>.alignment //8 -> 对齐的基数为 8
四.小小问题
var d1 : Int? = 10 //d1 包含一个可选盒子和int值
var d2 : Int?? = d1 //d2 包含一个可选盒子,这个可选盒子里面又包含 一个可选盒子和int值,即 d1
var d3 : Int?? = 10
print(d2 == d3) //ture
var e1 : Int? = nil
var e2 : Int?? = e1 //e2包装了e1
var e3 : Int?? = nil
print(e2 == e3) //false 因为nil比较特殊,Int??=nil 等价于 int??=nil, 而不是Int?=nil -> 差了一个问号
// 牛皮的题
(e2 ?? 1) ?? 2 //2 e2不为nil,而且因为1不是可选型,e2被强制解包成Int? 因为Int?为nil,所以返回2
(e3 ?? 1) ?? 2 //1 e3为nil,所以返回1 1??2 = 1
//lldb`fr v -R` 查看变量的内存区别
/*
(lldb) fr v -R d1
(Swift.Optional<Swift.Int>) d1 = some {
some = {
_value = 10
}
}
(lldb) fr v -R d2
(Swift.Optional<Swift.Optional<Swift.Int>>) d2 = some {
some = some {
some = {
_value = 10
}
}
}
(lldb) fr v -R d3
(Swift.Optional<Swift.Optional<Swift.Int>>) d3 = some {
some = some {
some = {
_value = 10
}
}
}
fr v -R e1
(Swift.Optional<Swift.Int>) e1 = none { //有值为some,无值叫none. 如果为none,就不用看里面了.
some = {
_value = 0
}
}
(lldb) fr v -R e2
(Swift.Optional<Swift.Optional<Swift.Int>>) e2 = some {
some = none {
some = {
_value = 0
}
}
}
(lldb) fr v -R e3
(Swift.Optional<Swift.Optional<Swift.Int>>) e3 = none {
some = some {
some = {
_value = 0
}
}
}
*/
//Optional 其实是一个枚举
网友评论