OC vs Swift -- Enumeration

枚举声明的类型是囊括可能状态的有限集。也可以说enum是一组常量的集合,可以让我们的代码可读性更高。

Enum in OC

OC中枚举类型必须为整型,默认第一个枚举值为0。

iOS6中引入了两个宏来定义枚举类型(即:NS_ENUM与NS_OPTIONS),这两者在本质上并没有差别,都是用于定义枚举类型,但是在使用中NS_ENUM多用于一般枚举,而NS_OPTIONS则多用于带有移位运算的枚举。

对于一般的枚举,要获取枚举的最大值是很难的,因为随着枚举的扩充,最大值在不断变化,这时推荐使用一个固定的枚举表示最大值。

typedef NS_ENUM(NSUInteger, EnumTest)
{
    EnumTestOne,
    EnumTestTwo,

    EnumTestMax  //Max Value
};

位枚举是一种特殊的枚举,位枚举可以使用位运算来处理枚举值,实际使用中可以用一个变量存储多个枚举值,表示互不影响的多个设置。

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
test |= TMEnumTestFour; //添加
test &= ~TMEnumTestThree; //移除
if (test & TMEnumTestFour) //是否包含

Enum in Swift

和OC中的枚举相比,Swift有三点优势:

  • OC中,你只能为枚举分配整型值,而Swift则可以不用给每个枚举提供枚举值,同时枚举值类型可以是整型,浮点数,字符串,布尔类型, 让它使用起来更灵活;
  • Enum可以通过关联值将额外信息附加到每个枚举, 这些关联值可以是任意类型;
  • 通过内嵌(nesting),添加方法,关联值和模式匹配(pattern matching), 枚举可以分层次地定义任何有组织的数据,清晰表达代码的意图。

Enum在Swift的应用场景非常多:

  • Optional就是由 ENUM + 范型定义的一个数据类型;


    OC vs Swift -- Enumeration_第1张图片
    Optional
  • 可以通过递归枚举来定义如FileNode、二叉树等类型;

OC vs Swift -- Enumeration_第2张图片
File Node

OC vs Swift -- Enumeration_第3张图片
Tree
  • 将字符串类型的重用标识或者 storyboard 标识映射为类型系统可以进行检查的类型;


    OC vs Swift -- Enumeration_第4张图片
    Reuse Identifier
  • Enum 还可以用来定义值类型model,说到定义值类型model, 通常会想到使用struct。来看个列子:

protocol ErrorType {
    func description() -> String
}
enum APIError: ErrorType {
    case PasswordIncorrect
    case UserIsNotExist
    case ConnectError(error: NSError)

    func description() -> String {
        switch self {
        case .PasswordIncorrect:
            return "password is not correct"
        case .UserIsNotExist:
            return "user is no exist"
        case .ConnectError(let error):
            return "connect error: \(error)"
        }
    }
}
struct PasswordIncorrect: ErrorType {
    func description() -> String {
        return "password is not correct"
    }
}

struct UserIsNotExist: ErrorType {
    func description() -> String {
        return "user is no exist"
    }
}

struct ConnectError: ErrorType {
    func description() -> String {
        return "connect error: \(error)"
    }
    let error: NSError
}

可以看出使用enum定义model有2个好处:

  • 更清晰,知道有多少种类型的APIEorror;
  • 预防将其他类型的error传递给api error 类型的参数,更安全。

所以一般来讲,如果问题可以被分解为有限的不同类别,则推荐使用来enum定义model 。

你可能感兴趣的:(OC vs Swift -- Enumeration)