GitHubに置いているMTCCoreのSwift 3対応を行い、更にSwift API Design Guidelinesを適用したコードに書き換え作業中に、定数の定義について迷ったことです。
元のコード
元のコードは次のような形で定数を定義しています。
public enum LineBreakType {
case Unknown
case LF
case CR
case CRLF
case LS
}
let kLineBreakCharacterCR: Character = "\r"
let kLineBreakCharacterLF: Character = "\n"
let kLineBreakCharacterCRLF: Character = "\r\n"
let kLineBreakCharacterLS: Character = "\u{2028}"
Swift API Design Guidelinesの定数の命名について
Swift API Design Guidelinesで該当する部分は次の記述かなと思います。
The names of other types, properties, variables, and constants should read as nouns.
Follow case conventions. Names of types and protocols are UpperCamelCase. Everything else is lowerCamelCase.
これに従うと、定数は名詞を使うことと小文字で始めれば良いということですね。
NG案
こんな感じにしてみました。
public enum LineBreakType {
case unknown
case lf
case cr
case crlf
case ls
}
fileprivate struct LineBreakCharacter {
static let cr = Character("\r")
static let lf = Character("\n")
static let crlf = Character("\r\n")
static let ls = Character("\u{2028}")
}
何となく、Swiftらしくない感じがします。
改善案
上記の2つの定数は、LineBreakというクラスのメソッドが使用します。また、LineBreakTypeが名前空間のトップにいる必要も無いことに気が付きました。また、LineBreakCharacterはプライベートな定数をまとめているだけなので、適切では無い感じがします。LineBreakからしか使われないので、LineBreak内のプライベート定数にする方が適切です。これを踏まえて、次のように変更しました。
public final class LineBreak {
/// Line break types
public enum BreakType {
case unknown
case lf
case cr
case crlf
case ls
}
private static let characterCR = Character("\r")
private static let characterLF = Character("\n")
private static let characterCRLF = Character("\r\n")
private static let characterLS = Character("\u{2028}")
public init() {
}
}
本当は、BreakTypeではなく、シンプルにTypeにしたかったのですが、Typeは定義済みで使用できなかったので、BreakTypeにしました。
何となく、Swiftらしい定義になったような気がします。もっと相応しい記述方法に出会うまでは、これで行こうと思います。