Swift扩展:var和func,哪个更好?

5

我是一个初学者。 这是代码:

extension Double  {
    func abs1() -> Double  {
        return ( self > 0 ) ? self : -1.0 * self
    }

    var abs2 : Double {
        return ( self > 0 ) ? self : -1.0 * self
    }
}

我想知道 abs1() 函数和 abs2 变量之间的区别是什么,它们是如何工作的,哪个更好?


它们执行相同的操作,应该具有类似(如果不是完全相同)的性能特征。这主要取决于您是否认为一个数字的绝对值是该数字的属性。 - zneak
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Eduardo Oliveros
1个回答

10
它们的工作方式相同,实际上它是一个意图信号。个人建议在这种情况下使用函数,尽管这有点违反直觉,所以我会解释一下。
第一个规则是“它是否有副作用?”如果是,那么它应该是一个函数。
第二个规则是“它是O(1)吗?”(也就是说,“运行需要一个常量时间,并且通常被认为是短时间。”换句话说,它是否“便宜”?)如果不是,那么它应该是一个函数。
但第三个更微妙的规则是“它是否合理地被认为是实例的“属性”?”在这种情况下,我会争辩说不是。它是实例上计算出来的完全不同于实例的东西,并不是实例固有的一部分。替换为非计算属性会相当荒谬(您永远不会将“4”存储为“ -4”的“abs”字段)。所以我会将它做成一个函数。
请注意,在Swift 3中,abs是类型的静态函数(例如,它是Double.abs(4.0),而不是(4.0).abs)。这并不否定你的问题,但考虑到这个特定的案例,这是团队选择解决它的方式,我认为这是更好的方式。

+1. 我通常在合适的时候将它们用作属性,但我喜欢你提出的另外两个标准来考虑它应该是函数还是计算属性。当它没有副作用且“廉价”时,将其视为属性是很有道理的。 - Andy Ibanez
仅供参考:Double 上的静态 abs() 方法是其符合 AbsoluteValuable 协议的一部分,这是有符号数字类型提供自定义实现给全局 abs() 函数的可选方式。我不确定这是否真的是一种通用实例操作方法的首选方式,或者它是否真的意味着以这种方式直接调用。我真的很喜欢你回答中的指南(并点赞了它),但我认为,除非需要符合协议,否则将此类函数建模为静态方法可能是不正确的。 - Daniel Hall
虽然同意不应该直接这样调用,但对于 abs 函数来说,首选方式是使用自由函数 abs()。在 Swift 中,自由函数非常不寻常,而且您是正确的,abs 在一般情况下并不是一个很好的 API 模型。 - Rob Napier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接