swift - 如何在 Swift 中消除对带有函数参数的泛型函数的调用的歧义?
问题描述
我正在编写一个解析器类,它期望以特定顺序读取一系列标记。其语法中的某些产品具有可选的非终端,因此我想做一个通用的“可能”函数,可以将负责将非终端解析为回调的函数传递给该函数。通常,该函数会在失败时抛出错误,但由于在某些情况下它是可选的,因此该 may 函数会抑制错误。但是,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
。
或者,您可以这样定义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() }
推荐阅读
- powershell - 如何在 Powershell 中使用 OR 操作
- xcode - Swift 故事板和 Hello World
- python - 尝试抓取我的蜘蛛时出错 (NotImplementedError)
- sequelize.js - 此 sql 的等效 sequelize [Op.any] 语句?
- python - 重温旧代码 - AI(无法正常工作)
- python - 如何理解生成器中的作用域?
- python - django 自定义博客文章网址
- delphi - 我在 Delphi 10.3.3 的 OnClick 事件中遇到堆栈溢出错误
- batch-file - 尝试使用 Windows 批处理删除所有多余的空格,同时在值之间只留一个空格
- c# - 为测试目的生成 X509Certificate2 的最简单方法