Spazure Stoneheart
SpazureScript

SpazureScript

Today's work was surprisingly easy

Today's work was surprisingly easy

(especially considering Optionals are still kicking my ass) #100DaysOfSwift Day 55

Spazure Stoneheart's photo
Spazure Stoneheart

Published on Oct 6, 2021

4 min read

Today, we started work on a "Whack-a-Penguin" game that's basically "Whack-a-mole" without copyright infringement. I then added a Diglett from Pokémon, which puts us right back IN to copyright infringement territory -- but since I can't share any apps I write anyway, no harm done.

It's not quite a game yet, it's more "watch a mole" at the moment, but we're getting there.

Screen Shot 2021-10-06 at 1.38.22 PM.png

Last night was challenging for me because I did some review on some basics I still occasionally struggle with. Specifically: Optionals, typecasting, and nil coalescence. A lot of the trouble I'm having at the moment is that while I can see quiz questions I'm getting wrong, I don't understand the WHY of something being wrong. I think Paul is an excellent teacher and I have learned a lot from him, but on this one particular topic, I think I need to find an alternate information source.

For example:

var score: Int?

score += 1

Cannot be done. They're both int, but because one's an optional int, Swift is like "Sorry, i don't know how to add two numbers together!"

So you have to do something like:

if let unwrappedScore = score {
    var thirdFuckingVariableBecauseIfLetMakesAConstant = unwrappedScore
    thirdFuckingVariableBecauseIfLetMakesAConstant += 1
    score = thirdFuckingVariableBecauseIfLetMakesAConstant
}

.. which is messy AF because now you have two different variable names for the same number. I absolutely hate this code and desperately wish I knew a way around it. There HAS to be a way around it because there is no way that people are making three variables every time they want to do math with an optional Int.

And of course if you try to use score again anywhere, you then have to unwrap it AGAIN .. but of course you can't access the variable you just used to do that because it's stuck inside a function, unless you declare the various steps of the unwrapping ahead of time like:

var scoreFirstVariable: Int?
var thirdFuckingVariableBecauseIfLetMakesAConstant: Int = 0

scoreFirstVariable = 1

func screwOptionals() -> Int {
    if let unwrappedScoreSecondVariable = scoreFirstVariable {
        thirdFuckingVariableBecauseIfLetMakesAConstant = unwrappedScoreSecondVariable
        thirdFuckingVariableBecauseIfLetMakesAConstant += 1

    }
    return thirdFuckingVariableBecauseIfLetMakesAConstant
}

let message = screwOptionals()

print(message)

And yes, the only way I have found to work with Optionals at all is to unwrap them inside a function and then start using the third variable. (And yes I'm aware the second one is actually a constant and not a variable. That's not even my point here. Please don't come @ me on this.)

Now I know what you may be thinking: "Oh, you can just not make the first variable an optional, and skip all of this!"

Oh how nice that would be. In this super dumbed down example, sure -- but if you're pulling info from a third-party API, there's always the chance that data you're looking for isn't there --- so Optionals become a necessary evil.

But honestly??? This is as far as I even understand optionals. There's other stuff involved like typecasting and nil coalescence that I can't even begin to explain here other than there's more question marks and xcode screaming at me and...

So yeah, I definitely have more studying and learning to do. For now though? I hate optionals. They're harder for me even than closures were.

All I know at the moment is that there's a better way to write the above code, and I will find it if it's the last thing I do. If I were a betting man, I'd say the trick involves nil coalescence, optional chaining, and/or typecasting. All of the things I'm struggling with (that aren't autolayout -- don't get me started) -- are related specifically to Optionals.

Alright, let me hit up the documentation and..

To safely access the properties and methods of a wrapped instance, use the postfix optional chaining operator (postfix ?). The following example uses optional chaining to access the hasSuffix(_:) method on a String? instance.

.... FML. Fine. More googling for someone to break this down so even a noob like me can figure it out. I'm frustrated, I'm angry (mostly at myself), but I am not giving up.

 
Share this