A Swift Tourをなぞるメモ

自分がswiftを始めたので勉強がてらAppleの公式ドキュメントを読みながら、swiftの言語仕様、というよりサンプルコードを記述していきます。

Appleの公式ドキュメント（[A Swift Tour](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-ID1)）より「クラス」まで

## ログ表示する

```swift:swift
print("Hello World")
//注：シングルクオートだとエラーになる
//print('Hello World')
```

## 変数

```swift:swfit
var hoge = "hoge"
hoge = "hogehoge"
```

## 定数

```swift:swift
let piyo = "piyo"
//以下はエラー：定数は値の変更が出来ない
//piyo = "piyopiyo"
```

## 型推論
変数の宣言時に型を明示しなくても良い。

```swift:swift
//変数hogeの型が文字列型になる
var hoge = "hoge"
//以下はエラーになる：hogeの型が文字列型になっているためint型の値の代入が出来ない
//hoge = 1
```

型を明示的に指定する場合

```swift:swift
var hoge:String = "hoge"
let piyoNum:Double = 3
```

##　数値型から文字列型への変換

```swift:swift
var num1 = 1
var dispNum1 = "this is num1," + String(num1)

var num2 = 2
var dispNum2 = "this is num2,\(num2)"
```

## 配列と辞書
最後の要素の後にコンマがあっても問題なし

###配列

```swift:swift
//配列
var shoppingList = ["milk", "water", "banana",]
print(shoppingList[2]) //banana

//型を明示して初期化
var emptyArray = [String]()
//要素の追加
emptyArray.append("hoge")

//色々な型の値を入れる場合
var aryArray = [Any]()
anyArray.append("hardware")
anyArray.append(3)
```

### 辞書

```swift:swift
//辞書
var occupations = [
    "Malcolm":"Captain",
    "Kaylee":"Mechanic",
]
print(occupations["Malcolm"]) //Captain

//型を明示して初期化
var emptyDict = [String:Float]()
//要素の追加
emptyDict["hoge"] = 2
emptyDict["piyo"] = 3
```

### if文

```swift:swift
var hogeVal = 1
if hogeVal == 1 {
    print("hogeval is 1")
}else{
    print("hogeval is not 1")
}
```

### Optional
swiftにはoptionalという機能があり、変数・定数がnilを許容するかどうかを設定できる。

変数・定数の後に型を指定し、その後に?マークを付けるとoptionalになる。

```swift:swift
var optionalString:String? = "Hello"
//nilを代入してもエラーにならない
optionalString = nil
```

### switch文
swfitのswitch文では柔軟な比較ができる

```swift:swfit
var name = "John Mackenzie"
switch name {
case "John Appleseed":
    print("John Appleseed")
case "John Jonny", "John Mackenz":
    print("John Jonny or Mackenz")
case let x where name.hasPrefix("John"):
    print("the name has John")
default:
    "default"
}
//the name has John
```

### forin文

```swift:swfit
//配列
var fruitAry:Array = [String]()
fruitAry = ["Apple", "Banana", "Grape", "Orange"]
for fruit in fruitAry {
    print(fruit)
}

//辞書
var fruitDict:Dictionary = [String:Int]()
fruitDict = [
    "Apple":1,
    "Banana":2,
    "Grape":3,
    "Orange":4,
]
for (fruit/*key*/, num /*value*/) in fruitDict {
    print("The number of \(fruit) is \(num)")
}
```

### while文

```swift:swift
var num = 3
while num < 100
{
    num = num + 1
}
print(num)
```

### repeatwhile文
```swift:swift
var num2 = 3
repeat{
    num2 = num2 + 1
}while num2 < 100
print(num2)
```

### Function

```swift:swfit
func greet(person:String /*引数1*/, day:String/*引数2*/) -> String/*返り値*/{
    return "Hello \(person), today is \(day)"
}
greet(person: "John", day: "/1612/5")

//使われる側で引数にラベルを使いたくない場合
func greet2( _ person:String) -> String
{
    return "My name is \(person))"
}
greet2("John")

//呼ぶ側と呼ばれる側でラベルを変えたい場合
func greet3(name/*呼ぶ側のラベル*/ person/*呼ばれる側のラベル*/:String) -> String
{
    return "My name is \(person)"
}
greet3(name: "John")
```

### タプル
関数の返り値として返却できる複合的な値をタプルという。タプルの中身は名前でもインデックスでもアクセスできる。

```swift:swift
func calc(scores:[Int]) -> (min: Int, sum:Int)
{
    var min = scores[0]
    var sum = 0
    for score in scores {
        if score < min {
            min = score
        }
        sum = score + sum
    }
　　 //タプルを返却
    return (min, sum)
}
var calcResult = calc(scores: [1,3,5,7,9])
print(calcResult.min) //1
print(calcResult.1) //25
```

### 関数のネスト

```swift:swfit
func compSentence(sentence:String) -> String
{
    var compSentence:String
    //関数内関数
    func addMaru(sentence:String) -> String
    {
        return "\(sentence)です。"
    }
    compSentence = addMaru(sentence: sentence)
    return compSentence
}
print(compSentence(sentence: "私はジョン"))
```

### 関数を返却する関数

```swift:swift
func makeIncrementer() -> ((Int) -> Int)
{
    func addOne(number:Int) -> Int
    {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)
```
### 関数を引数とする関数

```swift:swift
//function which takes another function as its argument

func getBirthDaySentence( name:String, dateGetter:(String) -> String ) -> String
{
    return "The birthday of \(name) is \(dateGetter(name))"
}

func getBirthday( name:String ) -> String
{
    if name == "John Appleseed" {
        return "12/5"
    }else{
        return "unknown"
    }
}

print(getBirthDaySentence(name: "John Appleseed", dateGetter: getBirthday))
```
### クロージャー
無名の関数オブジェクトという理解でいいのだろうか。。

```swift:swift
var numbers = [1,3,5,7]
//map:配列の要素を一つ取り出し、引数のクロージャーに渡し、返り値をその要素の代わりに保持する、を要素数だけ順番に行う。
var ret = numbers.map(
    //以下クロージャー
    {
        (number:Int)/*引数*/ -> Int/*返り値の型*/ in
        let result = 3*number
        return result
    }
)
print(ret) //[3,9,15,21]
```

### クラス

```swift:swift
class Cat{
    let crySound:String = "meow"
    var name:String
    init(name:String) {
        self.name = name
    }
    func cry() -> String{
        return crySound
    }
    
}
var cat = Cat(name:"mike")
print(cat.name) //mike
```