表达式对于编译器来说过于复杂 - 如何将此表达式拆分为不同的子表达式?

时间:2016-01-19 20:18:26

标签: swift

错误与乘数变量有关。为什么编译器太复杂了?我该怎么改写呢?我应该发布整个drawRect函数吗?

  

表达太复杂,无法在合理的时间内解决;考虑将表达式分解为不同的子表达式

// Progress is a value between 1.0 and -0.5, determined by the current wave idx, which is used to alter the wave's amplitude.
        var progress = CGFloat(1.0 - Float(i) / Float(numberOfWaves))
        var normedAmplitude = (1.5 * progress - 0.5) * amplitude

        var multiplier = CGFloat(min(1.0, (progress / 3.0 * 2.0) + (1.0 / 3.0))) // error point
        waveColor.colorWithAlphaComponent(multiplier * CGColorGetAlpha(waveColor.CGColor)).set()

2 个答案:

答案 0 :(得分:3)

回答问题

重写代码并将其分解为更小部分的一种方法:

let firstValue = CGFloat(1.0)
let secondValue = ((progress * 2.0) + 1.0) / 3
var multiplier = min(firstValue, secondValue)
waveColor.colorWithAlphaComponent(multiplier * CGColorGetAlpha(waveColor.CGColor)).set()

编译器不会再抱怨了。

一般来说,编写较短的代码行是一个好主意,因为它不仅可以帮助编译器解析表达式,而且还可以让您或其他程序员更容易理解代码的作用。乍看之下,如果你在一两个月内查看代码,你会知道CGFloat(min(1.0, (progress / 3.0 * 2.0) + (1.0 / 3.0)))意味着什么以及为什么要添加,乘以和除以所有这些数字?

这是a good explanation首先出现此错误的原因。

代数游览;)

如何在数学上转换secondValue的代数表达式

你需要代数运算的这些数学属性:

  1. Commutative property:您可以交换操作数。

    适用于加法和乘法:

    • a + b = b + a
    • a * b = b * a
  2. Associative property:评估表达式的顺序无关紧要。您可以根据需要添加或删除括号。

    适用于加法和乘法:

    • (a + b)+ c = a +(b + c)
    • (a * b)* c = a *(b * c)
  3. Distributive property:您可以从括号中提取常见因素。

    适用于添加两个具有共同因素的产品:

    • (a * c)+(b * c)=(a + b)* c
  4. 此外,您需要operator precedence的规则:

    1. 在数学和通用编程语言中,运算符按以下顺序进行评估:

      1. Paranthesis()
      2. 指数x 2
      3. 乘法*和分区/
      4. 加法+和减法 -
    2. 然后还有另外一个技巧:

      1. 快速划分乘法:

        • a / b = a *(1 / b)
      2. 现在让我们使用这些属性来转换你的代数表达式:

             (progress / 3 * 2)         +  (1 / 3)         
          =   progress / 3 * 2          +   1 / 3          | removed parentheses (4)
          =   progress * (1 / 3) * 2    +   1 / 3          | (5)
          =   progress * 2  * (1 / 3)   +   1 / 3          | swapped factors (1)
          =   progress * 2  * (1 / 3)   +   1 * (1 / 3)    | 1 * x = x
          =  (progress * 2) * (1 / 3)   +   1 * (1 / 3)    | added parenthesis (2)
          = ((progress * 2) + 1) * (1 / 3)                 | pulled common factor out (3)
          = ( progress * 2  + 1) * (1 / 3)                 | removed parenthesis (4)
          = ( progress * 2  + 1) / 3                       | (5)
        

        因此,

         (progress / 3.0 * 2.0) + (1.0 / 3.0) = ((progress * 2.0) + 1.0) / 3
        

答案 1 :(得分:2)

只需单独计算progress / 3.0 * 2.0

let calc = progress / 3.0 * 2.0
var multiplier = CGFloat(min(1.0, (calc) + (1.0 / 3.0)))

如果在单行中进行太多计算,则会发生此错误。