Swift
Swiftは、Appleが、iOS、iPadOS、macOS、tvOS、および watchOS のために
目次
- Swift/
- Swift/
文法 -主 に制御 構造 、関数 定義 について - Swift/オブジェクト
指向 -主 に列挙 体 、クラス、構造 体 について - Swift/
非同期 処理 -主 にGrand Central Dispatchによる非同期 処理 について
環境 準備
オンラインコンパイル実行
ローカルにコンパイル
- Swift Playgrounds
公式 のオンラインコンパイル実行 環境 です。- paiza.io
複数 のプログラミン言語 に対応 しており、Swiftにも対応 しています。
ビルド済 みバイナリーの導入
- iPadOS
- Appleから、「Swift Playgrounds」が
学生 を対象 に公開 されています。 - Swift Playgroundsは
開発 環境 であるとともに、Swiftの基本 を習得 するためのチュートリアルを含 んでいます。 - macOS
- Swiftを
開発 したAppleのプラットフォームです。 - macOS 10.9
以降 をサポートしています。 - Xcodeに
統合 されています。 複数 のツールチェインがSwiftをサポートしているので、目的 に応 じて切 り替 えて使用 します。- Windows
- Windows10
以降 をサポートしています(Windows8.1以前 はサポート対象 外 )。swift公式 サイトではwingetなどパッケージマネージャを用 いてインストールすることを推奨 している[1](※2023年 現在 、公式 サイトのwinget関連 のコマンドを使 っても、うまく行 かなかった)。なおそのダウンロード内容 は、swift公式 サイトのSDKのインストールに加 えて、さらに Visual Studio 2019以降 をインストールして『C++によるデスクトップ開発 』の標準 設定 をインストールする必要 がある。なお、Powershellからでもコマンドプロンプトからでも、どちらかでもコマンド実行 できる。 - GNU/Linuxのディストリビューション
- GNU/Linuxのディストリビューションの
場合 、公式 にサポートされているディストリビューションと公式 にはサポートされず独自 にパッケージを用意 していディストリビューションがあります。
公式 にサポートされているディストリビューション
- Ubuntu
- 18.04
以降 をサポートしています。 - CentOS
- 7
以降 をサポートしています。 - Amazon Linux
- 2
以降 をサポートしています。
公式 にサポートされていないディストリビューション
パッケージマネージャによってパッケージ
- Fedoraの
場合 - Fedora
独自 のパッケージリポジトリーから非公式 版 をインストールします。最新 の利用 可能 なバージョンへインストール済 みパッケージを同期 する$ sudo dnf distro-sync
- インストール
$ sudo dnf install swift-lang
ソースコードからのビルド
- ソースコードの
入手 - https://github.com/apple/swift から clone します。
- ビルド
環境 の構築 - ビルド
環境 の構築 のために build-toolchain スクリプトが用意 されています。--help で全 てのオプションの説明 を見 ることが出来 ます。
- ビルド
- コンフィギュレーション
- ビルド
- テスト
- インストール
バージョン確認 コマンド
インストールに
swift --version
で
PS C:\Users\ユーザー名 > swift -version compnerd.org Swift version 5.8.1 (swift-5.8.1-RELEASE) Target: x86_64-unknown-windows-msvc
実行 方法
Hello World
コードは
- hello.swift
print( "Hello, World!" )
の1hello.swift
.swift
が
コンパイルする場合
$ swiftc ファイル
名 .swift
を
すると、
MS-DOSやWindowsでは、PATHが
$ ./ファイル
名
のようなに ./
を
インタプリタの場合
コマンド
$ swift ファイル
名 .swift
で、コンパイルと
かつては「swift run ファイル
対話 モードの場合
$ swift
で
定数 と変数
変数
var
を
変数 の宣言 var
変数 名 :型 =式
定数
let
を
定数 の宣言 let
定数 名 :型 =式
変数 の値 を参照 var a: Int = 47 print( a )
実行 結果 47
Int
は
識別子
識別子 には以下 の文字 セットが使 えます。英数字 (a-z, A-Z, 0-9)- アンダースコア(_)
- $
記号 - Unicode
文字
識別子 の先頭 に数字 (0-9)を使 うことは出来 ません。var
のようなSwiftのキーワードは識別子 に使用 できません。print
のような標準 ライブラリー関数 は識別子 に使用 すべきではありません。
この
標準 ライブラリー関数 の名前 を定数 の名前 に使 ったlet print = 0 print(print)
- コンパイル
結果 main.swift:2:1: error: cannot call value of non-function type 'Int' print(print)
ただし、
- `(バッククオーテーション)で
括 りキーワードを識別子 に使 う let `var` = 42 print(`var`)
実行 結果 42
初期 化 と参照
定数 と変数 は宣言 時 の初期 化 を省略 できますvar a: Int a = 31 print( a ) let b: Int b = 42 print( b )
実行 結果 31 42
宣言 時 に初期 化 を省略 した変数 の値 を参照 (コンパイル時 にエラーになります)var a: Int print( a )
- コンパイル
結果 main.swift:2:8: error: variable 'a' used before being initialized print( a ) ^
型 推論
:
の
型 推論 let a = 31 print( a, String(describing: type(of: a)) ) let b = "abc" print( b, String(describing: type(of: b)) ) let c = 3.1415926536 print( c, String(describing: type(of: c)) )
実行 結果 31 Int abc String 3.1415926536 Double
String(describing: type(of:
は、式 )式 の型 を文字 列 で返 します。
let str = "abc"
に
暗黙 の型 変換 は行 われない
なお、いかなる
符号 の有無 の違 う定数 による初期 化 let signed: Int = 1 let unsigned: UInt = signed
- コンパイル
結果 main.swift:2:22: error: cannot convert value of type 'Int' to specified type 'UInt' let unsigned: UInt = signed ^~~~~~ UInt( )
数値 リテラル1
は、UIntの範囲 内 ですが swift は型 の不 整合 を理由 にエラーにします。
型 の異 なる定数 と数値 リテラルからなる式 let signed: Int = 1 let number = signed + 1.0
- コンパイル
結果 main.swift:2:8: error: binary operator '+' cannot be applied to operands of type 'Int' and 'Double' signed + 1.0 ~~~~~~ ^ ~~~ main.swift:2:8: note: overloads for '+' exist with these partially matching parameter lists: (Double, Double), (Int, Int) signed + 1.0 ^
型 の異 なる数値 リテラル同士 からなる式 let number = 1 + 1.0 print( number, String(describing: type(of: number)) )
実行 結果 2.0 Double
- これは
暗黙 の型 変換 に似 ていますが、数値 リテラルのみからなる式 (=コンパイル時 定数 式 )で、コンパイル時 に静的 に評価 されます。
- Double.piは
数値 リテラル扱 い? let rad_to_deg_factor = Double.pi / 180 print( rad_to_deg_factor, String(describing: type(of: rad_to_deg_factor)) )
実行 結果 0.017453292519943295 Double
- なぜ?
基本 データ型
Swiftには、
整数
タイプ 範囲 大 きさリテラルの 例 Int8 (
符号 付 き)-128 〜 127 8ビット let myInt8: Int8 = -12
UInt8 (
符号 なし)0 〜 255 8ビット let myUInt8: UInt8 = 42
Int16 (
符号 付 き)-32,768 〜 32,767 16ビット let myInt16: Int16 = -1234
UInt16 (
符号 なし)0 〜 65,535 16ビット let myUInt16: UInt16 = 5678
Int32 (
符号 付 き)-2,147,483,648 〜 2,147,483,647 32ビット let myInt32: Int32 = -123456
UInt32 (
符号 なし)0 〜 4,294,967,295 32ビット let myUInt32: UInt32 = 123456
Int64 (
符号 付 き)-9,223,372,036,854,775,808 〜 9,223,372,036,854,775,807 64ビット let myInt64: Int64 = -1234567890
UInt64 (
符号 なし)0 〜 18,446,744,073,709,551,615 64ビット let myUInt64: UInt64 = 1234567890
Int (
符号 付 き)-2,147,483,648 〜 2,147,483,647 (32ビット または 64ビット)
32ビットまたは64ビット (
環境 による)let myInt: Int = -1234567890
UInt (
符号 なし)0 〜 4,294,967,295 (32ビット または 64ビット)
32ビットまたは64ビット (
環境 による)let myUInt: UInt = 1234567890
Swiftには、
let decimalInt = 17 // 10
進数 let binaryInt = 0b10001 // 2進数 let octalInt = 0o21 // 8進数 let hexInt = 0x11 // 16進数
これらのリテラルの
浮動 小数点 数
データ 型 ビット 最小 値 最大 値 リテラル Float
32 1.175494e-38 3.402823e+38 3.14
,0.1e2
,1.25E-2
Double
64 2.2250738585072014e-308 1.7976931348623157e+308 3.14
,0.1e2
,1.25E-2
Float80
80 3.36210314311209350626e-4932 1.18973149535723176505e+4932 3.14
,0.1e2
,1.25E-2
let a: Float = 3.14 let b: Double = 0.1e2 let c: Float80 = 1.25E-2 print(a) // 3.14 print(b) // 10.0 print(c) // 0.0125
真理 値
Swiftでは、
let happy: Bool = true let hungry = false print(happy) // true print(hungry) // false
文字 と文字 列
型 バリエーション リテラルの 例 Character Unicodeスカラー 値 "A"
String Unicodeスカラー 値 または文字 列 "Hello, world!"
こちらはSwiftでの
let letterA: Character = "A" let message: String = "Hello, world!"
文字 列 と文字 列 の連結
let str1 = "Hello" let str2 = "world" let str3 = str1 + " " + str2 print(str3) // "Hello world"
また、+=
var str4 = "Hello" str4 += " world" print(str4) // "Hello world" var str4 = "Hello" str4 += " world" print(str4) // "Hello world"
文字 列 に値 を埋 め込 む方法
var name = "John" var age = 25 var message = "\(name) is \(age) years old." print(message)
実行 結果 John is 25 years old.
また、String(format: "%@", value)のように、Stringクラスのformatメソッドを
var name = "John" var age = 25 var message = String(format: "%@ is %d years old.", name, age) print(message)
実行 結果 John is 25 years old.
どちらの
サロゲートペア
このSwiftのコードは、
import Foundation // Foundationフレームワークをインポート let str = "a
α あ𪚲" //文字 列 を定義 (ASCII, ギリシャ文字 , ひらがな,片仮名 , および漢字 等 を含 む) print(str.utf8.count) // UTF-8形式 での文字 列 の長 さをカウント(バイト単位 ):10 print(str.utf16.count) // UTF-16形式 での文字 列 の長 さをカウント(16ビット単位 ):5 print((str as NSString).length) // UTF-16形式 での文字 列 の長 さを計算 :5 print(str._bridgeToObjectiveC().length) //上 と同様 にUTF-16形式 での文字 列 の長 さを計算 :5 let char = str.character(at:3) // 4番目 の文字 のUnicode scalarを見 つける print(type(of: char)) // UInt16(16ビット符号 なし整数 型 ) print(String(format:"%x", char)) // d869(4番目 の文字 のUnicode scalarを16進数 表記 で出力 )
このコードでは、Foundation
フレームワークがインポートされているため、NSString
のメソッドであるlength
メソッドにアクセスできます。
また、character(at:)
はNSString
にもSwift
のString
配列
Swiftにおける
配列 の宣言 方法 説明 Array<
要素 の型 >()空 の配列 を定義 する方法 です。[
要素 の型 ]()空 の配列 を定義 する省略形 です。
var emptyArray: Array<Int> = Array<Int>() var emptyArray2: [Int] = [Int]() var emptyArray3: [Int] = []
ここで、Array<Int>()
と[Int]()
は、emptyArray
とemptyArray2
に[]
はemptyArray3
に
var arrayWithLiteral1: [Int] = [1, 2, 3] var arrayWithLiteral2 = [4, 5, 6]
ここで、[1, 2, 3]
と[4, 5, 6]
は、arrayWithLiteral1
とarrayWithLiteral2
に
var fruits = ["apple", "banana", "orange"] print(fruits[0]) // "apple" print(fruits[1]) // "banana" print(fruits[2]) // "orange"
fruits
のfruits[0]
と(
となります。
配列 の結合
+
演算 子 を使 った配列 の結合
+
let array1 = [1, 2, 3] let array2 = [4, 5, 6] let joinedArray = array1 + array2 print(joinedArray) // => [1, 2, 3, 4, 5, 6]
+=
演算 子 を使 った配列 の結合
+=
var array3 = [7, 8, 9] array3 += [10, 11, 12] print(array3) // => [7, 8, 9, 10, 11, 12]
配列 の代入
Swiftの
var array4 = [13, 14, 15] var array5 = array4 array5.append(16) print(array4) // => [13, 14, 15] print(array5) // => [13, 14, 15, 16]
ただし、
基本 操作
var arr = [0, 1, 2, 3, 4, 5, 6] arr.append(7) print(arr) // [0, 1, 2, 3, 4, 5, 6, 7] arr += [8, 9, 10] print(arr) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] arr.insert(11, at:2) print(arr) // [0, 1, 11, 2, 3, 4, 5, 6, 7, 8, 9, 10] arr[2] = 12 print(arr) // [0, 1, 12, 2, 3, 4, 5, 6, 7, 8, 9, 10] arr[2...2] = [11, 12, 13] print(arr) // [0, 1, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9, 10] arr.remove(at:0) print(arr) // [1, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9, 10] arr.removeLast() print(arr) // [1, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9] arr[5...] = [99] print(arr) // [1, 11, 12, 13, 2, 99] let index13 = arr.index(of: 13) print(index13) // Optional(3) let squared = arr.map{ i in i * i } print(squared) // [1, 121, 144, 169, 4, 9801] let filtered = arr.filter{ n in n > 3 } print(filtered) // [11, 12, 13, 99] let sorted = arr.sorted{ (a, b) in a > b } print(sorted) // [99, 13, 12, 11, 2, 1] let sum = arr.reduce(0){ (s, n) in s + n } print(sum) // 138 arr.forEach{ n in print(n) } // 1↵121↵144↵169↵4↵9801 let arr1 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] let arr1_1 = arr1.map{ a -> [Int] in a.reversed() } print(arr1_1) // [[3, 2, 1], [6, 5, 4], [9, 8, 7]] let arr1_2 = arr1.flatMap{ a -> [Int] in a.reversed() } print(arr1_2) // [3, 2, 1, 6, 5, 4, 9, 8, 7] let arr2 = [1, 2, nil, 4] let arr2_1 = arr2.map{ n -> Int? in n } print(arr2_1) // [Optional(1), Optional(2), nil, Optional(4)] let arr2_2 = arr2.flatMap{ n -> Int? in n } print(arr2_2) // [1, 2, 4]
このコードは、Swift
append()
メソッドは、+=
insert()
メソッドは、remove()
メソッドは、removeLast()
メソッドは、
map()
メソッドは、filter()
メソッドは、sorted()
メソッドは、reduce()
メソッドは、forEach()
メソッドは、
map()
メソッドは、flatMap()
メソッドは、map()
メソッドはオプショナルflatMap()
メソッドはnil
集合
Swiftの
//
空 の集合 を作成 する var setA = Set<Int>() print(setA) // [] //初期 値 を指定 して集合 を作成 する var setB: Set<Int> = [1, 2, 3] print(setB) // [1, 2, 3] //集合 に要素 を追加 する setA.insert(1) setA.insert(2) setA.insert(3) setA.insert(4) print(setA) // [1, 2, 3, 4] //集合 から要素 を削除 する setA.remove(3) print(setA) // [1, 2, 4] //集合 の要素 数 を取得 する print(setA.count) // 3 //集合 に要素 が含 まれているかを調 べる print(setA.contains(1)) // true print(setA.contains(3)) // false //集合 を空 にする setA.removeAll() print(setA) // [] //集合 の演算 let set1: Set<Int> = [1, 2, 3, 4] let set2: Set<Int> = [3, 4, 5, 6] //和 集合 を取得 する let unionSet = set1.union(set2) print(unionSet) // [1, 2, 3, 4, 5, 6] //積 集合 を取得 する let intersectionSet = set1.intersection(set2) print(intersectionSet) // [3, 4] //差 集合 を取得 する let subtractingSet = set1.subtracting(set2) print(subtractingSet) // [1, 2] //対称 差 集合 を取得 する let symmetricDifferenceSet = set1.symmetricDifference(set2) print(symmetricDifferenceSet) // [1, 2, 5, 6]
Swiftの
まず、forループを
let set: Set = ["apple", "orange", "banana"] for element in set { print(element) } // apple // orange // banana
このSet
のfor-in
ループで1つずつ
map()
、filter()
、reduce()
のような
map()
Set
のSet
を
let set: Set = [1, 2, 3, 4, 5] let mappedSet = set.map { $0 * 2 } print(mappedSet) // [2, 4, 10, 8, 6]
このSet
のSet
をmap()
Set
の
また、filter()
Set
の
let set: Set = [1, 2, 3, 4, 5] let filteredSet = set.filter { $0 % 2 == 0 } print(filteredSet) // [4, 2]
このSet
のSet
を
reduce()
Set
の
let set: Set = [1, 2, 3, 4, 5] let sum = set.reduce(0) { $0 + $1 } print(sum) // 15
このSet
のreduce()
Set
の
辞書
Swiftの
var dict: [KeyType: ValueType] = [KeyType: ValueType]()
ここで、KeyTypeはキーのデータ
var numberDict: [String: Int] = ["one": 1, "two": 2, "three": 3]
print(numberDict["one"]) // Optional(1) print(numberDict["four"]) // nil
contains
メソッドを
if numberDict.contains(where: { $0.key == "one" }) { print("Key exists") } else { print("Key does not exist") }
numberDict["four"] = 4
removeValue(forKey:)
メソッドを
numberDict.removeValue(forKey: "four")
numberDict["one"] = 10
for-in
ループを
for (key, value) in numberDict { print("\(key): \(value)") }
keys
プロパティを
for key in numberDict.keys { print(key) }
values
プロパティを
for value in numberDict.values { print(value) }
map
、filter
、reduce
などの
map
は(key, value)
のタプルをdict
の
let dict = ["a": 1, "b": 2, "c": 3] let doubled = dict.map { (key, value) in (key, value * 2) } print(doubled) // ["a": 2, "b": 4, "c": 6]
filter
は(key, value)
のタプルを
let dict = ["a": 1, "b": 2, "c": 3] let oddValues = dict.filter { (key, value) in value % 2 != 0 } print(oddValues) // ["a": 1, "c": 3]
reduce
は(key, value)
のタプルをdict
の
let dict = ["a": 1, "b": 2, "c": 3] let sum = dict.reduce(0) { (result, keyValue) in let (_, value) = keyValue return result + value } print(sum) // 6
タプル
Swiftのタプルは、
let myTuple = ("apple", 3.14, true) print(myTuple) //
出力 : ("apple", 3.14, true)
タプルには、
タプルの
let myTuple = ("apple", 3.14, true) print(myTuple.0) //
出力 : apple print(myTuple.1) //出力 : 3.14 print(myTuple.2) //出力 : true
また、タプルの
let myTuple = (name: "apple", price: 100, isOnSale: true) print(myTuple.name) //
出力 : apple print(myTuple.price) //出力 : 100 print(myTuple.isOnSale) //出力 : true
タプルは、
func findMinMax(array: [Int]) -> (min: Int, max: Int) { var min = array[0] var max = array[0] for value in array { if value < min { min = value } if value > max { max = value } } return (min, max) } let result = findMinMax(array: [3, 5, 2, 8, 1]) print("
最小 値 : \(result.min),最大 値 : \(result.max)") //出力 :最小 値 : 1,最大 値 : 8
このfindMinMax
result
は、タプルであるため、.min
と.max
を
オプショナル型
Swiftにおけるオプショナル(Optional)は、nil
という
Int
x
をnil
となります。
var x: Int?
このようにオプショナルを
オプショナルのnil
でないことを
var optionalInt: Int? = 10 // optionalIntがnilでないことを
確認 してからアクセスする if let unwrappedInt = optionalInt { print(unwrappedInt) } //強制 的 にアンラップする let unwrappedInt2 = optionalInt! print(unwrappedInt2)
optionalInt
に10
をif let
optionalInt
がnil
でないことをunwrappedInt
にアンラップした!
optionalInt
がnil
である
また、オプショナルguard let
func foo(optionalStr: String?) { guard let unwrappedStr = optionalStr else { print("optionalStr is nil") return } print(unwrappedStr) } foo(optionalStr: "Hello, world!") // Hello, world! foo(optionalStr: nil) // optionalStr is nil
このfoo
optionalStr
がnil
でないunwrappedStr
にアンラップされたnil
であるguard
オプショナル??
を
var optionalStr: String? = nil let unwrappedStr = optionalStr ?? ""
- オプショナル
連鎖
Swiftにおいて、オプショナルの
オプショナル
struct Person { var name: String var age: Int? } let person: Person? = Person(name: "John", age: 30) // オプショナル
連鎖 を使用 せずにageにアクセスすると、コンパイルエラーになる // let age = person.age // オプショナル連鎖 を使用 してageにアクセスする let age = person?.age print(age) // Optional(30)
person
はPerson
age
プロパティもオプショナルです。let age = person?.age
とすることで、person
がnil
でないage
にアクセスされます。age
のInt?
となります。
また、オプショナル
struct Car { var name: String func drive() { print("\(name) is driving.") } } var car: Car? = Car(name: "Tesla") // オプショナル
連鎖 を使用 してdriveメソッドにアクセスする car?.drive() // "Tesla is driving." car = nil // オプショナル連鎖 を使用 してdriveメソッドにアクセスする car?.drive() //何 も出力 されない
car
はCar
car?.drive()
とすることで、car
がnil
でないdrive
メソッドが
オプショナル
演算 子
Swiftにおいて、
このセクションでは、Swiftで
算術 演算 子
+ |
|
- |
|
* |
|
/ |
|
% |
|
&+ |
|
&- |
|
&* |
|
&/ |
0 となります)(※ |
&% |
0 となります)(※ |
+ |
|
- |
|
++ |
インクリメント( |
-- |
デクリメント( |
++ |
インクリメント( |
-- |
デクリメント( |
比較 演算 子
|
|
|
print(1...5 ~= 3) // true
var str = "mission control" print(str.range(of: "control")! ~= str.index(of: "c")!) // true
論理 演算 子
&& |
|
|| |
|
! |
三 項 演算 子
|
nil結合 演算 子
?? |
T? T nil であれば |
"x".toInt() ?? 0 // 0 "5".toInt() ?? 0 // 5
ビット演算 子
<< |
|
>> |
|
& |
AND |
| |
OR |
^ |
XOR |
~ |
NOT(ビット |
代入 演算 子
|
|
範囲 演算 子
..< |
|
... |
キャスト演算 子
is |
|
as |
|
as? |
オプショナル |
as! |
- キャスト
演算 子 var arr:[Any] = [1, 2.0, "3", -4] for item in arr { let intItem = item as? Int print(intItem) }
実行 結果 Optional(1) nil nil Optional(-4)
import Foundation var array1 = [1, 2, 3, 4] as NSArray var mutableArray1 = array1 as? NSMutableArray // ダウンキャストできないので、nilになる // ※
補足 :上記 の例 の場合 、Mutableな状態 で取得 したければ array1.mutableCopy() を行 うべき。 var mutableArray2 = [1, 2, 3, 4] as NSMutableArray var array2 = mutableArray2 as NSArray var mutableArray2_2 = array2 as? NSMutableArray //元々 mutableArray2の型 はNSMutableArrayなので、キャストに成功 する
その他
let リンゴの
数 = 3 let みかんの数 = 5
\(...)
には、
let リンゴ
説明 = "私 は\(リンゴの数 )個 のリンゴを持 っています。" // ”私 は3個 のリンゴを持 っています。" let果物 説明 = "私 は\(リンゴの数 + みかんの数 )個 の果物 を持 っています。" //"私 は8個 の果物 を持 っています。"
ヒアドキュメントには、ダブルクォーテーション3つを
let tanka = """
田子 の浦 に うち出 でてみれば白妙 の富士 の高嶺 に雪 は降 りつつ """ print(tanka)
0b
"で20o
"で80x
"で16
let dec = 29 let bin = 0b11101 // 2
進数 で29 let oct = 0o35 // 8進数 で29 let hex = 0x1D // 16進数 で29
let
π = 3.1415926535897931 let pi = 0x1.921fb54442d18p+1 // NSString(format:"%a",π ) の出力 と同様
let threeHundledMillion = 300_000_000 let bitMask: UInt8 = 0b0010_0000
アンダースコアは、
var s:String? = "String" if let _ = s { print("sはnilではありません。") }
for _ in 0..<5 { print("repeat") }
let result = (404, "Not Found", false) let (_, message, _) = result
他 言語 との比較
C言語 との類似 点
- ほとんどのC
言語 の演算 子 はSwiftでも使用 できます。- ただし、Swiftではオーバーフローを
伴 う数値 演算 のサポートのための演算 子 が追加 されています。
- ただし、Swiftではオーバーフローを
中 括弧 は、文 をグループ化 するために使用 されます。等号 1つ=
は代入 、2つ==
は等価 比較 を意味 します。- この
他 に、Swiftでは等号 3つ===
は同 じオブジェクトを参照 しているかどうかを確認 するための演算 子 を意味 します。
- この
while
、if
、for
等 の制御 文 が類似 しています。- ただし、Swiftでは
拡張 機能 を有 します。例 えば、while
、if
文 はパターンマッチングや条件 付 きOptionalアンラップをサポートします。
- ただし、Swiftでは
角 括弧 は、配列 の宣言 と配列 の要素 取得 の両方 で使用 されます。
Objective-Cとの類似 点
基本 的 な数値 型 Int
、UInt
、Float
、Double
等 のサポート。- クラスメソッドは、インスタンスメソッドと
同様 に継承 されます。クラスメソッド内 のself
は、メソッドが呼 び出 されたクラスを意味 します。 for
...in
列挙 構文 のサポート。
Objective-Cとの相違 点
文 はセミコロン(;
)で終 わる必要 はありません。しかし、1行 に複数 の文 を記述 する際 に使用 することができます。- ヘッダーファイルが
存在 しません。 /*
~*/
によるコメントはネストできます。型 推論 のサポート。- ジェネリックプログラミングのサポート。
関数 は第 一 級 オブジェクトです。演算 子 はクラスに対 して再 定義 (演算 子 のオーバーロード)でき、新 しい演算 子 を定義 できます。文字 列 はUnicodeを完全 にサポートします。ほとんどのUnicode文字 は識別子 や演算 子 でも使用 できます。例外 処理 は存在 しません。Swift 2では例外 処理 とは互換 性 のない別 のエラー処理 モデルが導入 されています。- バグの
原因 となるC言語 ファミリーの特徴 がいくつか削除 されています。- デフォルトでは、ポインタは
公開 されていません。プログラマが参照 の管理 をする必要 はありません。 変数 割 り当 ては値 を返 しません。これにより、=
と==
の誤用 を防 ぐことができます。switch
文 内 でbreak
を行 う必要 はありません。明示 的 にfallthrough
を行 わない限 り次 のcase
にフォールスルーすることはありません。変数 と定数 は常 に初期 化 され、配列 の境界 は常 にチェックされます。算術 オーバーフローは実行 時 エラーとしてトラップされます。オーバーフローを許可 する演算 子 は&+
、&-
、&*
、&/
、&%
として定義 されます。また、全 ての整数 型 にはプロパティmin
、max
が定義 されており、潜在 的 なオーバーフローのチェックに利用 することができます。- ブロックを
用 いない1行 のif
文 、while
文 はサポートされていません。 - Off-by-oneエラーの
原因 となるC言語 スタイルのfor (int i = 0; i < c; i++)
文 は、Swift 3で削除 されました。 - インクリメント
演算 子 ++
、デクリメント演算 子 --
は、Swift 3で削除 されました。
- デフォルトでは、ポインタは
脚註
外部 リンク
附録
コードギャラリー
エラトステネスの篩
エラトステネスの
- エラトステネスの
篩 import Foundation func sieveOfEratosthenes(_ n: Int) -> [Int] { var sieve = Array(repeating: true, count: n + 1) sieve[0] = false sieve[1] = false let sqrtN = Int(sqrt(Double(n))) for i in 2...sqrtN { if sieve[i] { for j in stride(from: i * i, through: n, by: i) { sieve[j] = false } } } return sieve.enumerated().compactMap { $1 ? $0 : nil } } print(sieveOfEratosthenes(100))
実行 結果 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
最大公約数 と最小公倍数
最大公約数 と最小公倍数 func gcd2(_ m: Int, _ n: Int) -> Int { n == 0 ? m : gcd2(n, m % n) } func gcd(_ args: Int...) -> Int { guard let first = args.first else { return 0 } return args.suffix(args.count - 1).reduce(first){ gcd2($0, $1) } } func lcm2(_ m: Int, _ n: Int) -> Int { m * n / gcd2(m, n) } func lcm(_ args: Int...) -> Int { guard let first = args.first else { return 0 } return args.suffix(args.count - 1).reduce(first){ lcm2($0, $1) } } print("gcd2(30, 45) => \(gcd2(30, 45))") print("gcd(30, 72, 12) => \(gcd(30, 72, 12))") print("lcm2(30, 72) => \(lcm2(30, 72))") print("lcm(30, 42, 72) => \(lcm(30, 42, 72))")
実行 結果 gcd2(30, 45) => 15 gcd(30, 72, 12) => 6 lcm2(30, 72) => 360 lcm(30, 42, 72) => 2520
二分 法
二分 法 func bisection(low: Double, high: Double, f: (Double) -> Double) -> Double { var low = low var high = high var x = (low + high) / 2.0 var fx = f(x) if abs(fx) < 1.0e-10 { return x } if fx < 0.0 { low = x } else { high = x } return bisection(low: low, high: high, f: f) } let result1 = bisection(low: 0, high: 3) { x in return x - 1 } print(result1) let result2 = bisection(low: 0, high: 3) { x in return x * x - 1 } print(result2)
実行 結果 0.9999999999417923 1.0000000000291038
旧 課程 (-2012年度 )高等 学校 数学 B/数値 計算 とコンピューター#2分 法 の例 を Swift に移植 しました。