★ 基本的な使い方
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)]