Left side of nil coalescing operator '??'

2019-03-05 20:54发布

问题:

i've converted a line from swift 1.2 to swift 4 but it still gives warning suggestion. if i remove that warning it was deleting one value in the addition. Can someone suggest am i doing anything wrong conversion to swift 4

Swift 1.2-----> let sumEmailRemoved = account.numMessageArchived.integerValue ?? 0 + account.numMessageDeleted.integerValue ?? 0

Swift 4------> let sumEmailRemoved = account.numMessageArchived.intValue ?? 0 + account.numMessageDeleted.intValue ?? 0

I'm trying to convert a method from swift 1.2 to swift 4 but it was nat satisfying the real requirement. can somebody please convert correctly or give your valuable suggestion to make me perfect.

Swift 1.2 code below---->

func checkShouldAllow() -> Bool {
    let productPurchased = NSUserDefaults.standardUserDefaults().boolForKey(kFullVersionProductId)
    if productPurchased { return true }
    if let account = account {
        let sumEmailRemoved = account.numMessageArchived.integerValue ?? 0 + account.numMessageDeleted.integerValue ?? 0
        if sumEmailRemoved > numCap {
            return false
        }
    }
    let numContactsRemoved = NSUserDefaults.standardUserDefaults().integerForKey(kNumContactsRemoved)
    println(numContactsRemoved)
    return numContactsRemoved < numContactsCap
}

Need Swift 4 Code ---->

回答1:

As you could deduce from the error message, one (but I guess both) of the account.numMessageArchived.intValue and account.numMessageDeleted.intValue are now non-optional, therefore the ?? is redundant. Try:

let sumEmailRemoved = account.numMessageArchived.intValue + account.numMessageDeleted.intValue


回答2:

It's about the precedence and associativity of operators.

Precedence = order of operation. E.g., * is higher than +, so it's evaluated first:

1 + 2 * 3 
= 1 + (2 * 3) 
= 7

Associativity = left or right group first. E.g., + is left associative, so it's evaluated from the left group:

1 + 2 + 3
= ((1 + 2) + 3)
= 6

Getting back to your question. First, let's simplify the code:

var num1: Int? = 0
var num2: Int = 0 // I believe this is non-optional, or else compiler will give another error.

let result = num1 ?? 0 + num2 ?? 0

Now surprisingly, + has higher precedence than ?? operator. So it's done first:

num1 ?? (0 + num2) ?? 0
num1 ?? 0 ?? 0

Then, ?? is right associative, so it's calculated from the right:

(num1 ?? (0 ?? 0))

The left 0 of (0 ?? 0) is already non-optional. That's why it gives a warning:

Left side of nil coalescing operator '??' has non-optional type 'Int', so the right side is never used


The solution is to use parentheses to be more clear:

let result = (num1 ?? 0) + num2

Check out the table of precedence and associativity here, ordered from high to low: https://developer.apple.com/documentation/swift/operator_declarations