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
相关产品推荐
相关产品推荐

