Why does return <expr> work when let var = <expr>; return var give an error that it can't convert the type

Viewed 53

I have the following code, which compiles & works fine:

import RealmSwift

struct Bucket: Codable, Identifiable {
    var id: UUID
    var title: String

    init() {
        self.id = UUID()
        self.title = "new bucket"
    }

    init(title: String) {
        self.id = UUID()
        self.title = title
    }

    init(id: UUID, title: String) {
        self.id = id
        self.title = title
    }
}

class RealmBucket : Object {
    @Persisted var id : UUID
    @Persisted var title : String
    convenience init(_ id: UUID, _ title: String) {
        self.init()
        self.id = id
        self.title = title
    }
}

func loadBuckets() -> [Bucket] {
    let realm = try! Realm()
    let realmBuckets = realm.objects(RealmBucket.self)
    return realmBuckets.map { Bucket(id: $0.id, title: $0.title) }
}

but if I change the loadBuckets() function to:

func loadBuckets() -> [Bucket] {
    let realm = try! Realm()
    let realmBuckets = realm.objects(RealmBucket.self)
    let result = realmBuckets.map { Bucket(id: $0.id, title: $0.title) }
    return result
}

(just the last line changed) I get the error:

Cannot convert return expression of type 'LazyMapSequence<Results<RealmBucket>, Bucket>' to return type '[Bucket]'

If I change the let line to be:

        let result : [Bucket] = realmBuckets.map { Bucket(id: $0.id, title: $0.title) }

then it works again.

I can think of a couple possible explanations for the behavior, but they all seem to point to a compiler bug, or language deficiency, and I'm guessing that perhaps there is some language feature I'm unaware of.

Does anyone know why the compiler is able to automatically convert the LazyMapSequence in the case of the return value being a variable, when it clearly knows the type of the variable given the error it is giving me. I'm relatively new to Swift, and hoping to learn something from this.

Based on the current answers, my assumption is that it is just a slightly different case in the compiler code to convert the variable versus a method call, so it's really just a compiler deficiency, and likely to not exist down the road. In any case, it's easy enough to work around, it just struck me as odd.

2 Answers

You have to explicitly define the return type of map function, when you use shorthand closure syntax, probably that is the reason.

A “return” statement knows the type it has to return, so if applies that knowledge when the right hand side is evaluated, and can often convert that result to the correct type.

A let statement with no type means the compiler doesn’t know which type is needed. So the right hand side can be evaluated differently.

Related