Leave a rating/review
We’ve now reduced our points(sliderValue:) method to just a few lines of code.
But good news - there’s a way to reduce the code by a few more characters, thanks to an amazingly handy feature of Swift called type inference.
Let’s take a look at this line of code right here, where we’re calculating the difference.
So we say we’re creating a constant called difference, and we’re setting it to the absolute value of target minus slider value.
Well, it turns out that Swift is pretty smart.
Swift knows that target is an integer. We’ve said it is up here when we declare the property.
It also knows sliderValue is an integer because we’ve said it will be up here where we define the parameter.
And it knows that this absolute value function takes an integer and returns an integer.
So, Swift knows all of the values involved here are integers, and it can figure out for you that if you’re setting difference equal to the resulting value, it’s also going to be an integer.
Because of that, you don’t actually need to specify in this case, that difference is an integer. I can actually delete that…
let difference = abs(target - sliderValue)
And the code still works, when I hit Command B, it builds and we don’t have any issues.
And I can verify that Swift knows this is an Int by holding down the option key, and clicking on “difference”
And right here, it says differences is an Int.
This has been figured out automatically for us by the Swift compiler because we’re setting it to an expression that evaluates to an Int.
We can do this a lot of places in our code, to make it a lot shorter and concise and easier to read and that’s actually a best practice in Swift development to not specify the type if you don’t have to.
So I’m going to go ahead and delete it for “awardedPoints” also, because again, it can calculate the a hundred, which is an integer minus difference, which is an integer, it’s also an integer.
let awardedPoints = 100 - difference
I can also option-click on that to verify it.
Up here at the top of the file, target is clearly going to be an Int because we’re calling this random method on Int to get one, so you can delete the type from there.
var target = Int.random(in: 1...100)
There’s another common case where Swift can infer a type. And that’s when we used something called a “literal”.
Score and round are both set to Integer literals. Anytime you type a number without a decimal, and there’s nothing else saying it’s some other type, Swift will assume you mean it should be an Int.
And since we’re setting these initial values with a 0 and 1, we don’t need to specify the Int there either.
var score = 0
var round = 1
I can option-click to verify all of those.
ContentView.swift
Let’s go to ContentView.swift, and we can clean up some of these as well.
We’re setting this to false, which is one of two possible values of a boolean.
So I don’t need to say that it’s a boolean.
@State private var alertIsVisible = false
This 50.0 is a Double literal. When you include a decimal in number, Swift assumes you mean a Double.
I’ll go ahead and delete that.
@State private var sliderValue = 50.0
What about game? Well, we’re setting this to an instance of Game, so we don’t need to say that it’s a game again. So, delete that one too!
@State private var game = Game()
And there’s another case that we’ve done this down here. Here we’re saying roundedValue is an Int, but we don’t need to do that. We’re already saying it when we create the Int here.
let roundedValue = Int(sliderValue.rounded())
All right, so our code is already looking a lot more concise, thanks to Swift type inference, but I wanna show you how we can reduce our point method even more.
So, back in Game.swift, we can truly get this down to just one line.
So we have a couple of constants here in a row, but we can simplify this. So instead of making a constant for awarded points and returning awarded points, we can just directly say return one hundred minus the difference.
return 100 - difference
But we don’t even really need the difference constant. We just say return hundred minus the result of this absolute value function. Just copy and paste the code down there.
return 100 - abs(target - sliderValue)
And there’s actually one more way that we can simplify this. If you have a method that just has a single line of code in it, you don’t actually need to put the return beforehand.
We’ve said the method returns a value, so Swift will assume since a value has to be returned from this method, and you’ve got code here evaluating to the right type, it should just return the result of this line of code. So, I can remove the return as well.
100 - abs(target - sliderValue)
And now you can see that this has become extremely short.
I’ve come a long way from that long if else statement to this nice little line of code. It’s looking really good.
So let me run my tests with Command + U, all looking good. Everything is still working!
And if you’d like, you’re welcome to run this in the simulator to try it out manually yourself with Command-R.
I’ll do my best to match the target, tap hit me, and close the alert. Perfect!