特定の enum に対して拡張したい場合は、それに対して extension を書けばいいです。
ただ、複数の enum に対して 使い回せる 拡張をしたい場合の書き方がわからなくなりがちだったので、記事にしました。
例で書いているコードは実用性のない適当なものなので、流し読みで。
様々な enum に適応する拡張
RawRepresentable
の extension を作成すれば良いです。
※ RawValue が存在する enum をでなければ使用できません!
extension RawRepresentable {
init?(_ rawValue: RawValue?) {
guard let rawValue = rawValue else { return nil }
guard let value = Self.init(rawValue: rawValue) else { return nil }
self = value
}
var rawValueClassName: String {
return String(describing: type(of: self.rawValue))
}
}
特定の RawValue の enum に適応する拡張
特定の RawValue
型のすべての enum に適応されます。
上記の extension に where を指定します。
extension RawRepresentable where RawValue == Int {
var twice: Int {
return self.rawValue * 2
}
}
// 下記のような enum に使用できます
enum Example: Int {}
自ら指定した enum のみ拡張させる
前述までのものでは、新たに enum を作成したとき、条件が一致すればそれも適応されてしまいます。
能動的に適応させるために protocol を用意します。
A. RawRepresentable に準拠させる
ただ protocol を用意しただけでは色々なものに適応できてしまうので、制限をかけます。
下記 protocol を RawValue = Int の enum
以外に適用させるとエラーが発生します。
// RawRepresentable に準拠させることで enum(RawValueあり) のみに使用できるように (from Swift5)
// where 句で RawValue の型を制限 (変えたりとったりご自由に)
protocol EnumProtocol: RawRepresentable where RawValue == Int {}
extension EnumProtocol {
var twice: Int {
return self.rawValue * 2
}
}
// 下記のように使用します
enum Example: Int, EnumProtocol {}
B. extension に型制限をかける
下記のようにすることで、EnumProtocol
自体は class や struct など何にでも適用できますが、
.twice
プロパティが使用できるのは RawValue が Int か String の enum
のみです。
protocol EnumProtocol {}
extension EnumProtocol where Self: RawRepresentable, Self.RawValue == Int {
var twice: Int {
return self.rawValue * 2
}
}
extension EnumProtocol where Self: RawRepresentable, Self.RawValue == String {
var twice: String {
return String(repeating: self.rawValue, count: 2)
}
}
この辺は enum というより protocol の話なので、色々調べてみてください。
参考
環境
- Swift 5.0