Swift初学 - 四大自定义数据类型之Enum
Swift的Enum比其他语言的都要更强大,因为你可以想struct一样在你创建的enum下定义methods或computed properties。我们先来看个基础的例子,然后逐步讲解在swift enum中你都可以做什么
1、基本形式
enum Status {
case pending, approved, failed // 一般是用camelCase
}
让我们来写一个用到Status的func
func getStatus(of status: Status) -> String {
switch status {
case .pending:
return "审核中"
case .approved:
return "审核通过"
case .failed:
return "审核未通过"
}
}
getStatus(of: Status.failed)
a) 当你把status作为参数传入getStatus的时候,swift已经知道他是Status类型了,所以switch中每个case就不用再写Status.x,直接写x就行
b) 当你的case比较少,可以把每一条都列在switch中的时候,那就不要用default了;代码读起来也方便,而且!如果有人在Status里又加了一个状态,那么swift就会在getStatus里警告你少了一种情况,你可以及时改正;有default的话就懒得理你了
2、Raw Values
Swift的enum可以加raw values,像上述例子,有了raw values,我们完全不需要getStatus这个func了。
enum Status: String {
case pending = "审核中"
case approved = "审核通过"
case failed = "审核未通过"
}
Status.pending.rawValue // 审核中
a) 如果raw value的类型是Int的话,你要是不给他们赋值,swift会自动从0一个个赋值;你可以给第一个赋值一个int,那么swift也会把后面逐次加1;
b) 像这个例子,如果我没有赋值,那么pending的rawValue就是"pending"
c) 你还可以通过rawValue来获得case,比如let pending = Status(rawValue: "审核中"),但是pending会是个optional你要注意
3、Associated Values
每一个case都可以有自己的associated value,而且他们的类型可以都不同。有了associated values就不能再加raw values。我们还是用刚才的Status为例,一般审核不通过会有一个原因:
enum Status: String {
case pending
case approved
case failed(msg: String)
}
func review(_ name: String) -> Status {
if name.count > 10 {
return .failed(msg: "名字太长了")
}
return .pending
}
review("dsafs") // pending
review("dsafsdfsdfsd") // failed(msg: "名字太长了")
非常通俗易懂,我就不用多说啥了。如果未通过,怎么处理这个返回值呢?
let res = review("dsfsdfsdfsdf")
switch res {
case .pending:
print("通过")
case .failed(let msg):
print(msg)
default:
print("lazy me")
}
记得用一个let来绑定返回的信息,msg这个名字可以一样也可以不一样,最好一样。你要是跟我一样懒,就不要写这么多case了,用if case来解决:
let res = review("dsfsdfsdfsdf")
if case .failed(let msg) = res {
print(msg)
}
if case先检查了res里是不是failed,是的话,把msg给赋值。
4、其他可以讨论的
a) 如果想遍历一个enum,那么你定义的时候就要这样:
enum Status: CaseIterable { ... }
for status in Status.allCases { ... }
b) 我们经常用Math来计算一些数据,比如Math.min(),如果用Struct来写Math的话,我们知道swift会自动生成一个init,let math = Math(),完全没意义;所以我们可以用enum来写Math,反正swift支持在enum写method,我们也告诉其他人Math是不应该创建instance的。
c) Optional其实是一个enum,他有两个case: .none 和 .some(value: Any)
Cool! bye~