Swift中ArgumentParser结合async API时始终显示USAGE文本的问题
问题原因
你遇到的问题是因为**ParsableCommand协议要求的run()方法是同步无返回值的**,但你实现了async throws版本的run,框架无法找到符合协议要求的执行入口,因此默认输出了帮助信息。
解决方法
将Foo遵循的协议从ParsableCommand改为AsyncParsableCommand——这是ArgumentParser专门为支持异步命令提供的协议,它定义了async throws的run()方法签名。
修改后的代码如下:
struct Foo: AsyncParsableCommand { // 替换为AsyncParsableCommand @Argument( help: "File to be parsed. If not present, parses stdin.", transform: URL.init(fileURLWithPath:) ) var file: URL? mutating func run() async throws { let handle: FileHandle if let file { handle = try .init(forReadingFrom: file) } else { handle = .standardInput } for try await line in handle.bytes.lines { // do something with each line } try handle.close() } }
额外说明
如果你的项目使用的是较早版本的ArgumentParser(低于0.4.0),AsyncParsableCommand可能不存在,此时需要升级到支持异步的版本,或者手动处理异步逻辑:在同步的run()方法中调用异步代码,比如用Task包裹:
struct Foo: ParsableCommand { // ... 保持原有属性定义不变 ... mutating func run() { Task { do { let handle: FileHandle if let file { handle = try .init(forReadingFrom: file) } else { handle = .standardInput } for try await line in handle.bytes.lines { // do something with each line } try handle.close() } catch { print("Error: \(error)") exit(1) } } // 若需要等待异步任务完成,可添加RunLoop或DispatchQueue阻塞逻辑,避免程序提前退出 } }
不过更推荐使用AsyncParsableCommand的方案,它是框架官方提供的异步支持方式,能更好地处理错误和命令生命周期。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

