詳解Swift 第5版 第2章まとめ -オーバーロード・タプル-


こんにちは、マっさんです!

この記事は筆者に必要な部分を切り出し、まとめたものです。
詳しい内容を知りたい方は、ご購入をおすすめします。
S

詳解 Swift 第5版

詳解 Swift 第5版

オーバーロード

オーバーロードとは

同じ関数名で、引数の個数が違ったり、型が違う別の関数を定義する事を言います。
これを関数のオーバーロードと言います。

//(1)引数が二つの関数
func mySwap(_ a: inout Int, _ b: inout Int){
    let t = a; a = b; b =t
}

//(2)引数が3つの関数
//同じ関数名で引数が異なる関数が定義できる
func mySwap(_ a: inout Int, _ b: inout Int, _ c: inout Int) {
     let t = a; a = b; b = c; c = t 
}

var s = 10, t = 20
var x =1, y = 2, z =3
mySwap(&s, &t) //(1)を呼び出し
print("s=\(s), t=\(t)")

mySwap(&x, &y, &z) //(2)を呼び出し
print("x=\(x), y=\(y), z=\(z)") 
// 実行結果
s=20, t=10
x=2, y=3, z=1

また、返り値の異なるオーバーロード関数を定義する事もできます。
ただし、返り値の型が明確になる様な使い方をしないと、コンパイラが混乱する為、あまり使ってはいけません。

引数ラベルを使ったオーバーロード

Swiftではさらに、引数ラベルとして異なる識別子を指定することにより、同名で別の関数を定義できます。
下記の例を使って、以下の様に定義できます。

func mySwap(_ a: inout String, _ b: inout String) {
    let t = a; a = b; b = t
}

var a = "Alcott", b = "Bodewig"
mySwap(&a, &b)
print("a=\(a), b=\(b)")

func mySwap(little a: inout Int, great b: inout Int) {
    if a > b {
        let t = a; a = b; b = t
    }
}

s = 10; t = 20
mySwap(little:&s, great:&t)
print("s=\(s), t=\(t)")
mySwap(little:&t, great:&s)
print("s=\(s), t=\(t)")
// 実行結果
a=Bodewig, b=Alcott
s=10, t=20
s=20, t=10

この様に、同名関数、別名ラベル・別型の引数なら使用することができます。
これが、オーバーロードです。

Apple社のドキュメントに記載されている関数について

オーバーロードの説明をしていますが、これを応用してAppleのドキュメントについて説明します。 まずこちらのAppleのDocumentをみてください。
f:id:MasayaStripes:20191204150033p:plain この記法は、Apple のドキュメントでよく見かける記法であります。
この記法の意味は、まず関数名が記載され、()内に引数ラベル「 _ 」と「 : 」を交互に書き並べています。
つまり、この関数absの呼び出し方としては、「 _ 」なので、「引数ラベルはなんでも良い」
と言うことになります。
もし指定されているのであれば、例として”mySwap(little:great:)”と言う風に書かれます。

タプル

タプルとは

タプルとは、
複数個のデータを組みにしてまとめたものです。
これは、一時的に保持したりするとうな用途で使うべきです。
複雑になる場合は、構造体や辞書型、もしくはクラスを使いましょう。

以下が使い方の例になります

let m = ("moneky.jpg", 161_022) // ファイル名とバイト数

// 型宣言した場合
let m : (string, Int) = ("moneky.jpg", 161_022)

二つだけでなく、複数の要素でも使えます。

let cat = ("cat .jpg", 1024, 768)
var img : (String, Int, Int) = cat // 代入可能

print("\(img.0): \(img.1) x \(img.2)")
img.2 = 800
print("\(img.1)x\(img.2)")
//実行結果
cat .jpg:1024x768
1024x800

タプルと代入操作

タプルの代入操作は以下の様に代入できます。

let photo = ("tiger.jpg", 640, 800)
let (file, width, height) = photo
print("\(file): \(width)x\(height)") 

// 実行結果
tiger.jpg: 640x800

ここでも、ワイルドカードの"_"を使うことができます。
ここでの意味は、
その値を明示的に使用しない
という意味です。

// ファイル名だけを使う
let (file, _, _) = photo

任意のインスタンスもタプルに入れることができます。
例えば、タプル内にタプルを入れるということもできます。

let pic = ("snake.jpg", (780, 1024))
let (file, (w, h)) = pic
let(name, _) = pic

このタプルを使えば初心者の方には比較的難しい、フィボナッチ数列も簡単に実装できます。

var fibo1 = 0, fibo2 = 1

print(fibo1, terminator: " ")
for _ in 0 ..< 50 {
    (fibo1, fibo2) = (fibo2, fibo1 + fibo2)
    print(fibo1, terminator:" ")
}
print()
//実行結果
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2971215073 4807526976 7778742049 12586269025 

タプルを返す関数

タプルは関数の処理結果を返すこともできます。
利点としては、
複数の値を手早く受け取れる、処理できる
という点です。

func BMI(tall:Double, weight:Double) -> (Double, Double) {
    let ideal = 22.0
    let t2 = tall * tall / 10000.0
    let index = weight / t2
    return (index, ideal * t2)
}

let result = BMI(tall:177.0, weight:80.0)
print(result)
(25.535446391522232, 68.9238)

考察

今回はオーバーロードとタプルについて、まとめていきました。
特に私にとってタプルはすごく使いやすくて、個人プロジェクトや実装で使っています。
Swiftには他の言語では見られない、より賢く書く書き方があるイメージが多くある様に見受けれました。(まぁPerl とJavaしか本格的にやったことないんですがねw)

今回は以上!

詳解 Swift 第5版

詳解 Swift 第5版