内部有闭包的递归函数

Posted

技术标签:

【中文标题】内部有闭包的递归函数【英文标题】:Recursive func with closure inside 【发布时间】:2020-04-08 17:29:14 【问题描述】:

我正在尝试在我的 Firebase 数据库中生成一个唯一的 8 位用户 ID 作为我的用户的密钥,而不是在 Firebase 中创建的 28 位用户ID。

在函数中,我想生成随机变量,然后对照数据库检查它是否存在。如果它存在于数据库中,我想递归调用,直到创建唯一键。

我试过了

func createUniqueID() -> String 

    let userID = generateUserID()

    let ref = Database.database().reference(withPath: "users")
    ref.observeSingleEvent(of: .value, with:  (snapshot) in
        if snapshot.hasChild(userID) 
            return createUniqueID() //errors here
        
        else 
            return userID //errors here
        
    )

但我在 firebase 闭包“无效函数中的意外非无效返回值”中的两条返回行都收到错误

我尝试将其作为内联函数来实现

func wtf() -> String 

    let userID = "123456"//generateUserID()

    func doesUserIDExistAlready(userID: String, complete: @escaping(String) -> ()) 

        let ref = Database.database().reference(withPath: "users")
        ref.observeSingleEvent(of: .value, with:  (snapshot) in
            if snapshot.hasChild(userID) 
                complete( self.wtf() )
            
            else 
                complete( userID )
            
        )
    

    doesUserIDExistAlready(userID: userID)  userID in
        return userID //warning here
    

但我在返回用户 ID 时收到“未使用 'String' 类型的表达式”的警告

我也尝试使用没有完成但返回字符串的内联函数

func wtf2() -> String 

    let userID = "123456"//generateUserID()

    func doesUserIDExistAlready(userID: String) -> String 

        let ref = Database.database().reference(withPath: "users")
        ref.observeSingleEvent(of: .value, with:  (snapshot) in
            if snapshot.hasChild(userID) 
                return self.wtf2() //errors here
            
            else 
                return userID //errors here
            
        )
    

    return doesUserIDExistAlready(userID: userID)

但我在 firebase 闭包“无效函数中的意外非无效返回值”中的两条返回线上也遇到错误

这可能吗?

【问题讨论】:

相关,但不是重复的 IMO:***.com/questions/27390656/… 【参考方案1】:

向 Firebase 请求数据是一个异步操作,因此createUniqueID 无法立即返回String。您可以接受 completion 闭包以将 ID“返回”给调用者(就像 observeSingleEvent 如何使用闭包为您提供值一样)。

func createUniqueID(_ completion: (String) -> Void) 

    let userID = generateUserID()

    let ref = Database.database().reference(withPath: "users")
    ref.observeSingleEvent(of: .value, with:  (snapshot) in
        if snapshot.hasChild(userID) 
            createUniqueID(completion)
        
        else 
            completion(userID)
        
    )

【讨论】:

太棒了,我没有想过从 firebase 调用中完成它而不是尝试从递归函数中返回一个值。谢谢

以上是关于内部有闭包的递归函数的主要内容,如果未能解决你的问题,请参考以下文章

十八十九穿插python沉淀之路--嵌套闭包递归,三者的区别

关于闭包函数和递归函数的详细理解

javascript之闭包,递归,深拷贝

函数的定义和调用 + 改变this指向方法 + 闭包 + 递归

递归,闭包,闭包与变量

函数变量闭包