Swift泛型与非泛型函数调用优先级问题及解决方法咨询
让Swift编译器优先选择非泛型decode函数的解决方案
你的代码中存在两个核心问题:
WASMDecoder协议同时声明了泛型decode<T: WASMDecodable>和非泛型decode(UInt8.Type)方法,编译器通过any WASMDecoder类型调用时,会优先匹配覆盖范围更广的泛型方法UInt8的init(from:)实现会调用decoder.decode(Self.self),和泛型decode方法形成循环调用
解决方案
将泛型decode<T: WASMDecodable>方法从WASMDecoder协议的主声明中移除,放到协议扩展中实现。Swift中,协议主声明的方法优先级高于扩展中的方法,编译器会优先选择非泛型的具体实现。
修改后的完整代码:
import Foundation import Combine func todo() -> Never{ fatalError("Not Implemented!") } protocol WASMDecodable{ init(from decoder: WASMDecoder) throws } protocol WASMLeafDecodable: WASMDecodable{} extension WASMLeafDecodable{ init(from decoder: any WASMDecoder) throws { self = try decoder.decode(Self.self) } } protocol WASMTopLevelDecoder{ associatedtype Input func decode<T: WASMDecodable>(_ type: T.Type, from input: Self.Input) throws -> T } // 仅在协议主声明中保留非泛型的UInt8解码方法 protocol WASMDecoder{ func decode(_ type: UInt8.Type) throws -> UInt8 } // 泛型解码方法移至协议扩展中作为默认实现 extension WASMDecoder{ func decode<T: WASMDecodable>(_ type: T.Type) throws -> T { try T(from: self) } } class WASMBinaryContainer: WASMDecoder{ private let bytes: Data init(bytes: Data) { self.bytes = bytes } func decode(_ type: UInt8.Type) throws -> UInt8 { guard !bytes.isEmpty else { fatalError("No data available for decoding") } return bytes[0] } } class WASMBinaryDecoder: WASMTopLevelDecoder{ func decode<T>(_ type: T.Type = T.self, from input: Data) throws -> T where T : WASMDecodable { try WASMBinaryContainer(bytes: input).decode(type) } } extension UInt8: WASMLeafDecodable{ } // 测试调用:此时编译器会优先选择非泛型的decode(UInt8.Type)方法 let a: UInt8 = try WASMBinaryDecoder().decode(from: Data([0x01, 0x02]))
补充说明
你之前尝试的func decode<T: WASMDecodable>(_ type: T.Type) throws -> T where T == UInt8写法属于受限泛型,Swift 6中会因为该写法与具体类型的方法存在冲突而报错,因此不推荐使用。
内容的提问来源于stack exchange,提问作者赵家辉
相关产品推荐
相关产品推荐

