📝

[Swift] オーバーロード選択クイズ10問

2024/04/16に公開

はじめに

Swiftには関数のオーバーロード機能があります。
ある呼び出しについて、有効なオーバーロードが複数ある場合、どのオーバーロードが選択されるかはコンパイラの型推論器に定められたルールによって決まっています。
以下の10個のプログラムにおいて、それぞれどの関数が選択される(もしくは、何が出力される)でしょうか?

正解とする環境

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0

実行コマンド

swift Source.swift

-enable-upcoming-featureなし

第1問

func f(_ a: Int?) { print("Int?") }
func f(_ a: Any) { print("Any") }

let a: Int = 1
f(a)
答え

Any

第2問

struct A: Hashable {}

func f(_ a: Any) { print("Any") }
func f(_ a: AnyHashable) { print("AnyHashable") }
let a: A = A()
f(a)
答え

Any

第3問

func a(_ b: Int) {}
var a = 0

func f(_ a: (Int) -> Void) { 
    print("func") 
}
func f(_ a: Int) { 
    print("var")
}
f(a)
答え

var

第4問

func f(_ a: [Int]?) { print("[Int]?") }
func f(_ a: [Int?]) { print("[Int?]") }

let a: [Int] = [1, 2, 3]
f(a)
答え

[Int]?

第5問

import Foundation

func f(_ a: CGFloat) { print("CGFloat") }
func f(_ a: Double?) { print("Double?") }

let a: Double = 10.0
f(a)
答え

Double?

第6問

func f(_ a: UnsafePointer<Int>) { print("UnsafePointer<Int>") }
func f(_ a: [Int]?) { print("[Int]?") }

let a: [Int] = [1, 2, 3]
f(a)
答え

UnsafePointer<Int>

第7問

func f(_ a: Int) { print("Int") }
func f(_ a: Int?) { print("Int?") }

var a: Int! = 1
f(a)
答え

Int?

第8問

func f(
    _ a: (() -> Void)? = nil,
    _ b: (() -> Void)? = nil
) {
    if a != nil { print("forward") }
    if b != nil { print("backward") }
}

f { }
答え

backward

Swift 6.0もしくは-enable-upcoming-feature ForwardTrailingClosures
forward

第9問

func h(_ a: () async -> Void) {
    print("async")
}
func h(_ a: () -> Void) {
    print("sync")
}
h { }
答え

sync

第10問

func f() { print("sync") }
@_disfavoredOverload
func f() async { print("async") }

func g() async {
    f()
}
await g()
答え

func f() asyncが選択される (awaitがないのでコンパイルエラー)

おまけ

func h(_ a: () async -> Void) async {
    print("async")
}
func h(_ a: () -> Void) {
    print("sync")
}
func g() async {
    await h { }
}
await g()
答え

sync

バグではないのですが、奇妙で直感に反する挙動だと感じたのでおまけにしました。
forumでも聞いてみました

最後に

何問正解できましたか?

オーバーロード選択のルールについて詳しくは以下の記事を参照

https://zenn.dev/kntk/articles/5b758d29b5c49d

Discussion