[英]How to call a generic function with parameter of associated type in Swift 3
[英]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.