簡體   English   中英

如何在 Swift 中使用函數參數消除對泛型函數的調用的歧義?

[英]How do I disambiguate this call to a generic function with a function parameter in Swift?

我正在編寫一個解析器類,它期望以特定順序讀取令牌序列。 其語法中的某些產生式具有可選的非終結符,因此我想制作一個通用的“可能”函數,該函數可以傳遞負責將非終結符解析為回調的函數。 通常,函數會在失敗時拋出錯誤,但由於在某些情況下它是可選的,maybe 函數會抑制錯誤。 但是,Swift 提供了錯誤“表達式類型在沒有更多上下文的情況下不明確”,我無法找出正確的強制轉換和/或類型集來消除歧義。

這是我能夠編寫以重新創建錯誤的最少量代碼:

public struct VariableDeclaration {
    public let identifier: Identifier
    public let type: String?
}

public struct Identifier { }

public class Parser {
    
    public func parseVariableDeclaration() throws -> VariableDeclaration {
        let identifier = try self.parseIdentifier()
        let type = self.maybe(self.parseType)
        return VariableDeclaration(identifier: identifier, type: type)
    }
    
    public func parseIdentifier() throws -> Identifier { return Identifier() }
    
    public func parseType() throws -> String { return "" }
    
    public func maybe<T>(_ callback: (Parser) -> () throws -> T) -> T? {
        do {
            return try callback(self)()
        }
        catch {
            return nil
        }
    }
}

以下是我在消除有問題的行的歧義方面的一些失敗嘗試:

let type: String? self.maybe(self.parseType)
let type = self.maybe(self.parseType) as String?
let type = self.maybe<String>(self.parseType)

這里的問題不是通用參數。 您的第一次和第二次嘗試會告訴編譯器T應該是什么類型。

問題是您作為callback傳遞的值,它具有以下簽名:

(Parser) -> () throws -> T

您正在傳遞具有以下簽名的self.parseType

() throws -> String

使用Self.parseType (注意大寫S )或Parser.parseType作為callback值是Parser.parseType

或者,你可以定義maybe是這樣的:

public func maybe<T>(_ callback: (Parser) throws -> T) -> T? {
    do {
        return try callback(self)
    } catch {
        return nil
    }
}

然后像這樣調用它:

let type = self.maybe { try $0.parseType() }

我不知道這是否真的是你想做的事,但如果你想保留的簽名maybe ,你需要通過這樣的方法的部分參考:

        let type = self.maybe(Parser.parseType)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM