はじめに
デフォルトパラメータ値を使うと、呼び出し側は必要のない引数を省略できます。可変長パラメータは、任意の数の引数を受け取ります。どちらも定型コードを減らし、APIを使いやすくします。
デフォルトパラメータ値
```swift
func log(_ message: String, level: String = "INFO") {
print("[\(level)] \(message)")
}
log("Server started") // [INFO] Server started
log("Disk full", level: "ERROR") // [ERROR] Disk full
```
デフォルト値は、必須パラメータの後に配置する必要があります。
複数のデフォルト値
```swift
func connect(host: String, port: Int = 443, useTLS: Bool = true) {}
connect(host: "api.example.com")
connect(host: "api.example.com", port: 8080)
connect(host: "api.example.com", port: 80, useTLS: false)
```
呼び出し側では、デフォルト値が設定されたパラメータのうち、任意のものだけを上書きできます。
可変長パラメータ
可変長パラメータは、同じ型の値を0個以上受け取ります:
```swift
func sum(_ numbers: Int...) -> Int {
numbers.reduce(0, +)
}
print(sum(1, 2, 3)) // 6
print(sum(10, 20, 30, 40)) // 100
```
関数内では、`numbers`は`[Int]`配列になります。
1つの関数につき可変長パラメータは1つだけ
Swiftでは、1つの関数につき可変長パラメータを1つだけ使用できます(Swift 5.4以降は最後のパラメータでなくても構いません):
```swift
func format(_ template: String, args: String...) -> String {
var result = template
for arg in args { result = result.replacingOccurrences(of: "%s", with: arg) }
return result
}
```
デフォルト値と可変長パラメータの組み合わせ
```swift
func build(separator: String = ", ", _ items: String...) -> String {
items.joined(separator: separator)
}
build("apple", "banana", "cherry") // "apple, banana, cherry"
build(separator: " | ", "one", "two", "three") // "one | two | three"
```
配列を可変長パラメータに渡す
配列を可変長パラメータに直接渡すことはできません:
```swift
let nums = [1, 2, 3]
// sum(nums) ❌ — won't compile
```
`...`で展開します(Swift 5.4以降でもシーケンスの展開は組み込みでサポートされていないため、自分でreduceなどを使って展開します):
```swift
let total = nums.reduce(0, +)
```
デフォルトのクロージャ
クロージャパラメータにもデフォルト値を設定できます:
```swift
func retry(count: Int = 3, action: () -> Bool) {}
retry { fetchData() } // count defaults to 3
retry(count: 5) { fetchData() }
```
デフォルト値を使う場合でも、末尾クロージャ構文を使用できます。
デフォルト値のドキュメント化
呼び出し側が想定すべき内容を把握できるよう、デフォルト値を明確にコメントするか、名前で示します:
```swift
/// Sends a request. Timeout defaults to 30 seconds.
func send(request: URLRequest, timeout: TimeInterval = 30.0) {}
```
適切なドキュメントがあれば、呼び出し側がデフォルト値を明示的に指定する必要はありません。
実践的なパターン:printのようなAPI
Swiftの標準`print`自体が、デフォルト値を持つ可変長関数です:
```swift
// Simplified signature:
func print(_ items: Any..., separator: String = " ", terminator: String = "\n")
print("a", "b", "c") // a b c
print("x", "y", separator: "-") // x-y
print("no newline", terminator: "")
```
確認問題
関数内では、可変長の`Int...`パラメータはどの型になりますか?
まとめ
重要なポイント:
• デフォルト値により、呼び出し側ではパラメータを省略できる
• デフォルト値は必須パラメータの後に置く必要がある
• 可変長パラメータ(`Type...`)は0個以上の値を受け取り、関数内では配列になる
• 1つの関数につき可変長パラメータは1つだけ
• 両方を組み合わせると、柔軟で簡潔なAPIを作れる
次は、inoutパラメータと複数の値の返却について学びます。