Swiftの戻り値を完全解説!たった10のサンプルコードでマスター

Swiftの戻り値のイメージとサンプルコードのスクリーンショットSwift
この記事は約16分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

あなたがSwiftのプログラミングを始めて、関数の基本を学ぶ中で、”戻り値”という言葉に出会ったことはありませんか?

関数が何かの計算や処理を行い、その結果を外部に伝えるための仕組み、それが戻り値です。

この記事を読めば、Swiftの戻り値を理解し、使いこなすことができるようになります。

具体的なサンプルコードとともに、初心者から中級者までしっかりとサポートします。

●Swiftの戻り値とは

Swiftの戻り値は、関数やメソッドが処理を完了した後に返す値のことを指します。

この戻り値は、関数内部で計算や処理された結果を外部に伝えるのに非常に役立ちます。

○基本的な定義と概念

Swiftでの関数の定義方法は、funcキーワードを使います。

そして、戻り値を持つ関数を定義する際には、関数名の後の括弧()の後に->を使って、戻る値の型を指定します。

このコードでは、addという名前の関数を定義しています。

この関数は、2つのInt型の引数abを取り、その合計をInt型の戻り値として返します。

func add(a: Int, b: Int) -> Int {
    return a + b
}

このコードを実行すると、add関数に2と3を引数として渡した場合、5という値が戻ります。

Swiftの戻り値は、関数内で処理された結果を返すだけでなく、関数の外部でその値を利用する際にも非常に役立ちます。

例えば、上記のadd関数の戻り値は、変数に格納することができます。

let result = add(a: 2, b: 3)
print(result)  // 5と表示されます。

このように、Swiftの戻り値を利用することで、関数やメソッドの処理結果を柔軟に取り扱うことができます。

●Swiftの戻り値の使い方

Swiftの戻り値の魅力は、それだけでなく、その使い方の幅広さにあります。

ここでは、Swiftの戻り値の基本的な使い方から、より複雑な形の戻り値までを順番に学んでいきましょう。

○サンプルコード1:基本的な関数の戻り値

Swiftの関数では、処理の結果として何らかの値を返すことができます。

この値が、戻り値です。

ここでは、2つの数値を加算してその結果を返す簡単な関数を紹介します。

func sum(a: Int, b: Int) -> Int {
    return a + b
}

このコードでは、sumという関数はInt型の引数abを取り、その合計をInt型として返します。

この-> Intが戻り値の型を示しています。

実際に関数を呼び出すと、次のような結果になります。

let total = sum(a: 5, b: 3)
print(total)  // 8と表示されます。

○サンプルコード2:複数の戻り値を持つ関数

Swiftでは、1つの関数で複数の戻り値を返すこともできます。

その際に利用されるのが、タプル(tuple)というデータ型です。

ここでは、2つの数値の加算結果と減算結果を同時に返す関数を紹介します。

func calculate(a: Int, b: Int) -> (sum: Int, difference: Int) {
    return (a + b, a - b)
}

この関数を実行すると、加算と減算の結果がタプルとして返されます。

let result = calculate(a: 7, b: 3)
print("合計: \(result.sum), 差: \(result.difference)")  // 合計: 10, 差: 4と表示されます。

○サンプルコード3:オプショナルな戻り値

Swiftでは、戻り値が存在しない可能性を示すために、オプショナルという概念を導入しています。

オプショナルは、値が存在するか、または存在しない(nil)かの2つの状態を持ちます。

この機能は、関数が値を返せない場合やエラー時にnilを返すことで、呼び出し元にその状態を知らせるために非常に役立ちます。

下記のサンプルは、辞書からキーに対応する値を取得する際に、そのキーが存在しない場合はnilを返す関数です。

func getValue(from dictionary: [String: Int], key: String) -> Int? {
    return dictionary[key]
}

このコードではgetValue関数は、辞書とキーを引数として受け取り、戻り値の型がInt?となっていることから、Int型かnilのどちらかを返すことがわかります。

実際の呼び出しと結果は次のようになります。

let numbers = ["one": 1, "two": 2, "three": 3]
if let value = getValue(from: numbers, key: "four") {
    print("値は \(value) です。")
} else {
    print("キーに対応する値が見つかりませんでした。")
}
// キーに対応する値が見つかりませんでした。 と表示されます。

○サンプルコード4:タプルを使った戻り値

タプルは複数の値を一つのグループとして扱うためのデータ型です。

この特性を利用して、一つの関数から複数の戻り値を返すことができます。

例として、2つの整数の加算と乗算の結果を同時に返す関数を考えます。

func calculate(a: Int, b: Int) -> (addition: Int, multiplication: Int) {
    return (a + b, a * b)
}

関数を実行した結果は、

let results = calculate(a: 3, b: 4)
print("加算の結果: \(results.addition), 乗算の結果: \(results.multiplication)")
// 加算の結果: 7, 乗算の結果: 12 と表示されます。

○サンプルコード5:クロージャの戻り値

Swiftのクロージャは、関数のように動作する名前のないコードブロックです。

クロージャも関数と同様に、戻り値を持つことができます。

ここでは、与えられた数値を2倍にするクロージャを返す関数の例を紹介します。

func doubleMaker() -> (Int) -> Int {
    return { number in
        return number * 2
    }
}

この関数を使用してクロージャを取得し、実行すると、

let doubler = doubleMaker()
print(doubler(5))
// 10 と表示されます。

●Swiftの戻り値の応用例

Swiftの戻り値の基本的な使い方を学んだ後、さらに進んで応用的な使い方を探求してみましょう。

Swiftの関数やメソッドは非常に柔軟性が高く、さまざまな応用例が考えられます。

ここでは、特に実践的で役立つテクニックを中心に、サンプルコードを交えて詳しく解説していきます。

○サンプルコード6:高階関数としての使用

Swiftでは、関数はファーストクラスオブジェクトとして扱われます。

これにより、関数を引数や戻り値として利用することが可能です。

これを高階関数と呼びます。

例として、整数の配列と関数を引数に取り、その関数を配列の各要素に適用して新しい配列を生成する関数を考えます。

func applyFunction(on numbers: [Int], using function: (Int) -> Int) -> [Int] {
    return numbers.map(function)
}

このコードでは、applyFunctionは整数の配列と整数を引数に取り整数を返す関数を受け取ります。

そして、配列の各要素に関数を適用して新しい配列を生成します。

実行例として、次のようになります。

let result = applyFunction(on: [1, 2, 3, 4], using: { $0 * 2 })
print(result) 
// [2, 4, 6, 8] と出力されます。

○サンプルコード7:計算プロパティとしての戻り値

Swiftのプロパティには、実際に値を格納するストアドプロパティと、値を計算する計算プロパティがあります。

計算プロパティは、値を返すためのコードを書くことができ、この特性を利用して戻り値を持たせることができます。

ここでは、三角形の底辺と高さをプロパティとして持ち、面積を計算プロパティとして持つクラスの例を紹介します。

class Triangle {
    var base: Double
    var height: Double

    var area: Double {
        return 0.5 * base * height
    }

    init(base: Double, height: Double) {
        self.base = base
        self.height = height
    }
}

このクラスを使用して、三角形の面積を計算すると、

let triangle = Triangle(base: 10, height: 5)
print(triangle.area)
// 25.0 と出力されます。

○サンプルコード8:エラーハンドリングと戻り値

エラーハンドリングは、プログラム内で発生するエラーを的確に捉え、適切な処理を行うための手法です。

Swiftは、エラーハンドリングにthrowcatchを利用します。

関数やメソッドの戻り値と一緒にエラーハンドリングを利用することで、さまざまな状況に適切に対応することができます。

例えば、数字の文字列を整数に変換する関数を考えます。

この時、数字以外の文字列が与えられた場合にエラーを返すように設計します。

まず、エラーのタイプを定義します。

enum ConversionError: Error {
    case invalidInput
}

次に、文字列を整数に変換する関数を定義します。

func convertToInt(_ string: String) throws -> Int {
    guard let value = Int(string) else {
        throw ConversionError.invalidInput
    }
    return value
}

このコードでは、convertToInt関数は文字列を引数にとり、整数に変換して戻り値として返します。

変換できない場合、ConversionError.invalidInputエラーをスローします。

この関数を使用する際は、do-catchブロックを用いてエラーをキャッチします。

do {
    let result = try convertToInt("123")
    print(result) 
    // 123 と出力されます。
} catch ConversionError.invalidInput {
    print("無効な入力です。")
}

さらに、convertToInt("ABC")とすると、”無効な入力です。”という結果が得られます。

これにより、関数の戻り値を利用しながら、エラーの発生を適切にハンドルすることができます。

○サンプルコード9:ジェネリクスと戻り値

Swiftのジェネリクスは、型を汎用化することで、柔軟なコードを記述するための強力なツールです。

ジェネリクスを使用した関数やメソッドの戻り値は、多様な型に対応することができます。

ここでは、二つの値を交換するジェネリクス関数の例を紹介します。

func swapValues<T>(_ a: T, _ b: T) -> (T, T) {
    return (b, a)
}

このコードでは、swapValues関数はジェネリクスの型Tを使用しています。

この関数は、どんな型の値でも受け取り、その値を交換してタプルとして返します。

実行例として、次のようになります。

let swappedInts = swapValues(5, 10)
print(swappedInts) 
// (10, 5) と出力されます。

let swappedStrings = swapValues("first", "second")
print(swappedStrings) 
// ("second", "first") と出力されます。

これにより、関数の戻り値をジェネリクスで汎用化し、さまざまな型に適応することができます。

○サンプルコード10:アサーションと戻り値

Swiftのアサーションは、コードの特定の部分が期待する条件を満たしているかをチェックするデバッグツールです。

アサーションの条件がfalseの場合、プログラムはクラッシュします。

例として、2つの数値のうち大きい方を返す関数を考えますが、同じ数値が入力された場合はアサーションでチェックします。

func maxOfTwo(_ a: Int, _ b: Int) -> Int {
    assert(a != b, "入力された数値は同じです。")
    return a > b ? a : b
}

このコードでは、maxOfTwo関数は、2つの整数を引数にとり、大きい方の整数を戻り値として返します。

しかし、2つの整数が同じ場合、アサーションが発動し、エラーメッセージが表示されます。

この関数を実行すると、maxOfTwo(5, 10)の場合は10、maxOfTwo(15, 7)の場合は15という結果が得られます。

しかし、maxOfTwo(5, 5)とすると、”入力された数値は同じです。”というエラーメッセージとともにプログラムはクラッシュします。

●Swiftの戻り値の注意点と対処法

Swiftにおける関数やメソッドの戻り値は非常に便利ですが、正確に使用するためにはいくつかの注意点を把握しておく必要があります。

ここでは、戻り値の使用に関する主要な注意点と、それらの問題を避けるための対処法を詳しく解説します。

○戻り値の型推論に関する注意

Swiftは強力な型推論システムを持っており、多くの場合、変数や定数の型を明示的に宣言しなくても、適切な型が自動的に推論されます。

しかし、関数やメソッドの戻り値に関しては、型推論が予期しない動作を引き起こすことがあります。

例えば、次の関数は整数のリストを受け取り、その平均値を返すことを意図しています。

func average(of numbers: [Int]) -> Double {
    let sum = numbers.reduce(0, +)
    return Double(sum) / Double(numbers.count)
}

このコードでは、sumの型はIntと自動的に推論されます。

そのため、最後の行で明示的にDoubleへの変換が必要です。

この変換を忘れると、整数の除算となり、正確な平均値が計算されない可能性があります。

対処法としては、戻り値の型や中間変数の型を常に明示的に宣言することで、型推論によるミスを防ぐことができます。

○オーバーロードされた関数の戻り値の扱い

関数のオーバーロードは、同じ関数名を持ちながら異なる引数リストや戻り値の型を持つ関数を複数定義することを指します。

しかし、オーバーロードされた関数の戻り値の型が異なる場合、呼び出し時にどの関数が選択されるかが曖昧になることがあります。

例として、次の2つの関数を考えます。

func getValue() -> Int {
    return 10
}

func getValue() -> String {
    return "ten"
}

上記のように、getValue関数は2つの異なる戻り値の型を持っています。

この場合、関数を呼び出す際にどちらの関数が選択されるかは、戻り値を代入する変数や定数の型によって決まります。

このような状況を避けるためには、オーバーロードする関数の戻り値の型を統一するか、関数名を異なるものにすることが推奨されます。

また、戻り値の型に依存するようなオーバーロードは、コードの可読性や保守性を低下させる可能性があるため、適切な命名やコメントを付けることも大切です。

●戻り値のカスタマイズ方法

Swiftの戻り値は非常に柔軟性が高く、様々な方法でカスタマイズが可能です。

ここでは、カスタム戻り値の定義方法や、拡張機能を使用した戻り値のカスタマイズ方法を中心に、詳細に解説します。

○カスタム戻り値の定義方法

Swiftでは、標準のデータ型だけでなく、独自のデータ型を定義して戻り値として使用することもできます。

このようなカスタムデータ型を活用することで、より柔軟な戻り値の表現が可能となります。

例として、ユーザー情報を表す構造体を定義し、それを戻り値とする関数を考えてみましょう。

// ユーザー情報を表す構造体
struct UserInfo {
    var id: Int
    var name: String
    var email: String
}

// ユーザー情報を取得する関数
func fetchUserInfo(userId: Int) -> UserInfo {
    // 仮のユーザー情報を返す
    return UserInfo(id: userId, name: "田中太郎", email: "tanaka@example.com")
}

let user = fetchUserInfo(userId: 1)
print(user.name) // 出力: 田中太郎

このコードでは、UserInfoという構造体を定義し、そのインスタンスを戻り値とするfetchUserInfo関数を作成しています。

これにより、ユーザー情報を簡潔にまとめて返すことができるようになりました。

○拡張機能を使用した戻り値のカスタマイズ

Swiftの拡張機能は、既存のデータ型に新しい機能を追加することができます。

これを利用して、特定のデータ型の戻り値に関する便利なメソッドやプロパティを追加することができます。

例えば、Int型の値を円として扱い、税込み価格を計算するメソッドを追加してみましょう。

extension Int {
    // 10%の税込み価格を計算するメソッド
    func taxIncluded() -> Int {
        return self + self / 10
    }
}

let price = 100
let taxIncludedPrice = price.taxIncluded()
print(taxIncludedPrice) // 出力: 110

このコードでは、Int型にtaxIncludedという新しいメソッドを追加しています。

これにより、整数値を価格として扱い、その税込み価格を簡単に計算することができるようになりました。

まとめ

Swiftの戻り値は、プログラムの柔軟性と拡張性を高めるための重要な要素となります。

この記事を通して、基本的な使い方から応用例、カスタマイズ方法まで、多岐にわたる戻り値の取り扱い方を学ぶことができたかと思います。

特に、カスタム戻り値の定義方法や拡張機能を用いたカスタマイズ方法は、Swiftの強力な機能を活かすための鍵となる部分です。

これらの機能を適切に活用することで、より複雑な処理やデータの取り扱いも、簡潔で読みやすいコードに落とし込むことが可能となります。

Swiftにおける戻り値の使い方やカスタマイズ方法には、さらに多くの応用例やテクニックが存在します。

今回学んだ内容を基盤として、さらに深い理解を積み重ねていくことで、Swiftの魅力を最大限に引き出すプログラムの実装が可能となるでしょう。