Xcode13 Playground用some Summable作参数报错,咨询原因及适用范围
Swift中some/any关键字的使用疑问及解决方案
问题还原
你在Xcode 13.0的Playground中编写了如下代码:
protocol Summable { static func +(lhs: Self, rhs: Self) -> Self } extension Int: Summable {} extension Double: Summable {} extension String: Summable {} struct Print { func printSummable(x: some Summable) { print(x) } }
出现错误提示:
'some' types are only implemented for the declared type of properties
and subscripts and the return type of functions
你希望仅打印符合Summable协议的对象,同时想咨询:some/any关键字是否仅适用于带有关联类型的协议?
核心解答
报错原因
some关键字的使用范围有明确限制:只能用于属性、下标的声明类型,以及函数的返回类型,不能用在函数的参数位置上——这和协议是否带有关联类型没有关系。some/any并非只针对带关联类型的协议
这两个关键字的作用是处理存在类型(existential type),带关联类型的协议因为无法直接作为具体类型使用,所以经常会结合some/any来解决,但它们同样可以用于普通协议(比如你的Summable)。
解决方案:打印符合Summable协议的对象
针对你的需求,有两种可行写法:
写法1:使用any Summable(Swift 5.6+)
显式用any声明参数为任意符合Summable的类型实例:
struct Print { func printSummable(x: any Summable) { print(x) } }
写法2:直接使用协议作为参数类型(兼容旧版Swift)
因为Summable是无关联类型的普通协议,原本就可以直接作为参数类型(Swift 5.6之前的默认写法,5.6之后依然兼容):
struct Print { func printSummable(x: Summable) { print(x) } }
补充:some的正确使用场景
举几个some的合法用法示例:
- 函数返回值:
func getRandomSummable() -> some Summable { Bool.random() ? 42 : "Hello" }
- 属性:
struct Example { var defaultSummable: some Summable = 3.14 }
内容的提问来源于stack exchange,提问作者Isiah
相关产品推荐
相关产品推荐

