使Swift泛型与重载函数一起玩

使Swift泛型与重载函数一起玩,第1张

概述我正在尝试构建一个通用类型MyStruct< T>可以使用Float或Double进行内部存储.在初始化程序中,我传递了一个类型为T的参数(我打算将其作为Float或Double).该初始化程序调用一些trig函数,例如sin()和cos().这两个函数都在系统库中重载,以提供Float和Double版本. var f:Float=1.2var d:Double=1.2sin(f) //0. 我正在尝试构建一个通用类型MyStruct< T>可以使用float或Double进行内部存储.在初始化程序中,我传递了一个类型为T的参数(我打算将其作为float或Double).该初始化程序调用一些trig函数,例如sin()和cos().这两个函数都在系统库中重载,以提供float和Double版本.

var f:float=1.2var d:Double=1.2sin(f) //0.9320391sin(d) //0.9320390859672263

麻烦的是,我不能在我的通用结构中使用它们.精简案例如下所示:

struct MyStruct<T> {    var v:T    init(x:T){v=sin(x)}}

因为:

Playground execution Failed: UnTitled Page.xcplaygroundpage:9:17:
error: cannot invoke ‘sin’ with an argument List of type ‘(T)’
init(x:T){v=sin(x)}

UnTitled Page.xcplaygroundpage:9:17: note: overloads for ‘sin’ exist with these partially matching parameter Lists:
(float),(Double)
init(x:T){v=sin(x)}

看起来应该有办法使这项工作,但它感觉很像this situation.评论表明,没有办法要求存在全局功能.

我可以通过使用如下构造强制这种情况:

init(x:T){v=T(sin(Double(x)))}

并且在T上设置一个可以从Double构造的约束,但这似乎打败了构造结构的float版本的目的,这是为了减少在关键代码循环中使用它时的计算工作量.

如果在库中将sin()定义为泛型函数而不是重载函数,感觉会更容易:

func sin<T:floatingPointType> (x:T) -> T

但是它就是这样啊.

有没有办法让我在标准库之上构建一个float / Double不可知的库,而不会增加很多开销?

解决方法 不幸的是,没有简单的方法可以像在Swift中实现sin()一样.它必须被视为运算符(如Equatable和==如何工作),以便允许您将其添加为协议要求.

@matt’s solution是一个很好的快速修复,但如果你想要一些更永久的东西,你可能想要考虑创建一个协议,然后扩展浮点类型,以便允许你使用泛型版本重载sin()函数.

protocol floatingPointMathType : floatingPointType {    var _sinValue : Self { get }}extension float : floatingPointMathType {    var _sinValue : float {return sin(self)}}extension Double : floatingPointMathType {    var _sinValue : Double {return sin(self)}}extension CGfloat : floatingPointMathType {    var _sinValue : CGfloat {return sin(self)}}func sin<T:floatingPointMathType>(x:T) -> T {return x._sinValue}

(随意添加更多数学函数)

我们必须在这里使用’shadow’计算属性来弥补我们不能简单地使用sin()作为协议要求的事实.它并不理想 – 但可能和你一样好.

您现在可以继续使用sin()作为通用函数:

struct MyStruct<T:floatingPointMathType> {    var v : T    init(x:T) {        v =  sin(x)    }}
print(MyStruct(x: float(3.0)).v) // 0.14112print(MyStruct(x: Double(3.0)).v) // 0.141120008059867print(MyStruct(x: CGfloat(3.0)).v) // 0.141120008059867
总结

以上是内存溢出为你收集整理的使Swift泛型与重载函数一起玩全部内容,希望文章能够帮你解决使Swift泛型与重载函数一起玩所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1005163.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存