Pab*_*rro 6 generics templates swift
请考虑以下内容(从实际代码中简化):
func roundedInt<T: FloatingPoint>(_ f: T) -> Int {
return Int(f.rounded())
}
Run Code Online (Sandbox Code Playgroud)
无法编译时出现以下错误:
无法使用类型为'(T)的参数列表调用类型'Int'的初始值设定项'Int'的过载存在这些部分匹配的参数列表:(Int64),(Word),(UInt8),(Int8),(UInt16) ),(Int16),(UInt32),(Int32),(UInt64),(UInt),(Int),(Float),(Double),(Float80),(String,radix:Int),(CGFloat), (的NSNumber)
我认为这意味着FloatingPoint无法与任何Int重载匹配.
是否有一种简单的方法可以使这项工作?或者是否存在限制Swift泛型(例如,与C++模板相比)排除这种情况?
简单的 C++ 模板只不过是一种宏式、无类型、源代码替换机制。调用代码被应用的模板替换,编译器检查生成的代码是否有意义。你是对的,roundedInt<T> 无界函数在 C++ 领域应该可以正常工作。
相反,Swift 泛型在设计上是类型安全的,这意味着泛型代码本身必须是健全的,独立于给定调用站点的任何细节。在您的示例中,FloatingPoint协议是指导编译的类型(而不是T调用代码使用的实际类型)。
(顺便说一句,Java/C# 泛型也类似于 Swift 风格。)
关于您的实际问题,您可以简单地为该roundedInt函数提供两个重载:
func roundedInt(_ f: Float) -> Int { ... }
func roundedInt(_ f: Double) -> Int { ... }
Run Code Online (Sandbox Code Playgroud)
这应该涵盖大多数用例。当然,假设您只是用这个编写小的辅助函数......而不是完整的库/框架!
否则,请尝试@Sweeper基于字符串的解决方案。但请记住,除了他正确指出的潜在精度损失之外,还潜伏着一些令人讨厌的性能问题。