Swiftを勉強する前に知っておきたかった、検索しづらいSwiftのシンタックスシュガーたち(JavaやC#,C++などのコンパイラ言語経験者向け)

f:id:monex_engineer:20200330091044j:plain
こんにちは。証券企画室の佐藤です。
1月からSwiftコードを書き始めていますが、他の言語に比べて記号を使った構文が多く、それらについてWebで調べづらいと感じたので、 今回はそれらの"検索しづらいシンタックスシュガーたち"を紹介します。
Swift言語の基本から解説するものでは無いので、Swiftを勉強しながらよくわからない記法に遭遇した時に参考にしていただければと思います。

mapやfilterの後ろにいきなり書かれる{}

コード例
let numberList:[Int] = [1, 2, 3, 4]
let isEvenList = numberList.map{ ($0 % 2) == 0 } //map関数を呼んでいるのに()が無い
print(isEvenList)

map()関数を呼び出しているかと思いきや、()がなくいきなり{}が書かれています。
これの正体はTrailingClosureです。最後の引数にクロージャを渡すことができる関数は、()の後ろにいきなり{}で渡したいクロージャを書くことができます。
特に、mapのようにクロージャしか受け取らない関数の場合には、()ごと省略することができます。
詳細はSwiftの公式ドキュメントをご参照ください。
https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID102

ドット(.)で始まる値渡しや代入

コード例
enum TestEnum{
    case A
    case B
}
func TestFunc(_ testValue:TestEnum){
    print(testValue)
}
TestFunc(.B) //TestEnum.Bと書かなくて良い。

型推論によるもので、enumを渡す場合に、そのenum型名を省略することができます。
enumと関数定義、呼び出しが上記のようにこれだけ近くに書いてあれば直感的にわかるのですが、他の言語のプログラマがいきなりTestFunc(.B)だけ見ると、
selfのメンバーだろうか、と考えてしまう確率が高いのではないでしょうか。

もちろんこれは関数の引数だけではなく、下記のように値の代入などでも機能します。

コード例
var inferedValue:TestEnum = .A //TestEnum.Aと書かなくて良い。

変数の後ろに現れるクエスチョンマーク二つ(??)

コード例
func printValue(_ optionalTestValue:Int?){
    print(optionalTestValue ?? 0) //いきなり現れるクエスチョンマーク2つ。
}
printValue(nil) //0が表示される
printValue(3) //3が表示される

これはNil-Coalescing Operatorです。
値がnilでなければその値自体を返し、nilであれば??の後ろの値を返します。
if文によるnilのチェックとデフォルト値の返却を書かずに済むので、楽に記述できますね。
詳細は公式ドキュメントをご参照ください。
https://developer.apple.com/documentation/swift/optional#2849660

関数の戻り値を、宣言してもいないアンダースコアで受け取る

コード例
func ShowLabel() -> Bool{
    // 何かの処理  
    return true
}
_ = ShowLabel() //アンダースコアは何者?

これは他の言語でプログラミング経験があれば推測しやすいと思いますが、戻り値を捨てる目的で、_で受け取っています。
これを書かないと、コンパイラからResult of call to 'ShowLabel' is unusedという警告が出てしまいます。
戻り値を意図的に使いませんよという意思表示ですね。

以上、簡単に4つほどSwiftの構文を取り上げてみました。Swiftは比較的新しい言語で、20年以上前から存在するような言語に親しんでいると、面食らう構文が多いです。
しかし、これらを使いこなすことで、読みやすく強固なコーディングができるようになるので、一つずつ理解して自然なSwiftコードを書けるようになりたいですね。

佐藤 俊介 証券企画室