Swift中如何仅擦除闭包的参数类型为AnyHashable?
解决Swift闭包类型擦除问题:将
(T.Element) -> any View转为(AnyHashable) -> any View 你可以通过包装原闭包,在新闭包内部完成AnyHashable到T.Element的类型转换,实现类型擦除。修改后的初始化代码如下:
init<T: RandomAccessCollection>( items: T, build: @escaping (T.Element) -> any View ) where T.Element : Hashable { self.items = AnyRandomAccessCollection(items.map({ AnyHashable($0) })) // 包装原闭包,完成类型擦除 self.itemBuild = { anyHashable in // 由于初始化时所有元素都是T.Element转的AnyHashable,这里转换是安全的 guard let element = anyHashable as? T.Element else { fatalError("Unexpected element type passed to itemBuild: \(type(of: anyHashable))") } return build(element) } } private let itemBuild: (AnyHashable) -> any View
原理说明
- 这里的类型擦除是通过中间闭包实现的:对外隐藏原始的
T.Element类型,只暴露AnyHashable作为输入类型;内部则保留对原始类型的转换逻辑。 - 因为初始化时
items里的所有元素都是从T.Element转换为AnyHashable的,后续调用itemBuild时传入的参数必然是对应类型的AnyHashable,所以正常流程下as? T.Element的转换永远成功。如果想简化代码,也可以直接用强制解包:build(anyHashable as! T.Element),但保留guard能在异常情况下给出更清晰的错误信息。
内容的提问来源于stack exchange,提问作者shipty
相关产品推荐
相关产品推荐

