Generics in Swift explained with code examples – onlinecode

Generics in Swift explained with code examples – onlinecode

In this post we will give you information about Generics in Swift explained with code examples – onlinecode. Hear we will give you detail about Generics in Swift explained with code examples – onlinecodeAnd how to use it also give you demo for it if it is necessary.

Generics in Swift allows you to write generic and reusable code, avoiding duplication. A generic type or function creates constraints for the current scope, requiring input values to conform to these requirements.

You’ve probably been using generic implementations already since they’re all over the place in the Swift standard library. Though, using them in your implementation might still be scary since generics can look complex and hard to write. Writing generic code requires a certain mindset to generalize functions to make them reusable. I encourage you to read my articles covering opaque types and existentials as well, as you’ll likely use them alongside generics.

Architecting SwiftUI apps with MVC and MVVMAlthough you can create an app simply by throwing some code together, without best practices and a robust architecture, you’ll soon end up with unmanageable spaghetti code. Learn how to create solid and maintainable apps with fewer bugs using this free guide.

How to use generics in Swift

You can write generics in Swift to make existing code more reusable. A classic example is the one using a stack of elements, better known as an array in Swift:

struct IntStack {
    var items: [Int] = []

    mutating func push(_ item: Int) {
        items.append(item)
    }

    mutating func pop() -> Int {
        return items.removeLast()
    }
}

In this example, we’ve created a stack of integers. We can push and pop elements, but they all have to conform to integers. A stack with support for integers only might be good at first for you to keep around in your project. However, we’ll start duplicating code as soon as we need a stack of strings:

struct StringStack {
    var items: [String] = []

    mutating func push(_ item: String) {
        items.append(item)
    }

    mutating func pop() -> String {
        return items.removeLast()
    }
}

Both IntStack and StringStack have similar code implementations, resulting in code duplication and multiple types to maintain. Indicating duplicate code can be a great moment to consider rewriting your logic by making use of generics:

struct Stack<Element> {
    var items: [Element] = []

    mutating func push(_ item: Element) {
        items.append(item)
    }

    mutating func pop() -> Element {
        return items.removeLast()
    }
}

We’ve now created a generic Stack by defining a generic Element. The array of items uses the generic element, resulting in the same type constraint for both push and pop methods.

Creating generic methods

The above stack examples make use of generics on the type level. We can use generics within methods as well, like in the following print example:

func printElement<T: CustomStringConvertible>(_ element: T) {
    print(element)
}

Note that we introduced the concept of constraints in this example. An element passed into the print method must conform to the CustomStringConvertible protocol, allowing us to convert the element to a string before printing.

You can also write the above method using a where clause:

func printElement<T>(_ element: T) where T: CustomStringConvertible {
    print(element)
}

Deciding between using a where clause or not is a matter of taste since the outcome of generics and constraints will be the same.

Opaque types as a shorthand for generics

You can use opaque types instead of generics whenever you’re using generics in a single place. The above print method uses the generic T only within the method definition, and you can therefore rewrite it as follows:

func printElement(_ element: some CustomStringConvertible) {
    print(element.description)
}

You can read more about opaque types in my article Some keyword in Swift: Opaque types explained with code examples.

Using generic return types

You can also use generics as return types. For example, we could create a method to convert any element into an array:

func convertToArray<T>(_ element: T) -> [T] {
    return [element]
}

let name = "Antoine"
let arrayOfNames = convertToArray(name)

While this example is useless since you can create such an array directly, it nicely demonstrates the concept of returning a generic type.

Creating protocol extensions using constraints

Protocol extensions allow you to set up constraints using the associated type. For example, we can create an extension for an array of strings as follows:

extension Array where Element == String {
    func uppercaseAll() -> [Element] {
        map { $0.uppercased() }
    }
}

["Bernie", "Jaap", "Lady"].uppercaseAll() // Will be: ["BERNIE", "JAAP", "LADY"]

When should I use generics?

While generics allow you to write reusable code, it’s important to point out that it shouldn’t be your goal to write generics. You should always start with strongly typed classes and functions and only opt-in to generics if you know you need the flexibility provided by generic code.

Generics make your code more complex to maintain with the returned benefit of reusable code and less duplication. There is a tradeoff for you to make, which might be easier to accept based on your experience with generics. If you’re just getting started with Swift, I would like you to know that it’s okay if you start with writing less efficient, duplicated code.

My approach to determining whether generics are needed comes down to finding code used in multiple places and making that reusable in a single place. The outcome is a single piece of code to maintain and less duplication.

Moving code instead of using generics

Whenever you find yourself duplicating the same piece of code, it’s time to think about a way to make it reusable from multiple places. Doing so doesn’t always mean you’ll have to write generics as you might be able to move code first. Take the following example:

struct Person {
    let name: String
}

var people = [
    Person(name: "Antoine"),
    Person(name: "Jordi"),
    Person(name: "Bas")
]

func longestName() -> String {
    return people
        .sorted(by: { $0.name.count > $1.name.count })
        .first!
        .name
}

func shortestName() -> String {
    return people
        .sorted(by: { $0.name.count > $1.name.count })
        .last!
        .name
}

print(longestName()) // Prints: Antoine
print(shortestName()) // Prints: Bas

Both methods use the same sorting logic and only differ by selecting the first or last element. We could rewrite this using a generic method as follows:

extension Collection where Element == String {
    func sortedByLength() -> [Element] {
        sorted(by: { $0.count > $1.count })
    }
}

func longestName() -> String {
    return people
        .map(.name)
        .sortedByLength()
        .first!
}

func shortestName() -> String {
    return people
        .map(.name)
        .sortedByLength()
        .last!
}

We now have the benefit of being able to reuse the sortedByLength method on all arrays of strings. However, it might be easier at first to create a reusable method first:

var peopleSortedByNameLength: [Person] {
    people.sorted(by: { $0.name.count > $1.name.count })
}

func longestName() -> String {
    return peopleSortedByNameLength
        .first!
        .name
}

func shortestName() -> String {
    return peopleSortedByNameLength
        .last!
        .name
}

In other words, consider whether you need the complexity of generics and only opt-in when you know you’ll benefit from the code reusability. If you feel comfortable enough to write generics, it will be a better solution since you’ll prepare your code for future cases in which you might need the reusable functionality. However, avoiding generics is okay if you’re not too familiar with them yet.

Architecting SwiftUI apps with MVC and MVVMAlthough you can create an app simply by throwing some code together, without best practices and a robust architecture, you’ll soon end up with unmanageable spaghetti code. Learn how to create solid and maintainable apps with fewer bugs using this free guide.

Conclusion

Generics allow you to prevent code duplicating by creating reusable code. Writing generic code should not be a goal on its own, and you should feel fine staying away from them if you’re uncomfortable writing them. Though, generics allow you to create sustainable code and prepare for future cases in which you need to reuse the same piece of code.

If you like to improve your Swift knowledge, check out the Swift category page. Feel free to contact me or tweet me on Twitter if you have any additional tips or feedback.

Thanks!

<!– Disable cross link to Medium



Also published on Medium.

–>

 

Hope this code and post will helped you for implement Generics in Swift explained with code examples – onlinecode. if you need any help or any feedback give it in comment section or you have good idea about this post you can give it comment section. Your comment will help us for help you more and improve us. we will give you this type of more interesting post in featured also so, For more interesting post and code Keep reading our blogs

For More Info See :: laravel And github

We're accepting well-written guest posts and this is a great opportunity to collaborate : Contact US