Bob Lee Course Part 5 (lesson 8)

It's been a few days but I've managed to find a bit of time to code! Last time it was about type casting - changing the type of different values and knowing the hierarchy for up/down casting. Interesting stuff, especially as it linked in neatly to optionals and error handling. Today we are starting with 'generics'. Don't think I've ever seen these before so here we go!

Start Time - 20:24

Introduction to Generics

Code 'smell'. What does that mean? Well it is like something could be up. Universal issues include overusing var instead of let; complex or wordy code that is competitive. Interesting!

let gradeScores = [4.5, 3.2, 9.8, 4.4, 7.5, 8.6]

For this example, I could print out each element separately OR do a for-in loop. What's better? The for in loop obviously - much more elegant code!

func genericFunction<anything>(value: anything) {
    print(value)
}


So the above is an example of a generic function. 

func printElement<T>(array: [T]) {
    for element in array {
        print(element)
    }
}

printElement(array: gradeScores)

This is all logical but I'm not sure why 'T' was used. 

This is potentially very exciting - I've found before that I create a separate function for each time I want to do something e.g. on the 'F1 Fun Facts', I had a separate function for each array being used of facts. This would solve that issue surely! Having any array put in for the above example makes sense. 









struct Family {
    
    var members: [String] = []
    
    mutating func push(member: String) {
        members.append(member)
    }
}

Here is a good example of mutating - that if I want to CHANGE the value of one of the properties, then that func must have the mutating keyword. 

OK good example. If the name actually were an int that needed numbers, I would need to have a NEW struct, which would have to change the String bit to Int...NEEDLESS COMPLEXITY and NOT GENERIC enough!!!!

struct Family<T> {
    
    var members: [T] = []
    
    mutating func push(member: T) {
        members.append(member)
    }
}

Some bits I am trying out!


var newFam = Family<Any>()

newFam.push(member: 1345)

let newMember = newFam.members

print(newMember)

var genericFamInt = Family<Int>()


genericFamInt.push(member: 45)



AH ok - so if you specify 'Any' in the creation of an object, then you are not declaring the type. In the latter example, I've specified Int so I HAVE to use them.

I know why to use 'T' as 'T' means 'Type'!

extension Family {
    
    var firstElement: T? {
    
    if members.isEmpty {
    return nil
    } else {
    return members[0]
        }
    }
}
















This is getting pretty complex now. Not going to pretend to understand the syntax!

Finish Time - 21:00 (36 minutes total)

Well there we go - that's generics! I've never used the < > with putting a custom type in. It makes sense to create something that can then be adapted rather than lots of different functions, which are really tricky to keep track of. So before moving on to the next lesson, I'm going to do a little consolidation of all of Bob's concepts so far. Will be worth doing!


Comments

Popular posts from this blog

*Xcode Project Entry 2* F1 Quiz - part 1

Angela Yu Course Part 10 (up to lesson 112)

Angela Yu Xcode 12 Course - Part 7 (lectures 74 to 79)