07、enum枚举

1、定义enum

很多时候,我们需要用一组特定的值,来表达一个公共的含义。例如用1,2,3,4表示东、南、西、北,面对“把一组有相关意义的值定义成一个独立的类型”这样的任务,Swift为我们提供了一种类型安全的方式,叫做enum。

1.1 不设置rawValue

enum Week {
    case MON
    case TUE
    case WED
    case THU
    case FRI
    case SAT
    case SUN
}

简写:
enum Week {
    case MON,TUE,WED,THU,FRI,SAT,SUN
}
print(Week.MON)
type(of: Week.MON) // __lldb_expr_17.Week.Type
没有设置rawValue 无法调用Week.MON.rawValue

1.2 设置rawValue为String类型

01、不绑定默认值。如果我们不想写后面的字符串,也可以简写成如下的形式,默认rawValue是case 后面的值。
enum Week:String {
    case MON
    case TUE
    case WED
    case THU
    case FRI
    case SAT
    case SUN
}
02、绑定默认值
enum Week:String {
    case MON = "MON"
    case TUE = "TUE"
    case WED = "WED"
    case THU = "THU"
    case FRI = "FRI"
    case SAT = "SAT"
    case SUN = "SUN"
}

print(Week.MON) //
type(of: Week.MON) // __lldb_expr_21.Week.Type
type(of: Week.MON.rawValue) //String.Type

1.3 设置rawValue为整数

和Objective-C不同,Swift的enum默认不会为它的case“绑定”一个整数值。

01、如果不设置默认值,Swift默认为会把Week.MONWeek.TUEWeek.WEDWeek.THUWeek.FRIWeek.SATWeek.SUN绑定为0123456
enum Week:Int {
    case MON
    case TUE
    case WED
    case THU
    case FRI
    case SAT
    case SUN
}
02、绑定默认值
enum Week:Int {
    case MON = 2
    case TUE = 3
    case WED = 4
    case THU = 5
    case FRI = 6
    case SAT = 7
    case SUN = 8
}

03、根据第一个值自动推导
enum Week:Int {
    case MON = 2
    case TUE 
    case WED
    case THU
    case FRI
    case SAT
    case SUN
}
print(Week.MON)
type(of: Week.MON) //__lldb_expr_23.Week.Type
type(of: Week.MON.rawValue) //Int.Type

2、关联值(Associated value)

在Swift里,我们可以给每一个case“绑定”不同类型的值。我们管这样的值叫做associated values。

enum HttpAction {
    case get
    case post(String)
    case delete(Int,String)
}

var action1 = HttpAction.get
var action2 = HttpAction.post("lichangan")

switch action1 {
case .get:
    print("HTTP GET")
case .post(let msg):
    print("\(msg)")
case let .delete(id, data):
    print("id = \(id),data = \(data)")
}

3、enum是值类型,也是引用类型

在Swift里,enum默认也是一个值类型,也就说,每一个enum对象,都只能有一个owner,因此,你无法创建指向同一个enum对象的多个引用。
但有一种特殊的情况,可以改变enum的这个属性

enum List {
    case end
    indirect case node(Int, next: List)
}
我们可以使用indirect修饰一个case,这样当一个Listcase node时,它就变成了一个引用类型,多个case node可以指向同一个List对象:

let end = List.end
let list1 = List.node(1, next: end)
let list2 = List.node(2, next: end)
此时,list1和list2就指向了同一个end对象。

4、enum中的函数

Swift中的枚举也可以包含方法,可以是实例方法也可以是类方法。

enum Week:Int {
    case MON,TUE,WED,THU,FRI,SAT,SUN
    mutating func nextDay() {
        if self == .SUN {
            self = .MON
        }else {
            self = Week.init(rawValue: self.rawValue + 1)!
        }
    }
    
    static func creator(){
        print("lichangan")
    }
    
}

5、enum中的属性

Swift中允许在枚举中包含计算属性和类型属性,但不能包含存储属性。

enum Week:Int {
    case MON = 2
    case TUE
    case WED
    case THU
    case FRI
    case SAT
    case SUN
    //计算属性
    var firstDay:Week {
        return .MON
    }
    //类型属性
	 static let lastDay:Week = .SUN
}

6、与OC汇编

6.1 OC调用Swift中的枚举

如果想要在OC中使用Swift枚举要求会很严格:

  • 使用@objc标记
  • 类型必须是Int,也就是Swift的rawValue
  • 必须导入import Foundation
import Foundation

@objc enum Week: Int{
    case MON, TUE, WED, THU, FRI, SAT, SUN
}

此时编译后就可以正在project-Swift.h中看到转换后的对应的OC枚举:

在这里插入图片描述

在这里插入图片描述

6.2 Swift中调用OC

6.2.1 NS_ENUM

NS_ENUM(NSInteger, OCENUM){
    Value1,
    Value2
};

如果使用NS_ENUM创建的枚举会自动转换成swift中的enum

可以在ocfileName.h中查看转换后的枚举:
在这里插入图片描述
在这里插入图片描述
使用的话需要在桥接文件中导入OC头文件,然后在swift中使用:

let value = OCENUM.Value1

6.2.2 使用typedef enum

typedef enum {
    Enum1,
    Enum2,
    Enum3
}OCENum;

如果使用typedef enum这种形式的枚举,会转换成结构体,同样可以在ocfileName.h中查看转换后的结果,转换后的代码如下:
在这里插入图片描述

可以看到里面有一个rawValue属性,以及init方法。还遵守了Equatable, RawRepresentable两个协议。

使用的话也是需要导入头文件:

let num = OCEnum(0)
let num1 = OCEnum.init(0)
let num2 = OCEnum.init(rawValue: 3)

print(num)

<!--打印结果-->
OCNum(rawValue: 0)
这里我们只能通过init方法去初始化,不能访问枚举中的变量。

6.2.3 使用typedef NS_ENUM

typedef NS_ENUM(NSInteger, OCENUM){
    OCEnumInvalid = 0,
    OCEnumA = 1,
    OCEnumB,
    OCEnumC
};

使用typedef NS_ENUM也会自动转换为Swift的枚举,转换后的代码如下:
在这里插入图片描述
使用也是需要导入头文件:

let ocenum = OCENUM.OCEnumInvalid
let ocenumRawValue = OCENUM.OCEnumA.rawValue

6.3 混编时需要使用String类型的枚举

Swift中需要使用String类型的枚举,但是又要与OC混编,暴露给OC使用。

如果直接声明为String类型编译时不会通过的,这里只能弄个假的。Swift中的枚举还是声明为Int,可以在枚举中声明一个变量或者方法,用于返回想要的字符串。

@objc enum Week: Int{
    case MON, TUE, WED
    
    var value: String?{
            switch self {
            case .MON:
                return "MON"
            case .TUE:
                return "TUE"
            case .WED:
                return "WED"
            default:
                return nil
            }
        }
    
    func weekName() -> String? {
        switch self {
        case .MON: return "MON"
        case .TUE: return "TUE"
        case .WED: return "WED"
        default:
            return nil
       }
    }
}

用法:

<!--OC用法-->
Week mon = WeekMON;

<!--Swift用法-->
let value = Week.MON.value
let value1 = Week.MON.weekName()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值