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

ArgumentParser中AsyncParsableCommand无法识别async run()函数

问题分析与解决方案

核心问题1:run()方法签名不匹配

你给run()加了mutating修饰符,但AsyncParsableCommand协议定义的run()方法是非mutating的异步方法。当签名不匹配时,系统会执行协议的默认实现(打印命令帮助),而非你的自定义逻辑。

核心问题2:异步任务未被等待

即使修复签名,你的doAsyncInLoop里启动了独立Task后直接返回,导致run()执行完就退出程序,异步任务还没完成就被终止。


修复步骤

1. 移除run()的mutating修饰符

修改后的run()方法:

func run() async throws {
    print("In \(#function). count == \(count ?? 0)")
    if let count, count > 0 {
        await doAsyncInLoop(count: count)
    }
}

2. 等待异步任务完成

将doAsyncInLoop里的嵌套Task移除,直接在方法内执行循环并等待每个任务:

func doAsyncInLoop(count: Int) async {
    if #available(macOS 10.15, *) {
        print("In macOS ≥10.15")
        for index in 1...count {
            do {
                let result = try await doAsyncTask(index: index)
                print(result)
            } catch {
                print("Async job \(index) failed: \(error)")
            }
        }
    } else {
        print("In macOS <10.15. Task() not available.")
    }
}

完整修复后的代码

import ArgumentParser
import Foundation

@main
struct AsyncTest: AsyncParsableCommand {
    @Option(name: .shortAndLong, help: "The number of times to snork.")
    var count: Int? = nil
    
    func doAsyncInLoop(count: Int) async {
        if #available(macOS 10.15, *) {
            print("In macOS ≥10.15")
            for index in 1...count {
                do {
                    let result = try await doAsyncTask(index: index)
                    print(result)
                } catch {
                    print("Async job \(index) failed: \(error)")
                }
            }
        } else {
            print("In macOS <10.15. Task() not available.")
        }
    }

    @discardableResult func doAsyncTask(index: Int) async throws -> String {
        print("In \(#function).")
        let millisecond = NSEC_PER_SEC / 1000
        let duration = millisecond * UInt64.random(in: 10...500)
        if #available(macOS 10.15, *) {
            try await Task.sleep(nanoseconds: duration)
        }
        return "Async job \(index) complete"
    }

    func run() async throws {
        print("In \(#function). count == \(count ?? 0)")
        if let count, count > 0 {
            await doAsyncInLoop(count: count)
        }
    }
}

验证修复

运行命令:

swift run AsyncTest --count 3

此时程序会依次执行3个异步任务,等待每个任务完成后输出结果,所有任务结束后才会退出。

内容的提问来源于stack exchange,提问作者Duncan C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:03:37