Swift

Swift入門

変数、分岐、繰り返し、関数、Optional、構造体を、コードと実行結果で基礎から学びます。

対象:Swift 6系。基礎はコンソールで学びます。iOSアプリの開発にはmacOSとXcodeが必要です。

01

Swiftとは

SwiftはAppleのアプリ開発などに使われるプログラミング言語です。Swiftは言語、SwiftUIは画面を作るためのフレームワーク、Xcodeは開発ツールです。この講座では画面を作る前に、コンソールへ結果を表示して文法を確かめます。

学習順序:実行環境 → 値と処理 → Optional → データの整理 → 保存とテスト。プログラミング経験は不要です。コードはUTF-8で保存し、各例を別々に実行してください。
02

準備と最初の実行

macOSではXcodeをインストールし、初回起動時の追加コンポーネントの設定を済ませます。Linux・Windowsでは公式のOS別手順でSwiftと必要な開発ツールを導入します。ターミナルで次のコマンドがバージョンを表示することを確認します。

ターミナルCOMMAND
swift --version

練習用フォルダーを作り、その中に移動します。コマンドは1行ずつ実行してください。

作業フォルダーを作成COMMAND
mkdir swift-study
cd swift-study

エディターで次の内容を main.swift に保存します。

main.swiftSWIFT
print("こんにちは、Swift!")
macOS・Linux:ファイルを保存したフォルダーで実行COMMAND
swift main.swift

Windowsでは同じソースをコンパイルして実行します。公式の導入手順で開発ツールとSDKを揃え、PowerShellで次を実行してください。ソースを書き換えるたびに再コンパイルします。

Windows PowerShellで実行COMMAND
swiftc main.swift -o study.exe
.\study.exe
実行結果OUTPUT
こんにちは、Swift!
以下の基礎例は、特記がなければmain.swiftを全体ごと置き換え、macOS・Linuxでは swift main.swift、Windowsでは上記のコンパイル手順で実行します。コマンドが見つからなければ導入とPATH、ファイルが見つからなければ作業フォルダーと拡張子を確認します。スマートフォンのブラウザーだけではこのコマンドは実行できません。
03

基本の書き方

処理は上から順番に進みます。文字列は半角の二重引用符で囲みます。// 以降はコメント、{ } は処理のまとまりです。文末のセミコロンは通常不要です。

main.swift(全体を置き換え)SWIFT
// 2つの表示を順番に行う
print("開始")
print(10 + 20)
実行結果OUTPUT
開始
30
04

定数・変数・型

let は再代入しない定数、var は変更できる変数です。: の後に型を指定できます。省略すると初期値から推論されます。整数はInt、小数はDouble、文字列はString、真偽値はBoolです。文字列内の \(式) で値を埋め込みます。

main.swift(全体を置き換え)SWIFT
let name: String = "Mity"
var age: Int = 20
let height: Double = 170.5
let isStudent: Bool = true
age += 1
print("\(name)さんは\(age)歳です")
print(height)
print(isStudent)
実行結果OUTPUT
Mityさんは21歳です
170.5
true
まずletを使い、後で変える必要がある値をvarにします。age = "二十" のようにIntへ文字列を代入するとコンパイルエラーです。
05

入力と安全な型変換

readLine() は入力された1行を受け取ります。入力終了時には値がありません。?? "" でその場合を空文字列にし、Int(...) で整数に変換します。変換に成功したときだけ if let の中が実行されます。Optionalの詳しい仕組みは後の章で扱います。

main.swift(全体を置き換え)SWIFT
print("年齢を入力してください")
let text = readLine() ?? ""
if let age = Int(text), (0...130).contains(age) {
    print("来年は\(age + 1)歳です")
} else {
    print("0〜130の整数を入力してください")
}
実行例(20を入力してEnter)OUTPUT
年齢を入力してください
20
来年は21歳です

「二十」、空の入力、-1を試すと、いずれも「0〜130の整数を入力してください」と表示します。入力を受け付けないオンライン環境では、let text = "20" に置き換えて変換を試せます。

06

計算・比較・論理演算

+ - * / は四則演算、% は整数の余りです。Int同士の割り算では小数部分が切り捨てられます。小数で計算したい場合はDoubleに変換します。== は等しいか、>= は以上、&& は両方の条件が真かを調べます。

main.swift(全体を置き換え)SWIFT
let price = 500
let count = 3
print(price * count)
print(7 / 2)
print(Double(7) / 2)
print(7 % 2)
print(count >= 1 && price == 500)
print(count == 0 || price > 0)
print(!(count == 0))
実行結果OUTPUT
1500
3
3.5
1
true
true
true

|| は少なくとも一方が真、! は真偽の反転です。= は代入で、比較の == とは異なります。0による整数の割り算は実行時エラーになるため、割る数を先に確認します。

07

ifとswitch

if は条件が真なら実行し、else if は次の条件、else はどれも当てはまらない場合です。最初に当てはまる分岐だけを実行します。

main.swift(全体を置き換え)SWIFT
let score = 82
if score >= 80 {
    print("よくできました")
} else if score >= 60 {
    print("合格")
} else {
    print("再挑戦")
}
実行結果OUTPUT
よくできました

switch は値ごとに処理を分けます。default は残りの値を受け持ちます。Swiftではcaseの末尾にbreakを書かなくても、次のcaseへ続きません。

main.swift(全体を置き換え)SWIFT
let day = "土"
switch day {
case "土", "日":
    print("休日")
default:
    print("平日")
}
実行結果OUTPUT
休日
08

for・while・途中終了

1...3 は1から3まで、0..<3 は0から2までです。forは範囲や配列を順番にたどります。

main.swift(全体を置き換え)SWIFT
for number in 1...3 {
    print(number)
}
var count = 2
while count > 0 {
    print("残り", count)
    count -= 1
}
実行結果OUTPUT
1
2
3
残り 2
残り 1

continue は今回だけを飛ばし、break は繰り返し全体を終えます。次の例は2を飛ばし、4になった時点で終了します。

main.swift(全体を置き換え)SWIFT
for number in 1...5 {
    if number == 2 { continue }
    if number == 4 { break }
    print(number)
}
実行結果OUTPUT
1
3
whileでは条件が変わる処理を忘れると無限ループになります。停止できなくなったときはターミナルでCtrl+Cを押します。
09

配列・辞書・集合

配列は順番のある値の集まりで、位置は0から数えます。append は末尾への追加、count は要素数です。空の配列で [0] を使うとエラーなので、先に isEmpty で確認します。

main.swift(全体を置き換え)SWIFT
var fruits = ["りんご", "みかん"]
fruits.append("もも")
if !fruits.isEmpty { print(fruits[0]) }
print(fruits.count)
for fruit in fruits { print(fruit) }
実行結果OUTPUT
りんご
3
りんご
みかん
もも

辞書はキーと値を対応付けます。キーがない可能性があるため、取得結果はOptionalです。集合Setは重複を取り除きます。表示順を揃えるため、ここでは sorted() で並べ替えています。

main.swift(全体を置き換え)SWIFT
var stocks = ["りんご": 5, "みかん": 8]
stocks["りんご"] = 6
print(stocks["りんご"] ?? 0)
print(stocks["もも"] ?? 0)
let tags: Set<String> = ["Swift", "Web", "Swift"]
print(tags.sorted())
実行結果OUTPUT
6
0
["Swift", "Web"]
10

関数と引数

func で処理に名前を付け、引数で入力、-> Int で戻り値の型を指定します。return は結果を呼び出し元へ返します。呼び出す側でも引数名を書くのが基本です。

main.swift(全体を置き換え)SWIFT
func total(price: Int, count: Int = 1) -> Int {
    return price * count
}
print(total(price: 500, count: 3))
print(total(price: 500))
実行結果OUTPUT
1500
500

countの = 1 は省略されたときの初期値です。関数の中で作った変数は原則としてその中でだけ使えます。表示するprintと、値を返すreturnは役割が異なります。

11

Optionalとnil

String? は「文字列、または値なし」を表し、値なしを nil と書きます。if let は値があるときだけ取り出し、?? は値がない場合の代わりを決めます。

main.swift(全体を置き換え)SWIFT
let nickname: String? = nil
print(nickname ?? "ゲスト")
let number = Int("42")
if let value = number {
    print(value + 1)
} else {
    print("整数ではありません")
}
実行結果OUTPUT
ゲスト
43
Optionalの後ろへ ! を付けて強制的に取り出すと、nilのときに停止します。入力、検索、変換には失敗があるため、まずif letや??を使いましょう。
12

文字列とクロージャ

文字列の count は文字数、hasPrefix は先頭の一致を調べます。uppercased() は英字を大文字にした新しい文字列を返します。Swiftの文字列は整数で直接 text[0] と参照できません。先頭はOptionalを返すfirstで調べます。

main.swift(全体を置き換え)SWIFT
let text = "Swift"
print(text.count)
print(text.hasPrefix("Sw"))
print(text.uppercased())
if let first = text.first { print(first) }
実行結果OUTPUT
5
true
SWIFT
S

クロージャは名前を付けずに渡せる処理です。filter は条件に合う要素を残し、map は各要素を変換します。score in のscoreは、処理中の1要素です。

main.swift(全体を置き換え)SWIFT
let scores = [40, 70, 90]
let passed = scores.filter { score in score >= 60 }
let doubled = passed.map { score in score * 2 }
print(passed)
print(doubled)
実行結果OUTPUT
[70, 90]
[140, 180]
13

構造体で値をまとめる

struct は関連する値と処理をまとめる型です。プロパティは持っている値、メソッドはその値を使う関数です。Product(...) で実際のデータを作ります。

main.swift(全体を置き換え)SWIFT
struct Product {
    let name: String
    let price: Int
    func total(count: Int) -> Int {
        return price * count
    }
}
let pen = Product(name: "ペン", price: 120)
print(pen.name)
print(pen.total(count: 3))
実行結果OUTPUT
ペン
360

構造体とクラスの違い、状態を変更するメソッド、共通の約束を定義するプロトコルは発展ページで学びます。

14

失敗する処理を扱う

throws は失敗を報告できる関数です。throw でErrorに適合する値を投げ、呼び出しを try で示します。do の中で起きたエラーを catch で受け取ります。enumは名前の付いた選択肢を定義します。

main.swift(全体を置き換え)SWIFT
enum PriceError: Error { case negative }
func checkedPrice(_ value: Int) throws -> Int {
    if value < 0 { throw PriceError.negative }
    return value
}
do {
    print(try checkedPrice(120))
    print(try checkedPrice(-1))
} catch {
    print("価格は0以上にしてください")
}
実行結果OUTPUT
120
価格は0以上にしてください

引数の _ は呼び出し側の引数名を省く指定です。エラーが起きるとdoの残りの処理を飛ばします。Optionalは「値がない」、エラーは「処理が失敗した理由」を伝えるときに使い分けます。

15

練習問題

問題1:numberを7として偶数・奇数を表示してください。動いたら0、8でも確認します。

解答例と結果を確認する

まず自分で書いてから、処理の順番と結果を比べましょう。

main.swift(全体を置き換え)SWIFT
let number = 7
if number % 2 == 0 { print("偶数") }
else { print("奇数") }
実行結果OUTPUT
奇数

問題2:[60, 80, 100]の平均をDoubleで求めてください。空の配列なら「データなし」と表示し、0で割らないようにします。

解答例と結果を確認する

まず自分で書いてから、処理の順番と結果を比べましょう。

main.swift(全体を置き換え)SWIFT
let scores = [60, 80, 100]
if scores.isEmpty {
    print("データなし")
} else {
    var sum = 0
    for score in scores { sum += score }
    print(Double(sum) / Double(scores.count))
}
実行結果OUTPUT
80.0

問題3:辞書から在庫を取得する関数を作り、未登録なら0を返してください。

解答例と結果を確認する

まず自分で書いてから、処理の順番と結果を比べましょう。

main.swift(全体を置き換え)SWIFT
func stock(of name: String) -> Int {
    let stocks = ["りんご": 5, "みかん": 8]
    return stocks[name] ?? 0
}
print(stock(of: "みかん"))
print(stock(of: "もも"))
実行結果OUTPUT
8
0
16

次に学ぶこと

基礎の次は、以下の4ページを順に進めましょう。各ページに手順、コード例、確認する結果と練習問題があります。

公式ドキュメントで確認する:Swiftの導入 / Swift言語ガイド / Swift Package Managerの入門