-1

我的理解是 go fmt 应该生成可读且格式一致的代码。但是,我认为情况并非如此。

我输入了注释代码,然后 go fmt 返回了未注释的代码。为什么它倒塌了0.5*(y3-y0),但没有0.5 * (y2 - y0)?这怎么一致?而且,IMO,几乎每个空间都塌陷的返回线是可读性灾难。

不一致是错误吗?有没有办法让 go fmt 单独留下一些行(如返回行)?

func cubicInterpolate(x, y0, y1, y2, y3 float64) float64 {
    // 4-point, 3rd-order Hermite (x-form)
    // c0 := y1
    // c1 := 0.5 * (y2 - y0)
    // c2 := y0 - 2.5 * y1 + 2. * y2 - 0.5 * y3
    // c3 := 1.5 * (y1 - y2) + 0.5 * (y3 - y0)
    //
    // return ((c3 * x + c2) * x + c1) * x + c0

    c0 := y1
    c1 := 0.5 * (y2 - y0)
    c2 := y0 - 2.5*y1 + 2.*y2 - 0.5*y3
    c3 := 1.5*(y1-y2) + 0.5*(y3-y0)

    return ((c3*x+c2)*x+c1)*x + c0
}
4

1 回答 1

2

这记录在go 源代码中;目的是使运算符优先级明确。例如,在您的示例y0 - 2.5*y1 + 2.*y2 - 0.5*y3中,乘法将在减法之前执行,并且选择的格式一目了然。

回答你的问题;这不是错误;确实在格式化方面付出了相当多的努力。您不能从格式中排除一行;这是设计使然,如常见问题解答中所述,目的是执行layont规则:

gofmt 是一个漂亮的打印机,其目的是执行布局规则;它取代了允许解释的通常的注意事项纲要。

下面是来自go/printer/nodes.go的格式化摘录,详细说明了格式化规则:

格式化二进制表达式:决定截止,然后格式化。让我们调用 depth == 1 Normal 模式和 depth > 1 Compact 模式。(Russ Cox 的算法建议。)

优先级是: 5 * / % << >> & &^ 4 + - | ^ 3 == != < <= > >= 2 && 1 ||

唯一的决定是第 4 层和第 5 层周围是否有空格。第 6 层(一元)永远不会有空格,并且总是在第 3 层及以下的空格。

要选择截断值,请查看整个表达式,但不包括主要表达式(函数调用、带括号的表达式),并应用以下规则:

  1. 如果存在右侧一元操作数的二元运算符在没有空格的情况下会发生冲突,则截止必须是(按顺序):
   /* 6   
   && 6   
   &^ 6   
   ++ 5   
   -- 5 

(比较运算符周围总是有空格。)

  1. 如果混合了 5 级和 4 级运算符,则在 Normal 模式下截止值是 5(使用空格来区分优先级),在 Compact 模式下是 4(从不使用空格)。

  2. 如果没有 4 级运算符或没有 5 级运算符,则在 Normal 模式下截止值为 6(始终使用空格),在 Compact 模式下为 4(从不使用空格)。

于 2019-11-25T02:35:57.293 回答