コンテンツにスキップ

Top

Swift入門

看板に偽りありだがSwiftの入門といっても本当の入門ではなく、C/C++やJavaをやってきた人間がSwiftを見て何これ?ってなったところだけをまとめたもの。

?(Question Mark)

Swiftは変数の型に?がつくことがあります。
これはオプショナル型にすることを意味します。
オプショナル型ってなんぞい、と思うかもしれませんがnilを許容する型ということです。
Intはnilを代入しようとしてもシバかれますが、Int?はnilを入れても良いのです。
なお、IntとInt?は似て非なる型なので、同じ型として扱うことはできません。

var int:Int = 100
var int_opt:Int? = 200
int += int_opt

とすると、Value of optional type 'Int?' must be unwrapped to a value of type 'Int' というエラーが表示されて失敗します。
このような場合はアンラップしてあげないといけません。

!(Exclamation Mark)

Swiftにおける!はアンラップを表します。
アンラップはラップしているクラスを外すということで、Int型をオプショナル型にラップしている状態からアンラップするとInt型に戻る、という感じです。

先ほどエラーになったコードですが、アンラップすると問題なくなります。

var int:Int = 100
var int_opt:Int? = 200
int += int_opt!

エラーが消えました。アンラップの結果、Int?がIntになったのでInt同士の足し算になったからです。

ではもしこのとき、Int? の値がnilだったらどうなるでしょう?

var int:Int = 100
var int_opt:Int? = nil 
int += int_opt!

error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
というエラーが発生してしまいましたね。
よってオプショナル型をアンラップする際はnilでないことを自身で保証しないとダメです。

?(Question Mark)

Any型

SwiftにはAnyという型がある。

IntやStringなどの型はみんなAny型を継承している。

Any型にはなんでも入れれる。

var any_string:Any = "Hello!"
var any_int:Any = 100

といった感じに。

ただし、Int型の変数に数値をいれたAny型の変数を直接代入とかできない。

var any_int:Any = 100
vat int:Int = any_int

その場合はas!やas?といったキャストを用いる必要があるがそれは後述。

as/as!/as?

enum

Swiftのenumは以下みたいな感じ。

enum Color: Int {
  case red
  case blue
  case green
}

???ケースって何(笑)。switch case文でしか見たことないんだけど。

という感じの定義の仕方。

初期値も入れれる。

enum Color: Int {
  case red = 1
  case blue = 2
  case green = 3
}

なんだろうね。使うときは、

let hoge = Color.red
って感じで使う。

guard

guard は 条件を満たさない時にelseの処理を行う、ifの逆バージョンみたいなやつ。

    guard 条件 else {
        !条件時の処理
        return
    }
    条件時の処理

いや、ifでえぇやろ!

例えば居酒屋で20歳以上かどうかをチェックするプログラムを書くとすると

guard age >= 20 else {
    print("ママのおっぱいでも吸ってろ")
    return
}
print("いらっしゃいませ")

いや、めっちゃわかりにくい。20歳以上「じゃなかったら」else、という否定を頭の中でやるの。
なんでこんなクソみたいな構文作ったんだろう?
でも結構みんな使ってるから理解しないと他人のコードが読めないので仕方ない。

変な書かれ方のコード

他人のソースを見ていると、以下のようなよくわからんif文やguard文を見かける。

var str:String? = "Hello, playground"
if let hoge = str {
    print("nil")
} else {
    print("OK")
}

guardでも同様なコードが

func aaa() {
    guard let hoge = greeting else {
        print("nil")
        return
    }
    print("OK")
}
aaa()

どうもnilチェックをしているらしい。
が、Xcodeのコンパイラが警告を出すし、なんでこんな書き方?

Value 'hoge' was defined but never used; consider replacing with boolean test

普通に!= nil でいいしょ?

var str:String? = "Hello, playground"
if str != nil {
    print("nil")
} else {
    print("OK")
}

よくわからん。が、こういう書き方が流行ってるのか知らんけど結構書く人がいるのでコードを読めるようにするために学ぶ必要がある。