You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 08:42:37