Swiftの文法
1. 変数、配列、ディクショナリ、制御
変数の定義
// letでイミュータブルな変数(1行コメント)
// イミュータブル……作成後に状態を変えられないオブジェクトのこと。対義語はミュータブル
let immutableStr = "hello"
immutableStr += " world" // => error
/*
* varでミュータブルな変数
* (複数行コメント)
*/
var mutableStr = "hello"
mutableStr += " world"
print(mutableStr) // => hello world
- 上の例では、型推論により、変数の型はString型となります。明示的に型を指定するには、以下のように書きます。
var mutableStr: String = "hello"
- Swiftでは 暗黙の型変換は行われません。よって、型を変換したい場合は、明示的に記述する必要があります。
let label = "This year is "
let year = 2017
let thisYear = label + String(2017)
print(thisYear) // => This year is 2017
// 文字列内での変数展開
let nextYear = "Next year is \(year + 1)"
print(nextYear) // => Next year is 2018
配列の定義
var itemsArray = ["foo", "bar", "baz"]
// 型を明示
var itemsArray: [String] = ["foo", "bar", "baz"]
ディクショナリの定義
var itemsDictionary = [
"foo": "FOO",
"bar": "BAR",
"baz": "BAZ"
]
// 型を明示
var itemsDictionary: [String: String] = [
"foo": "FOO",
"bar": "BAR",
"baz": "BAZ"
]
制御構造
// for, if-else
let list = [3, 7, 9, 12, 8, 5]
for number in list {
if number % 2 == 0 {
print("number \(number) is even")
} else {
print("number \(number) is odd")
}
}
// while
var number = 1
while number < 10 {
print(number)
number += 1
}
// switch-case
let age = 17
switch age {
case 0...6: // rangeオブジェクトをつかう事ができる
print("kindergarden kid")
case 7...12:
print("primary school student")
case 13...15:
print("junior high school student")
case 16...18:
print("high school student")
case 19...22:
print("college student")
default:
print("business person")
}
// => high school student
2. 関数、クロージャ、クラス
関数(メソッド)
func greet(expression: String, person: String) -> String {
return "\(expression) \(person)."
}
greet(expression: "Hello", person: "Mike") // => "Hello Mike."
func greet(_ expression: String, to person: String) -> String {
return "\(expression) \(person)."
}
// _ で引数ラベルの省略。 引数のラベル名をつけることもできる
greet("Hello", to: "Mike") // => "Hello Mike."
クロージャ
func incrementer() -> ( () -> Int ) {
var count = 0
func increment() -> Int {
count += 1
return count
}
return increment
}
var counter = incrementer()
counter() // => 1
counter() // => 2
counter() // => 3
- returnされる関数を無名関数に
func incrementerWithAnonymousFunc() -> ( () -> Int ) {
var count = 0
return { () -> Int in
count += 1
return count
}
}
var counter2 = incrementerWithAnonymousFunc()
counter2() // => 1
counter2() // => 2
counter2() // => 3
- 関数は、引数として関数を受け取ることができます。
func numbersMap(list: [Int], condition: (Int) -> Int) -> [Int] {
var numbers: [Int] = []
for item in list {
numbers.append( condition(item) )
}
return numbers
}
var items: [Int] = [1, 2, 3, 4, 5]
numbersMap(list: items, condition: { (number: Int) -> Int in number * 2 }) // => [2, 4, 6, 8, 10]
- このクロージャ機能により、Swiftではmap、filter、reduce等のメソッドに、引数として無名関数のブロックコードを渡して処理することができます。 ```swift var numbers = [3, 7, 9, 12, 8, 5] // 配列の要素をすべて2倍にする numbers.map({ (number: Int) -> Int in return number * 2 }) // => [6, 14, 18, 24, 16, 10]
// 奇数のみを抽出する numbers.filter({ (number: Int) -> Bool in return number % 2 == 1 }) // => [3, 7, 9, 5]
// すべての合計を計算する numbers.reduce(0, { (total: Int, number: Int) -> Int in return total + number }) // => 44
- map、filter、reduceの引数でブロックコードを渡す場合は、型指定を省略した書き方が可能
```swift
numbers.map{ number in number * 2 } // => [6, 14, 18, 24, 16, 10]
numbers.filter{ number in number % 2 == 1 } // => [3, 7, 9, 5]
numbers.reduce(0){ total, number in total + number } // => 44
クラス
class MyApp {
// Shapeクラスの定義
class Shape {
// nameプロパティ(インスタンス変数)
var name: String
// イニシャライザ(コンストラクタ)
init(name: String) {
self.name = name
}
}
// 四角形: RectangleがShapeを継承
class Rectangle: Shape {
var width: Double
var height: Double
init(name: String, width: Double, height: Double) {
self.width = width
self.height = height
// 親クラスのイニシャライザ呼び出し
super.init(name: name)
}
func area() -> Double {
return width * height
}
}
// 三角形: TriangleがShapeを継承
class Triangle: Shape {
var bottom: Double
var height: Double
init(name: String, bottom: Double, height: Double) {
self.bottom = bottom
self.height = height
super.init(name: name)
}
func area() -> Double {
return bottom * height / 2.0
}
}
}
// 正方形を作成
var square = MyApp.Rectangle(name: "My Square", width: 7.5, height: 7.5)
square.name // => "My Square"
square.area() // => 56.25
// 三角形を作成
var triangle = MyApp.Triangle(name: "My Triangle", bottom: 10, height: 8)
triangle.name // => "My Triangle"
triangle.area() // => 40