Swift - Generic 泛型

2023-08-18  本文已影响0人  tom__zhu

Generic
编写适用于多种类型的代码,并为这些类型指定需求。
泛型是Swift最强大的特性之一,Swift标准库的大部分都是用泛型代码构建的。

作用对象:

  1. 方法入参/属性声明
  2. class/struct
  3. protocol
// Make Generic Type with Class
class Node<ElementType> {
    let value: ElementType
    var next: Node?
    init(value: ElementType, next: Node?) {
        self.value = value
        self.next = next
    }
}
// Make Generic Type with function
extension Node {
    func getValue() -> ElementType {
        return self.value
    }
    
    @discardableResult
    func description() -> [ElementType] {
        var results: [ElementType] = []
        var head: Node? = self
        while let currentNode = head {
            results.append(currentNode.value)
            head = currentNode.next
            print(currentNode.value)
        }
        return results
    }
}
// Make Generic Type with Protocol
protocol Mathmatic {
    // Generic with associatedtype in Protocol
    associatedtype ElementType
    func sum(lhs: ElementType, rhs: ElementType) -> ElementType
}

class IndexClass: Mathmatic {
    // Generic with typealias in class
    typealias ElementType = Int
    func sum(lhs: Int, rhs: Int) -> Int {
        return lhs + rhs
    }
}

class MoneyClass: Mathmatic {
    // Generic with typealias in class
    typealias ElementType = Double
    func sum(lhs: Double, rhs: Double) -> Double {
        return lhs + rhs
    }
}

Generic 约束

  1. Inherit
  2. where

Inherit

protocol Mathmatic {
    // Generic with associatedtype in Protocol
    associatedtype ElementType: Numeric
    func sum(lhs: ElementType, rhs: ElementType) -> ElementType
}

where

protocol Mathmatic {
    // Generic with associatedtype in Protocol
    associatedtype ElementType
    func sum(lhs: ElementType, rhs: ElementType) -> ElementType
}

// Only add typeCheck for StringProtocol
extension Mathmatic where ElementType: StringProtocol {
    func typeCheck() {
        print("Error with string type")
    }
}

class MoneyClass: Mathmatic {
    // Generic with typealias in class
    typealias ElementType = Double
    func sum(lhs: Double, rhs: Double) -> Double {
        self.typeCheck() // Build Error: "Referencing instance method 'typeCheck()' on 'Mathmatic' requires that 'MoneyClass.ElementType' (aka 'Double') conform to 'StringProtocol'"
        return lhs + rhs
    }
}

class NameClass: Mathmatic {
    typealias ElementType = String
    func sum(lhs: String, rhs: String) -> String {
        self.typeCheck()  // Build Success
        return lhs + rhs
    }
}

https://medium.com/globant/swift-generics-and-associated-types-73aa2b184c7a#:~:text=Swift%20Generics%20and%20Associated%20Types%201%20Generics%20syntax,generally%20start%20implementation%20by%20adding%20protocols%20first.%20

上一篇 下一篇

猜你喜欢

热点阅读