由于 Swift 缺少 CGFloat 的隐式转换而造成的混乱

Posted

技术标签:

【中文标题】由于 Swift 缺少 CGFloat 的隐式转换而造成的混乱【英文标题】:Confusion due to Swift lacking implicit conversion of CGFloat 【发布时间】:2014-07-29 20:48:11 【问题描述】:

尝试在返回 `CGFloat 的函数中进行算术运算,但出现错误:

找不到接受提供的参数的“/”的重载

func kDCControlDegreesToRadians(x : CGFloat) -> CGFloat
 
     return (M_PI * (x) / 180.0) // error is here. 

有没有其他人看到过这种类型的问题?

【问题讨论】:

这不是重复的。虽然抛出的错误是相同的,但这里的根本原因比对类型安全和类型推断的误解要微妙得多。 @Mani,我建议您尝试为您的问题想一个不同的标题。事实上,它会导致与所谓的重复内容混淆,并且可能会让您的问题被仅根据标题投票的人关闭。 @Cezar 我已经编辑了我的标题,如果你觉得这个标题让人困惑,请随时编辑我的标题。 【参考方案1】:

这是doublefloat 转换的问题。

在 64 位机器上,CGFloat 定义为 double,您将毫无问题地编译它,因为 M_PIx 都是双精度的。

在 32 位机器上,CGFloatfloat,但 M_PI 仍然是双精度。不幸的是,Swift 中没有隐式转换,因此您必须显式转换:

return (CGFloat(M_PI) * (x) / 180.0)

180.0 字面量的类型是推断出来的。

在 Swift 3 中

M_PI 已弃用,请改用CGFloat.pi

return (x * .pi / 180.0)

【讨论】:

我的脑海中仍然在流淌着 C 和 Objective-C,这就是问题所在。我接到你了。工作正常。谢谢@Sulthan..【参考方案2】:

最好抽象出复杂性。首先创建一个扩展

extension Double 
    /** Converts the specified value in degrees into radians. */
    func degrees() -> CGFloat 
        return CGFloat(self) * CGFloat(M_PI / 180.0)
    

然后在您的代码中使用它,例如以下示例

let angle = 30.0.degrees()
let transform = CGAffineTransformRotate(self.sliderControl.transform, angle);

起初我不愿意扩展 Double,因为我不喜欢创建定制的语言使用(来自 C++ 中的编码恐惧)。然而,实践经验表明这是一种语言自然的抽象方式。

【讨论】:

【参考方案3】:

在这种特殊情况下,我有一个可爱的技巧要推荐

let π = CGFloat(M_PI)

Unicode 无处不在,π 很容易用 Opt+P

【讨论】:

+1 用于使用 unicode 符号名称,这不会像大多数人那样吓到我 :D (我想知道您是否可以将其添加为扩展名,因为 CGFloat.π 会很明显它是一种什么样的价值……)【参考方案4】:

这应该可以修复错误:

func kDCControlDegreesToRadians(x : CGFloat) -> CGFloat

    return (CGFloat(M_PI) * (x) / 180.0)

发生错误的原因是x 被明确声明为CGFloat,而M_PI 的类型为CDouble,如声明中所示:

var M_PI: CDouble  get  /* pi             */

因此,您需要将M_PI 转换为类型CGFloat,使其与x 的类型匹配(正如我在上面的代码中所做的那样)。这样,不同类型的操作就不会发生冲突了。

请注意,与其他答案(以及@Cezar 评论)中所述相反,您不需要将 180.0 显式转换为 CGFloat 类型,因为它是literal,并且没有显式类型,因此会自动转换为CGFloat,无需手动转换。

【讨论】:

至少应该有一个编译器标志来关闭这种纳粹类型检查。它真的会扼杀生产力 有,叫-x objective-c @PartialyFinite 具有不同类型的生产力 ki]]。

以上是关于由于 Swift 缺少 CGFloat 的隐式转换而造成的混乱的主要内容,如果未能解决你的问题,请参考以下文章

TransferValue - 在 TreeView ItemsSource 中生成的隐式转换器 <null>

仅在一个构造函数上的类成员初始化程序中的隐式常量转换 [-Werror=overflow] 溢出

第五篇:你“ 看不见 ” 的隐式转换

25.scala的隐式转换

JavaScript的数据类型的隐式转换

CALayer“内容”属性上的隐式动画