Swiftの勉強
A Swift TourのPlaygroundで勉強する。
Simple Values
変数、定数、文字列埋め込み、配列、マップ。
Control Flow
switch文が強力。Rustの影響?
Functions and Closures
タプルにも名前がつけられる。
Objects and Classes
コンストラクタはinit()。
Rustでは同じスコープで同名の定数を上書きできるが、Swiftではエラーになる。
setterの定義時にnewValueを使えるのは便利。どうせ引数書いてもラベルはnewValueだし。
willSet/didSetがデフォルトであるのも良い。
メンバ変数をprivateにする方法は?→この章では解説なし。privateをつける。
Enumerations and Structures
enumが強力。Rust?
classは参照、structは値としてコピー。
Protocols and Extensions
プロトコルはclassもstructも適用可能。
組み込み型もextensionで拡張できる。
Error Handling
Result型はない?
Generics
enumでもジェネリクスが使える。
whereで制約が書ける。C++のConcepts?
以上で終わり。これでSwiftを書けるようになった気は全然しない。
テストとデバッグのやり方は!?
Tourじゃない方のドキュメントを読む。
The Basics
assert()でデバッグできる。
precondition()で事前条件をチェックできる。
precondition()は-Oでも実行される。
未実装な関数をとりあえず落としたい場合はfatalError("Unimplemented")を使う。
Basic Operators
rangeを配列の引数に渡すこともできる。
Strings and Characters
Stringは値型。
文字列に対するforループは文字単位で処理される。
文字列同士の比較は正規化した上で行われる。
Closures
Shorthand Argument Namesはクロージャを楽に書きたいという情熱を感じる。
Trailing Closuresはちょっと見ない文法。
Enumerations
enumは再起的に定義できる。
Structures and Classes
classインスタンスのidenticalは===で確認する。ポインタではない。
メモリを操作する方法は別にある。
Properties
lazyで初期化のタイミングを遅延できる。バグの原因になりそう。
Properties Wrappersは便利な機能だと思うが、自分が定義することはそんなになさそう。使う範囲が狭ければ単にstructでつくるだろうし。
projected valueはちょっと魔術的ではなかろうか。便利かもしれないがわかりにくい。
Initialization
メンバ変数の初期化をクロージャでできるのはちょっと便利。どうせどこかに書くのならこれが一番良い。
Error Handling
try?で例外がnilに変換されるのは面白い。いいのか?とも思うが。
Extensions
extensionsはinit()も定義できる。
Opaque Types
返り値に使う場合はsomeをつける。ファクトリメソッド用?
Protocols Typesとの違いはtype identityを保証するかどうか。Opaqueの場合はassosiated typeでキャプチャ(?)した型の情報を保持することができる。
Automatic Reference Counting
参照関係を意識しないといけないの!?
流し読み終わり。相変わらずデバッグとテストのやり方はわからない。
Debugging and Reflection
Appleのサイトにデバッグの記述あり。
debugPring(), dump()など。
gdb的なものはなし?XCodeを使えということか。
XCTest
テストはXCTestを使うのが多分一般的。
基本的な使い方は別記事。
テクニックも別記事。
SwiftでLispをつくってみる。
Mac OSコマンドラインプロジェクトをつくる。
とりあえずテストを書こうとするがエラー。
Failed to build module 'XCTest' from its module interface; the compiler that produced it, 'Apple Swift version 5.3.1 (swiftlang-1200.2.41 clang-1200.0.32.8)', may have used features that aren't supported by this compiler, 'Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)'
単にtestフォルダをつくってSwiftファイルを置くだけではだめらしい。Test navigatorでテストターゲットとしてtestを追加する。次にテスト実行をするとschemeをconfigurationしろと言われるのでここでtestを追加すると実行可能になる。
srcでpublic関数を定義し、test側でimportをするが、リンク時にundefined symbolエラー。@testable importでもだめ。
一方でGUIアプリプロジェクト作成時にテストも追加しておくとエラーは発生しない。何かの呪文が抜けているようだが調べてもわからない。後からテストを追加するのは一般的ではないのか?
swift packageでつくった場合も同様のエラー。わけがわからない。
swift package init --type libraryでつくればswift testが成功。
ただし、swift package generate-xcodeprojでつくったプロジェクトをXcodeで開いてテストすると以下のエラー。
Compiling for macOS 10.15, but module 'Lisw' has a minimum deployment target of macOS 11.1
おそらく10.15がデフォルト値。Package.swiftに明示的にplatformを指定してプロジェクトファイルを再生成したら解消した。
platforms: [
.macOS(.v11)
],
プロジェクト名をliswからLiswにしてつくりなおし。なぜかtargetのエラーが出なくなった。
とりあえず簡単なS式は処理できるようになった。グローバル環境に登録された関数が+と<しかないしエラー時は大体fatalError()で落ちるが。
Swiftの良いところ
enumが強力。再帰的に定義できる分Rustより(多分)高機能。
guardがよい。ニーズの高いところにぴったりの文法を用意している。
Swiftの良くないところ
IDEのサポートがしょぼい。未定義の関数やクラスを書いたらサジェストしてほしい。これはAppCodeでは可能らしいが有料である。組み込みのコードフォーマッタもない?Ctrl+iでインデントはできるけど。
ドキュメントが英語。つらい。MSみたいに機械翻訳のドキュメントも困るが。
作り込んでもよいのだが、年を跨いでまでやることもないか。
swift-format
git clone -b swift-5.3-branch https://github.com/apple/swift-format.git
cd swift-format
swift build
swift run swift-format format -i foo.swift
swift run swift-format lint foo.swift
lintでenumはlowerCamel使えと出てくるが無視。
Github code scanning
swiftには未対応。
関数コメント
メニューでEditor > Structure > Add Documentationか、関数クリックして以下のショートカットで雛形が生成される。
option + command + /
option+clickでドキュメントが表示される。
swift自体は関数のコメントをどうするか定義してない?
Github release
releaseすると自動でzipとtar.gzをつくってくれる。