Swift中能否将抛出计算属性传入函数或初始化器?
Swift抛出计算属性的传递与扩展方案
一、直接以CustomView(Object.list)实例化是否可行?
不行。因为Object.list是带有throws的计算属性,Swift编译器强制要求访问这类属性时必须处理错误(使用try并配合do/catch、try?或try!)。直接写CustomView(Object.list)会触发编译错误,此时会直接尝试获取属性值,但未处理可能的抛出错误。
如果希望由CustomView的初始化器将其转换为Result类型,可以让初始化器接受一个自动闭包参数,内部处理错误转换:
struct CustomView { let result: Result<[Object], Error> init(_ fetchItems: @autoclosure () throws -> [Object]) { result = Result(catching: fetchItems) } }
但调用时仍需显式使用try:
// 必须带try,否则编译报错 CustomView(try Object.list)
无法省略try,这是Swift错误处理机制的强制要求。
二、能否通过泛型扩展为任意抛出属性添加.result计算属性?
可以通过扩展无参抛出闭包类型实现类似效果,但无法直接给抛出属性本身添加.result(因为属性的类型是其返回值类型,而非抛出闭包)。具体方案如下:
扩展() throws -> T类型,添加result计算属性,将闭包执行结果封装为Result:
extension () throws -> T { var result: Result<T, Error> { Result(catching: self) } }
使用时,将抛出属性包装为闭包后调用.result:
CustomView({ try Object.list }.result)
如果想进一步简化写法,可以定义一个全局工具函数,将抛出属性转换为闭包:
func throwing<T>(_ closure: @autoclosure () throws -> T) -> () throws -> T { closure } // 调用更简洁 CustomView(throwing(try Object.list).result)
注意:这里的try仍然无法省略,因为本质上还是在访问抛出属性,必须遵守Swift的错误处理规则。
内容的提问来源于stack exchange,提问作者Tony Tompos
相关产品推荐
相关产品推荐

