0

0

Go语言中对Allman风格括号布局的非标准实现探讨

心靈之曲

心靈之曲

发布时间:2025-08-02 14:56:02

|

790人浏览过

|

来源于php中文网

原创

Go语言中对Allman风格括号布局的非标准实现探讨

Go语言强制采用特定的代码格式,特别是括号的放置风格,与Allman风格存在冲突。尽管Go社区强烈推荐遵循其惯例,但部分开发者仍希望使用Allman风格。本文将探讨一种非传统的“双括号”技巧,使其在Go编译器中通过编译,但同时强调这种方法无法规避gofmt的自动格式化,并可能导致代码可读性和维护性的问题,最终建议遵循Go语言的惯例。

Go语言的惯用括号风格

go语言在设计之初就强调代码风格的统一性,旨在减少不必要的争论,让开发者专注于业务逻辑。其中一个显著的特点就是其强制性的括号放置风格,即k&r风格的变体:左大括号 { 必须与语句(如 if、for、func 等)在同一行,且其后不能有换行符。

例如,一个典型的Go函数定义或条件语句会是这样:

package main

import "fmt"

func main() { // 左大括号与函数名在同一行
    fmt.Println("Hello, Go!")
    if true { // 左大括号与if语句在同一行
        fmt.Println("This is true.")
    }
}

为了确保所有Go代码库的风格一致,Go语言提供了官方的格式化工具 gofmt。该工具会自动将代码格式化为Go语言推荐的风格,包括括号的放置。在Go开发中,gofmt 的使用几乎是强制性的,它被广泛集成到IDE、构建系统和CI/CD流程中,以确保代码库的整洁和一致性。

Allman风格的诉求与挑战

Allman风格(又称ANSI风格)是C语言家族中常见的另一种括号放置风格,其核心特点是将左大括号 { 放置在新的一行。例如:

// C语言中的Allman风格示例
int main()
{
    printf("Hello, Allman!\n");
    if (condition)
    {
        // ...
    }
    return 0;
}

对于习惯了Allman风格的开发者来说,Go语言强制的K&R风格可能会让他们感到不适。直接在Go代码中尝试使用Allman风格,例如将函数或块的左大括号放在新行,会导致编译错误

立即学习go语言免费学习笔记(深入)”;

// 尝试在Go中使用Allman风格(会导致编译错误)
package main

import "fmt"

func main() // ERROR: missing function body
{ // 编译错误:此处的 { 无法识别为函数体开始
    fmt.Println("This will not compile.")
}

Go编译器要求函数声明或控制流语句(如 if, for, switch)后的左大括号必须紧随其后。

一种非传统的“双括号”技巧

尽管Go语言的语法和工具链强烈倾向于其自身的代码风格,但对于那些执意希望在视觉上模拟Allman风格的开发者,存在一种非传统的“双括号”技巧,可以在一定程度上让编译器接受这种结构。

其核心思想是:利用Go语言允许空代码块的特性。通过在合法的第一层括号内部嵌套一个额外的括号对,可以在视觉上将实际的代码逻辑起始括号放置在新行。

考虑以下示例,它展示了如何在 if 语句中使用这种技巧:

package main

import "fmt"

func main() { // Go语言强制要求此括号与函数声明在同一行
    fmt.Println("Starting main function.")

    // 模拟Allman风格的if语句块
    if true { // 此处仍需遵循Go风格,{ 必须与if在同一行
    { // 此内部括号可以在新行,模拟Allman风格的逻辑开始
        fmt.Println("This code block uses a nested brace for visual Allman style.")
        // 实际的代码逻辑在这里
    }} // 对应的双重闭合括号

    fmt.Println("Finished main function.")
}

func exampleFunction() {
{ // 同样适用于函数内部的任意代码块,但函数声明的 { 仍需在同一行
    fmt.Println("This is an example function with a nested block.")
}} // 双重闭合括号

解析:

  1. 外部括号 {: 对于 if 或 func 声明,第一个左大括号 { 必须严格遵循Go语言的语法规则,即与语句在同一行。这是编译通过的必要条件。
  2. 内部括号 {: 在外部合法括号内部,可以插入一个空的匿名代码块 {}。这个内部的左大括号 { 可以放置在新行,从而在视觉上模拟Allman风格的“新行开括号”。
  3. 双重闭合括号 }}: 相应的,代码块的结束需要两个右大括号 }} 来闭合外部和内部的代码块。

这种方法使得编译器能够成功解析并编译代码,因为从语法层面看,它符合Go的块结构定义。

Lobe
Lobe

微软旗下的一个训练器学习模型的平台

下载

gofmt的影响与局限性

虽然“双括号”技巧能够让代码通过Go编译器的检查,但它在实际Go项目中的应用面临着巨大的局限性,主要体现在与 gofmt 工具的冲突上。

gofmt 的设计目标是强制统一所有Go代码的格式。当遇到上述“双括号”的代码时,gofmt 会将其重新格式化。例如:

原始代码(尝试Allman风格):

if true {
{
    fmt.Println("Nested block.")
}}

经过 gofmt 格式化后:

if true {
    {
        fmt.Println("Nested block.")
    }
}

可以看到,gofmt 会将内部的括号对 {} 视为一个独立的、缩进的匿名代码块,并将其格式化为标准的Go风格。这意味着,即使你手动编写了“双括号”来模拟Allman风格,一旦运行 gofmt(这在Go项目中几乎是不可避免的),你的代码就会被重新格式化,从而失去了你期望的Allman风格视觉效果。

因此,这种“解决方案”并未真正实现Allman风格的“保持”,而仅仅是让编译器接受了某种变形。它无法在日常开发流程中规避 gofmt 的自动校正。

代码可读性与维护性考量

除了 gofmt 的影响外,采用“双括号”这种非标准写法还会带来以下负面影响:

  1. 降低代码可读性: 这种写法不符合Go语言的惯例,对于熟悉Go标准风格的开发者来说,会显得非常陌生和难以理解。双重闭合括号 }} 也容易让人感到困惑。
  2. 增加团队协作难度: 在团队项目中,统一的代码风格是高效协作的基础。如果个别成员坚持使用非标准风格,将导致代码库风格不一致,增加代码审查的难度和维护成本。
  3. 可能导致工具链警告: 虽然编译器接受,但Linter等静态代码分析工具可能会将这种非标准写法标记为潜在的代码异味或风格问题。
  4. 与Go语言哲学背道而驰: Go语言的设计哲学之一就是“少即是多”和“约定优于配置”。强制统一代码风格正是这一哲学的体现,旨在减少不必要的选择和争论。

总结与建议

尽管存在“双括号”这种技术上可行的编译通过方案,但它无法真正实现Allman风格在Go项目中的视觉保持,并且会带来显著的可读性、维护性和协作问题。

因此,对于Go语言的开发者,强烈建议:

  • 拥抱Go语言的惯用风格: 适应Go语言的K&R变体括号风格,并充分利用 gofmt 带来的便利。
  • 遵循gofmt的格式化标准: 将 gofmt 集成到你的开发工作流中,让它自动为你格式化代码,确保代码库的统一性。
  • 理解语言设计哲学: 适应语言的设计哲学是高效开发的关键。Go语言在代码风格上的严格要求,是为了提高代码的可读性、可维护性和团队协作效率。

虽然个人喜好很重要,但在Go语言的生态系统中,遵循其既定的规范和工具,是实现高效、高质量代码开发的最佳路径。

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

400

2023.06.20

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

618

2023.07.25

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

354

2023.08.02

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

259

2023.08.09

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

603

2023.09.05

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

527

2023.09.20

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

645

2023.09.20

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

602

2023.09.22

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

25

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Rust 教程
Rust 教程

共28课时 | 4.8万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.8万人学习

Go 教程
Go 教程

共32课时 | 4.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号