考虑以下几点(从实际代码中简化):
func roundedInt<T: FloatingPoint>(_ f: T) -> Int {
return Int(f.rounded())
}这在编译过程中出现了以下错误:
不能使用“Int”类型的参数列表调用“Int”类型的初始化器,因为“Int”的重载包含这些部分匹配的参数列表:(Int64)、(Word)、(UInt8)、(Int8)、(UInt16)、(Int16)、(UInt32)、(Int32)、(UInt64)、(UInt)、(Int)、(浮点)、(双)、(Float80)、(字符串、基x: Int)、(CGFloat)、(NSNumber)
我认为这意味着FloatingPoint不能与任何Int重载相匹配。
有什么简单的方法可以让这件事成功吗?或者,Swift泛型(例如,与C++模板相比)是否有一个排除这一点的限制?
发布于 2017-04-30 12:43:03
简单的C++模板只不过是一种宏、类型少的源代码替换机制.调用代码被应用模板替换,编译器将检查生成的代码是否有意义。您是对的,roundedInt<T>无界函数在C++域应该可以很好地工作。
相反,Swift泛型是按设计设计的类型,这意味着泛型代码必须是独立的,独立于给定呼叫站点的任何细节。在您的示例中,FloatingPoint协议是引导编译的类型(而不是调用代码使用的实际T类型)。
(顺便说一下,Java/C#泛型也类似Swift风格。)
对于实际问题,只需为roundedInt函数提供两个重载:
func roundedInt(_ f: Float) -> Int { ... }
func roundedInt(_ f: Double) -> Int { ... }这应该涵盖大多数用例。当然,假设您只是在编写小助手函数.而不是完整的库/框架!
否则,尝试@Sweeper基于字符串的解决方案。但请记住,除了潜在的精度损失,他正确地指出,也有一些恶劣的性能问题潜伏在那里。
https://stackoverflow.com/questions/43706023
复制相似问题