Write an extension function for abstract type aggregates [2nd]
Swift itself is a statically typed language
Generic code enables functions and types that can work with different types
In general, a function is usually a piece of codes to be reusable and used to perform a single related action; therefore, an ordinary form of a function is common as follows:
func function_name(parameters: declared_type) -> return_type { //... Code here return typed_constants }
Traditionally, we could create functions for the same purpose individually to work with different types. However, it means that we produce codes based on similar patterns for each unique type declaration. And it somehow violates coding in a clean way and maintenance-free which is always a goal and principle to programmers. In view of that, we want a manner which is abstracted and able to expresses its intention in a clear form. And that's what we called Generic.
Let's start from a generic entity that can be reused with different types
A generic entity must have a type parameter. The "T" below stands for whatever type will eventually be used in the generic entity.
struct GenericStruct<T> { var someThing: T } // After above manner, GenericStruct can be constructed and parameterized over different types by adding type parameters in a pair of angle-brackets. let a = GenericStruct<Int>(someThing: 1) let b = GenericStruct<Float>(someThing: 2.5) let c = GenericStruct<String>(someThing: "Hello, world!")
Then, what if we put a generic entity in a collection?
It looks like that defining a generic entity is easy and straightforward. However, the story will not that simple always. If we do want to put our generic entity in a collection type, like Set, we need to have some more decoration and adopt Hashable protocol for that purpose. The snippet below is a revised version.
struct GenericStruct<T: Hashable>: Hashable { var someThing: T var hashValue: Int { get { // Hashable in angle-brackets is a constraint to tell compiler that type T must have .hashValue return someThing.hashValue } } static func ==(lhs: GenericStruct, rhs: GenericStruct) -> Bool { return lhs.hashValue == rhs.hashValue } } let set: Set = [ GenericStruct<String>(someThing: "Watermelon"), GenericStruct<String>(someThing: "Orange"), GenericStruct<String>(someThing: "Banana") ]
Extension function is the last thing that can't be missed
Back to our topic, the purpose is to write an extension function for abstract type aggregates. There is no doubt that the story is not finished yet. The last piece of having an extension function is still missing. We need a third revision of the snippet to have our extension function work with GenericStruct.
extension Set { func getFirstWith<T: Hashable>(value: T) -> Element? { return filter({$0.hashValue == value.hashValue}).first } } let set: Set = [ GenericStruct<String>(someThing: "Watermelon"), GenericStruct<String>(someThing: "Orange"), GenericStruct<String>(someThing: "Banana") ] let output = set.getFirstWith(value: "Orange") print(output!)
Certainly, another type like Int works too. Cheers!
let set: Set = [ GenericStruct<Int>(someThing: 226), GenericStruct<Int>(someThing: 603), GenericStruct<Int>(someThing: 818) ] let output = set.getFirstWith(value: 818) print(output!)












