Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Last active June 1, 2021 05:44
Show Gist options
  • Save KentarouKanno/65c8cd0aa58a4f7d07762a3f41c670f3 to your computer and use it in GitHub Desktop.
Save KentarouKanno/65c8cd0aa58a4f7d07762a3f41c670f3 to your computer and use it in GitHub Desktop.
Generics

Generics

★ 基本的な使い方

func repeatItem<ItemType>(item: ItemType,_ times: Int) -> [ItemType] {
    var result: [ItemType] = []
    for _ in 0..<times {
        result += [item]
    }
    return result
}

// ItemTypeがStirngの場合
repeatItem("knock", 4)
//=> ["knock", "knock", "knock", "knock"]

// ItemTyoeがIntの場合
repeatItem(10, 4)
//=> [10, 10, 10, 10]

★ クラスとプロトコルの制約

class func sendMail<T: UIViewController where T: MFMailComposeViewControllerDelegate>(vc: T)  {

    // 引数のvcには UIViewControllerクラスでMFMailComposeViewControllerDelegateに準拠しているオブジェクトが渡されてくる
}

★ ある特定のクラス && 指定のプロトコルに準拠しているもののみ引数としてとる

 // プロトコル
protocol MyProtocol {

}

// クラス
class ViewController: UIViewController, MyProtocol {

}

// メソッド
func test<T>(viewController: T) where T: UIViewController, T: MyProtocol {

}

let vc = ViewController()

// ViewControllerがMyProtocolに準拠していないとエラー
test(viewController: vc)

★ 可変長引数を受けて、ジェネリック構造体の配列にして返す

struct Container<T> {
    var value: T
}

func factory<T>(_ value: T...) -> Array<Container<T>> {
    return value.map { Container<T>(value: $0) }
}

var a = factory("a", "b") /* [{value "a"}, {value "b"}] */
type(of: a) 
//=> Array<__lldb_expr_59.Container<String>>.Type

print(a)
//=> [__lldb_expr_56.Container<Swift.String>(value: "a"), __lldb_expr_56.Container<Swift.String>(value: "b")]

var b = factory(1, 2, 3) /* [{value 1}, {value 2}, {value 3}] */
type(of: b)
//=> Array<__lldb_expr_48.Container<Int>>.Type

print(b)
//=> [__lldb_expr_62.Container<Swift.Int>(value: 1), __lldb_expr_62.Container<Swift.Int>(value: 2), __lldb_expr_62.Container<Swift.Int>(value: 3)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment