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

Swift中Task表达式类型歧义无类型注解错误的修复方法

修复PhotosPicker代码中Task的歧义错误

运行以下使用PhotosPicker的Swift代码时,出现错误提示:

Type of expression is ambiguous without a type annotation on 'Task'

原代码

PhotosPicker(selection: $selectedItem, matching: .videos){
    Image(systemName: "camera.fill")
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(height: 20)
        .padding(2)

}
.onChange(of: selectedItem) { newItem in
    
    videoURL = nil
    
    Task {

        if let data = try? await newItem?.loadTransferable(type: Data.self) {
            
            let bytes = Double(data.count)
            let megabytes = bytes / (8 * 1024 * 1024)
            
            print("size:")
            print(megabytes)

            
            if(megabytes > 32){
                print("too big")
            }else{

                let tempFile = TemporaryMediaFile(withData: data)
                
                let asset = tempFile.avAsset
                
                let vidWidth = await asset?.naturalSize()?.width
                let vidHeight = await asset?.naturalSize()?.height
                
                videoHeight = 160 * (vidHeight! / vidWidth!)
                videoURL = tempFile.url

            }
 
        }else{
            print("picking failed")
        }
    }
}

修复方法

显式指定Task的泛型类型,消除编译器的类型推断歧义:

将代码中的Task {替换为Task<Void, Never> {,修改后的关键代码片段如下:

.onChange(of: selectedItem) { newItem in
    
    videoURL = nil
    
    // 显式标注Task的类型,告知编译器无返回值、不抛出错误
    Task<Void, Never> {

        if let data = try? await newItem?.loadTransferable(type: Data.self) {
            // 原有逻辑保持不变
            let bytes = Double(data.count)
            let megabytes = bytes / (8 * 1024 * 1024)
            
            print("size:")
            print(megabytes)

            
            if(megabytes > 32){
                print("too big")
            }else{

                let tempFile = TemporaryMediaFile(withData: data)
                
                let asset = tempFile.avAsset
                
                let vidWidth = await asset?.naturalSize()?.width
                let vidHeight = await asset?.naturalSize()?.height
                
                videoHeight = 160 * (vidHeight! / vidWidth!)
                videoURL = tempFile.url

            }
        }else{
            print("picking failed")
        }
    }
}

原因说明

Swift编译器在视图修饰器的闭包这类上下文里,无法自动推断Task的返回类型和错误类型。显式指定<Void, Never>明确告诉编译器:这个异步任务没有返回值,且不会抛出任何错误,从而解决类型歧义问题。

另外补充优化建议:原代码中vidHeight! / vidWidth!使用了强制解包,容易因asset?.naturalSize()返回nil导致崩溃,建议改用可选值绑定处理:

if let width = await asset?.naturalSize()?.width, let height = await asset?.naturalSize()?.height {
    videoHeight = 160 * (height / width)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:12:14