Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Last active May 3, 2018 05:44
Show Gist options
  • Save KentarouKanno/dc3da39bb704a53e95b1e8dae1e8de0e to your computer and use it in GitHub Desktop.
Save KentarouKanno/dc3da39bb704a53e95b1e8dae1e8de0e to your computer and use it in GitHub Desktop.

Generic Types - Struct

// 1. struct - Generics
struct S1<T> {}
let s1_1 = S1<Int>()    /* S<Int> */
let s1_2 = S1<String>() /* S<String> */

// 型パラメーターが変数で決まる場合、型推論できる
struct _S1<T> {
    var t: T
}
let _s1_1 = _S1(t: 5)  /* _S1<Int> */
let _s1_2 = _S1(t: "a")/* _S1<String> */

// GenericsにExtensionでメソッドを追加
extension _S1 {
    // 型パラメーターを使用可能
    func value() -> T {
        return t
    }
}
let value1 = _s1_1.value() /* 5 */
let value2 = _s1_2.value() /* "a" */

protocol S1_Protocol1 {
    associatedtype T
    func getValue() -> T
}

// GenericsにProtocolを適用
extension _S1: S1_Protocol1 {
    // Protocolのassociatedtypeに型パラメーターを指定
    func getValue() -> T {
        return t
    }
}

let getValue1 = _s1_1.getValue() /* 5 */
let getValue2 = _s1_2.getValue() /* "a" */


// 2. struct - Generics - protocol
struct S2<T: Equatable> {}
let s2_1 = S2<Int>()    /* S2<Int> */
let s2_2 = S2<String>() /* S2<String> */

struct _S2<T: Equatable> {
    var t: T
}
let _s2_1 = _S2(t: 5)  /* _S2<Int> */
let _s2_2 = _S2(t: "a")/* _S2<String> */

protocol S2_Protocol1 {
    // associatedtypeも同じく'Equatable'に準拠
    associatedtype T: Equatable
    func isEqual(value: T) -> Bool
}

// GenericsにProtocolを適用
extension _S2: S2_Protocol1 {
    func isEqual(value: T) -> Bool {
        // 比較可能
        return t == value
    }
}

let b1 = _s2_1.isEqual(value: 4) /* false */
let b2 = _s2_1.isEqual(value: 5) /* true */


/* --- Example --- */

// Protocol
protocol ExampleProtocol {
    associatedtype T
    func getValue() -> T
}

// Non Generics - Protocol
struct NonGenerics: ExampleProtocol {
    var val: Int
    func getValue() -> Int {
        return val
    }
}

let nonGenerics = NonGenerics(val: 5)
let val = nonGenerics.getValue() /* 5 */

// Generics - Protocol
struct Generics<T>: ExampleProtocol {
    var val: T
    func getValue() -> T {
        return val
    }
}

// Int
let intGenerics = Generics(val: 5)
let val1 = intGenerics.getValue()    /* 5 */

// String
let stringGenerics = Generics(val: "a")
let val2 = stringGenerics.getValue() /* "a" */


// 3. struct - Generics - protocol(Multiple)
struct S3<T: Equatable & Comparable & Hashable> {}
let s3_1 = S3<Int>()    /* S3<Int> */
let s3_2 = S3<String>() /* S3<String> */

struct _S3<T: Equatable & Comparable & Hashable> {
    var t: T
}
let _s3_1 = _S3(t: 5)  /* _S3<Int> */
let _s3_2 = _S3(t: "a")/* _S3<String> */

// 4. struct - Generics(Multiple)
struct S4<T, U> {}
let s4_1 = S4<Int, String>() /* S4<Int, String> */
let s4_2 = S4<String, Int>() /* S4<String, Int> */

struct _S4<T, U> {
    var t: T
    var u: U
}

let _s4_1 = _S4(t: 5, u: "a") /* _S4<Int, String> */
let _s4_2 = _S4(t: "a", u: 5) /* _S4<String, Int> */

// 5. struct - Generics(Multiple) - protocol(Multiple)
struct S5<T: Equatable, U: Comparable & Hashable> {}

let s5_1 = S5<Int, String>() /* S5<Int, String> */
let s5_2 = S5<String, Int>() /* S5<String, Int> */

struct _S5<T: Equatable, U: Comparable & Hashable> {
    var t: T
    var u: U
}
let _s5_1 = _S5(t: 5, u: "a") /* _S5<Int, String> */
let _s5_2 = _S5(t: "a", u: 5) /* _S5<String, Int> */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment