-1

I've just started with Swift and am learning the basics. I've been playing around with Playgrounds and have come across an error whilst testing some code.

 //creating a Struct for humans
struct Human {
    var firstName: String? = nil
    var surName: String? = nil
    var age: Int? = nil
    var height: Int? = nil
}

var personA = Human()
personA.firstName = "Jake"
personA.surName = "-"
personA.age = 26
personA.height = 185

print (personA)

if (personA.age == 30) {
    print("You're 30 years old")
} else {
    print("You're not 30")
}


var personB = Human()
personB.firstName = "Andy"
personB.surName = "-"
personB.age = 24
personB.height = 180

print (personB)

if (personA.height > personB.height) { //error here
    print("Person A is taller, he is \(personA.height ?? 1)cms tall")
} else {
    print("not true")
}

Could anybody explain why I'm receiving the error in simple terms?

Jake Raven
  • 1
  • 1
  • 3
  • 2
    Also, just a side note. In Swift you don’t generally put parentheses after the if. – Fogmeister Oct 31 '18 at 14:35
  • 4
    Why are all struct members optional?. In reality I don’t know any human ageless and height-less. Declaring the members non-optional solves your problem. – vadian Oct 31 '18 at 14:40
  • See https://stackoverflow.com/a/44808567/3141234 – Alexander Oct 31 '18 at 15:33
  • In simple terms: It's not obvious how `nil` should compare to other numbers. In a sorted list, should `nil` come first (implying `nil` is less than any negative `Int`). Should it come after the negatives but before 0? after the 0 but before the positives? After all the positives? There are circumstances in which each of these variants might make sense, so they don't pick and force one for you. They let you decide how you want to handle `nil`. – Alexander Oct 31 '18 at 15:42

1 Answers1

4

The optional parameter Int? is actually enum

You have to unwrap the height in order to compare.

e.g.

if (personA.height ?? 0 > personB.height ?? 0 ) { //error here
    print("Person A is taller, he is \(personA.height ?? 1)cms tall")
} else {
    print("not true")
}

or, better,

guard let heightA = personA.height, let heightB = personB.height else {
print("Some paremter is nil")
return
}
if (heightA > heightB) { //error here
    print("Person A is taller, he is \(heightA ?? 1)cms tall")
} else {
    print("not true")
}
Vyacheslav
  • 26,359
  • 19
  • 112
  • 194
  • Your first code snippet provides only partial order over heights. If we call the heights `a` and `b`, then `a < b` is false for both `(a: 0, b: nil)`, and `(a: nil, b: 0)`. Among other things, it means that if you were to sort an array according to that, you would have all the negative numbers come first, then some indeterminate mix of `0` and `nil`, and then all the positive numbers. Probably not what you expected. For a better solution, see https://stackoverflow.com/a/44808567/3141234 – Alexander Oct 31 '18 at 15:37