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

Swift为何无法正确推断该返回类型?

问题分析与解决

你的问题根源在于Swift编译器在Array的扩展上下文里,错误地将Array(firstCharacters)的初始化类型推断为Array<Cocktail>,而不是你期望的Array<String>,这才导致了那两个看似矛盾的错误。

为什么会出现这种情况?

因为你是在Array where Element == Cocktail的扩展里编写代码,编译器会优先把当前作用域内的Array类型(也就是Array<Cocktail>)作为初始化器的默认类型。当你调用Array(firstCharacters)时,编译器尝试把Set<String>转换成Array<Cocktail>——显然这做不到,于是就抛出了那两个错误:

  • 第一个错误说“无法将Array转成[any ScrollIndexable]”,其实是编译器错误推断出的初始化结果类型,不是你实际的Set<String>对应的数组类型;
  • 第二个错误“调用初始化器无精确匹配”,是因为不存在从Set<String>到Array<Cocktail>的初始化方法。

解决方法

只需要明确指定初始化的数组类型,或者直接将结果转换为[any ScrollIndexable],让编译器明确你的意图:

方案1:显式指定Array的元素类型

extension Array: ScrollIndexProviding where Element == Cocktail {
    var scrollIndices: [any ScrollIndexable] {
        let firstCharacters = reduce(into: Set<String>()) { partialResult, cocktail in
            guard let firstCharacter = cocktail.name.first else {
                return
            }
            partialResult.insert(String(firstCharacter))
        }
        // 显式指定要创建String类型的数组
        return Array<String>(firstCharacters)
    }
}

方案2:直接转换为目标协议数组

也可以省略Array初始化,直接把Set转成[any ScrollIndexable]:

extension Array: ScrollIndexProviding where Element == Cocktail {
    var scrollIndices: [any ScrollIndexable] {
        let firstCharacters = reduce(into: Set<String>()) { partialResult, cocktail in
            guard let firstCharacter = cocktail.name.first else {
                return
            }
            partialResult.insert(String(firstCharacter))
        }
        return Array(firstCharacters.map { $0 as any ScrollIndexable })
        // 或者更简洁:
        // return firstCharacters.map { $0 } as [any ScrollIndexable]
    }
}

这两种方式都能让编译器正确推断类型,解决编译错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:10:33