Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional binding with try? and as? still produces an optional type

I have code for executing an NSFetchRequest and casting its result to an array of my custom data model type. Fetching may throw but I don't want to care about the error so I use try?, and I also use as? in casting. In Swift 2, this used to be just fine, but Swift 3 produces a double optional:

var expenses: [Expense]? {
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: Expense.entityName)
    request.predicate = NSPredicate(format: "dateSpent >= %@ AND dateSpent <= %@", [self.startDate, self.endDate])

    // Returns [Expense]? because right side is [Expense]??
    if let expenses = try? App.mainQueueContext.fetch(request) as? [Expense],
        expenses?.isEmpty == false {
        return expenses
    }
    return nil
}

How can I rephrase the right side of my optional binding in if let so that its type will simply be an array [Expense]? I think it looks absurd that in the following boolean condition (which used to be a where clause), the array is still optional.

like image 368
MLQ Avatar asked Oct 05 '16 10:10

MLQ


2 Answers

You must wrap your try? call within parenthesis like this :

if let expenses = (try? App.mainQueueContext.fetch(request)) as? [Expense]

That's because as? has a higher precedence than try? (probably because try? can be applied to the whole expression).

like image 118
Fantattitude Avatar answered Oct 11 '22 20:10

Fantattitude


@Fantattitude's answer gives what you want. But it takes me a while to go through the document to find out why. To long to be a comment, so here's the reference:


According to The Swift Programming Language (Swift 3) Expressions Chapter

When the expression on the left hand side of a binary operator is marked with try, try?, or try!, that operator applies to the whole binary expression.

Firstly, I thought as may not be a binary operator, but in Swift Standard Library Operators

as, as?, and as! are Infix operators operators

and in Operator Declaration chapter

An infix operator is a binary operator that is written between its two operands, such as the familiar addition operator (+) in the expression 1 + 2.

like image 25
zc246 Avatar answered Oct 11 '22 19:10

zc246