Go 코딩 표준 세트를 공유하세요! 수집에 오신 것을 환영합니다!
최근 프로젝트에서 Go 언어 코드를 많이 검토했는데, 노트 기록이라고 할 수 있는 코드 사양을 요약할 필요가 있습니다.
앞서 언급했듯이 이는 우리 팀의 규범일 뿐입니다.
오늘 우리는 Go의 코딩 표준에 대해 이야기합니다. 이는 패키지 노트/변수/상수 이름 지정, 기본 구문, 함수, 오류 처리, 경험 등과 같은 여러 주요 모듈로 대략 구분됩니다. [추천: golang 튜토리얼]
1. 코드 스타일
1.1 코드 형식
- 코드 형식은 gofmt로 구성해야 합니다. 구성은 직접 검색할 수 있습니다.
- 우리가 작성하는 코드는 다음과 같습니다. 한 줄에 120자를 초과할 수 없으며, 초과하는 내용은 줄 바꿈으로 해결됩니다.
- 한 파일의 최대 줄 수는 800줄을 초과할 수 없습니다.
- 한 기능의 최대 줄 수는 80줄을 초과할 수 없습니다.
- 가져오기 사양
- 패키지를 소개하는 데 상대 경로를 사용하지 마세요. 예를 들어
import ../util/net
- 패키지를 가져올 때 여러 개의 동일한 패키지 이름이 충돌하는 경우 가져오기 별칭을 사용해야 합니다.
- 패키지를 소개하는 데 상대 경로를 사용하지 마세요. 예를 들어
// bad "github.com/google/uuid" // good uuid "github.com/google/uuid"
- 가져온 패키지는 다음을 사용하는 것이 좋습니다. 그룹화 및 참조 익명 패키지 나중에 친구들이 쉽게 읽을 수 있도록 새 그룹을 사용하고 주석을 추가하는 것이 좋습니다
import ( // Go 标准库 "fmt" //第三方包 "github.com/jinzhu/gorm" "github.com/google/uuid" "github.com/go-redis/redis/v8" // 匿名包 /import mysql driver _"github.com/jinzhu/gorm/dialects/mysql" // 内部包 slice "xxx.local/pkg/v1/goslice" meta "xxx.local/pkg/v1/meta" gomap "xxx.local/pkg/v2/gomap")
1.2 선언, 초기화 및 정의
- 함수가 여러 변수를 사용해야 하는 경우 var 선언을 사용할 수 있습니다. 함수 시작 부분에. 함수 외부에 선언된 변수는 사용할 수 없습니다:=, 이는 함정으로 이어질 수 있습니다. 모르는 경우 주석 영역에 메시지를 남겨도 됩니다(주석 작성이 쉽지 않습니다)!
var ( port = 8081 metricServerPort = 2001)
- 구조체 초기화 시 new(struct) 대신 &struct를 사용하여 구조 초기화와 일치하는지 확인하고, 구조 초기화 시 줄을 바꿉니다.
// bad stu := new(S) stu.Name = "张三" // good stu := &S{ Name:"李四" }
- 콘텐츠를 미리 할당할 수 있도록 맵, 배열 등을 선언할 때 make를 사용하여 컨테이너의 용량을 지정하세요.
users := make(map[int]string, 10)tags := make([]int, 0, 10)
- 표준 var 키워드를 사용하고 표현식의 유형과 다르지 않는 한 유형을 지정하지 마세요.
// bad var _f string F() func F() string { return "hello world!" } // good var _f F() func F() string { return "hello world!" }
1.3 오류 처리
- 함수가 오류를 반환하면 해당 오류를 처리해야 합니다. 비즈니스에서 허용하는 경우 _를 사용하여 이를 수락하고 무시할 수 있습니다. 해당 지연은 명시적 처리 없이 처리될 수 있습니다.
// bad func InitConfig() error { ... } InitConfig() // good func InitConfig() error { ... } err := InitConfig() if err != nil { ... } // or _ := InitConfig()
- error는 반환값으로 사용될 때 마지막 매개변수로 반환되어야 합니다.
// bad func InitConfig() (error,int) { ... } // good func InitConfig() (int, error) { ... }
- Error는 별도로 처리해야 하며 다른 로직과 결합되지 않도록 노력해야 합니다.
// bad res, err := InitConfig() if err != nil || res != nil { return err } // good res, err := InitConfig() if err != nil { return err } if res != nil { return fmt.Errorf("invalid result") }
1.4 패닉 처리
- 비즈니스 코드에서 패닉 오류를 발생시키는 것은 금지되어 있습니다.
- 패닉은 구성 읽기, 링크 저장(redis, mysql 등) 등 서비스가 시작되기 전에만 표시되도록 허용됩니다.
- 비즈니스 코드에서는 패닉 대신 에러를 사용하는 것이 좋습니다.
1.5 단위 테스트
- 중요 기능별로 테스트 케이스를 작성해야 하며, 코드 병합 시 모든 테스트가 자동으로 실행되어야 합니다.
- 파일 이름은 xxx_test.go입니다.
- 함수 이름을 지을 때 테스트 함수 이름을 사용하는 것이 좋습니다.
2. 명명 규칙
모든 언어에서 명명 규칙은 코드 사양에서 매우 중요합니다. 통일되고 정확한 명명은 코드의 가독성을 향상시킬 뿐만 아니라 사람들이 이 동지가 실제로 방법을 알고 있다는 느낌을 갖게 합니다. 그것을하기 위해. 황소!
2.1 包命名规范
- 包名必须与目录名一致(这和其他 php、Java 还是有一点不太一样的),尽量采取有意义、简短的包名,不要与 go 的标准库名称一样。
- 包名小写,没有下划线,可以使用中划线隔开,使用多级目录来划分目录。
- 包名不要出现复数命名。
- 包名命名尽量简单一目了然,ge:user、log。
2.2 文件命名规范
- 文件名要见名思义,尽量简而短
- 文件名小写,组合词用下划线分割
2.3 函数命名规范
- 与 php、Java 一样,必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 单元测试的函数用大驼峰,TestFunc。
2.4 结构体命名规范
- 与 php、Java 一样,必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 避免使用 info 、data 这种无意义的名称。
- 命名使用名词而非动词。
- 结构体在声明和初始化的时候需要换行,eg:
type Student struct{ Name string Age uint8}student := Student{ Name: "张三", Age: 18,}
2.5 变量命名规范
- 和 php、Java 一样,必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 若变量为私有时,可以使用小写命名。
- 局部变量可以简写,eg:i 表示 index。
- 若变量代表 bool 值,则可以使用 Is 、Can、Has 前缀命名,eg:
var isExit boolvar canReturn bool
2.6 常量命名规范
- 必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 若代表枚举值,需要先创建。
type Code intconst ( ErrNotFound Code = iota ErrFatal)
3. 类型
3.1 字符串
好像学过的语言中,都是从字符串开始说起的。就像写代码第一行都是从 Hello World!一样!同意的点赞哈。
- 字符串判空值
// bad if s == "" { ...} // good if len(s) == 0 { ...}
- 字符串去除前后子串。
// bad var s1 "hello world"var s2 "hello"var s3 strings.TrimPrefix(s1, s2) // good var s1 "hello world"var s2 "hello"var s3 stringif strings.HasPrefix(s1, s2){ s3 = s1[len(s2):]}
3.2 切片 slice
- 声明 slice。
// bad s := []string{}s := make([]string, 10) // good var s []string s := make([]string, 0, 10)
- 非空判断。
//bad if len(slice) >0 { ...} // good if slice != nil && len(slice) > 0 { ...}
- slice copy。
// badvar b1,b2 []bytefor i, v := range b1 { b2[i] = v}for i := range b1 { b2[i] = b1[i]}// goodcopy(b2,b1)
- slice 新增。
// bad var a,b []intfor _, v := range a { b = append(b,v)} // good var a, b []int b := append(b, a...)
3.4 结构体 struct
- 初始化需要多行。
type Student struct{ Name string Age uint8}student := Student{ Name: "张三", Age: 18,}
4. 控制语句
4.1 if
- if 可以用局部变量的方式初始化。
if err := InitConfig; err != nil { return err}
4.2 for
- 不允许在 for 中使用 defer, defer 只在函数结束时才会执行。
// bad for file := range files { fd, err := os.Open(file) if err != nil { return err } defer fd.close()} // good for file := range files{ func() { fd,err := os.open(file) if err!=nil { return err } defer fd.close() }()}
4.3 range
- 如果不需要 key 直接用 _ 忽略,value 也一样。
for _, v := range students { ...}for i, _ := range students { ...}for i, v := range students { ...}
注: 若操作指针时请注意不能直接用 s := v。想知道可以评论区告诉我哦!
4.4 switch
- 和其他语言不一样,必须要有 defalt
switch type { case 1: fmt.Println("type = 1") break case 2: fmt.Println("type = 2") break default : fmt.Println("unKnown type")}
4.5 goto
- 业务中不允许使用 goto。
- 框架和公共工具也不允许使用 goto。
5. 函数
- 传参和返回的变量小写字母。
- 传入参数时slice、map、interface、chan 禁止传递指针类型。
- 采用值传递,不用指针传值。
- 入参个数不能超出 5 个,超过的可以用 struct 传值。
5.1 函数参数
- 返回值超出 1 个时,需要用变量名返回。
- 多个返回值可以用 struct 传。
5.2 defer
- 当操作资源、或者事物需要提交回滚时,可以在创建开始下方就使用 defer 释放资源。
- 创建资源后判断 error,非 error 情况后在用 defer 释放。
5.3 代码嵌套
- 为了代码可读性,为了世界和平,尽量别用太多的嵌套,因为真的很难有人类能看懂。
6. 日常使用感悟
- 能不用全局变量就不用,可以用参数传值的方式,这样可以大大降低耦合,更有利于单元测试。
- 衣服开发中,在函数间多用 context 传递上下文,在请求开始时可以生成一个 request_id,便于链路、日志追踪。
6.1 提高性能
- 在业务开发中,尽量使用 strconv 来替代 fmt。
- 我们在使用 string 字符串类型时,当修改的场景较多,尽量在使用时用 []byte 来替代。因为每次对 string 的修改都需要重新在申请内存。
6.2 避免踩坑
- append 要小心自动扩容的情况,最好在申明时分配好容量,避免扩容所带来的性能上的损耗以及分配新的内存地址。若不能确定容量,应选择一个比较大一点的值。
- 并发场景下,map 非线程安全,需要加锁。还有一种评论区告诉我吧。
- interface 在编译期间无法被检查,使用上会出现 panic,需要注意
7. 总结
本篇很讲了 Go 语言的编码规范,当时想说的,规范是大家预定的东西,每个公司、团队都会有不一样的规范,只要大家一起遵循就好啦。你可以根据自己团队的需求,定一套属于自己团队的项目规范。如果想小伙伴一起遵循,可以借助一些工具来保障执行度。
讲了很多,虽然很基础,希望对于刚刚转 Go 语言,或者刚学习 Go 语言的同学有帮助吧。今天就到这里了。希望得到大家的一键三连。感谢!
本文系转载,原文链接:mp.weixin.qq.com/s/lfjP9DEia2WL4Ua...
위 내용은 Go 코딩 표준 세트를 공유하세요! 수집에 오신 것을 환영합니다!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Go에서는 안전하게 파일을 읽고 쓰는 것이 중요합니다. 지침은 다음과 같습니다. 파일 권한 확인 지연을 사용하여 파일 닫기 파일 경로 유효성 검사 컨텍스트 시간 초과 사용 다음 지침을 따르면 데이터 보안과 애플리케이션의 견고성이 보장됩니다.

Go 데이터베이스 연결을 위한 연결 풀링을 구성하는 방법은 무엇입니까? 데이터베이스 연결을 생성하려면 데이터베이스/sql 패키지의 DB 유형을 사용하고, 최대 동시 연결 수를 제어하려면 MaxIdleConns를 설정하고, 연결의 최대 수명 주기를 제어하려면 ConnMaxLifetime을 설정하세요.

Go 프레임워크는 높은 성능과 동시성 장점으로 인해 두각을 나타냅니다. 그러나 상대적으로 새로운 프레임워크, 작은 개발자 생태계, 일부 기능 부족 등 몇 가지 단점도 있습니다. 또한 빠른 변화와 학습 곡선은 프레임워크마다 다를 수 있습니다. Gin 프레임워크는 효율적인 라우팅, 내장된 JSON 지원 및 강력한 오류 처리로 인해 RESTful API를 구축하는 데 널리 사용됩니다.

GoLang 프레임워크와 Go 프레임워크의 차이점은 내부 아키텍처와 외부 기능에 반영됩니다. GoLang 프레임워크는 Go 표준 라이브러리를 기반으로 하며 기능을 확장하는 반면, Go 프레임워크는 특정 목적을 달성하기 위해 독립적인 라이브러리로 구성됩니다. GoLang 프레임워크는 더 유연하고 Go 프레임워크는 사용하기 더 쉽습니다. GoLang 프레임워크는 성능 면에서 약간의 이점이 있고 Go 프레임워크는 확장성이 더 좋습니다. 사례: gin-gonic(Go 프레임워크)은 REST API를 구축하는 데 사용되고 Echo(GoLang 프레임워크)는 웹 애플리케이션을 구축하는 데 사용됩니다.

모범 사례: 잘 정의된 오류 유형(오류 패키지)을 사용하여 사용자 정의 오류 생성 자세한 내용 제공 오류를 적절하게 기록 오류를 올바르게 전파하고 컨텍스트를 추가하기 위해 필요에 따라 오류를 숨기거나 억제하지 않음

JSON 데이터는 gjson 라이브러리 또는 json.Unmarshal 함수를 사용하여 MySQL 데이터베이스에 저장할 수 있습니다. gjson 라이브러리는 JSON 필드를 구문 분석하는 편리한 방법을 제공하며, json.Unmarshal 함수에는 JSON 데이터를 비정렬화하기 위한 대상 유형 포인터가 필요합니다. 두 방법 모두 SQL 문을 준비하고 삽입 작업을 수행하여 데이터를 데이터베이스에 유지해야 합니다.

Go 프레임워크에서 일반적인 보안 문제를 해결하는 방법 웹 개발에서 Go 프레임워크가 널리 채택됨에 따라 보안을 보장하는 것이 중요해졌습니다. 다음은 샘플 코드를 통해 일반적인 보안 문제를 해결하기 위한 실용적인 가이드입니다. 1. SQL 주입 SQL 주입 공격을 방지하려면 준비된 문이나 매개변수화된 쿼리를 사용하세요. 예: constquery="SELECT*FROMusersWHEREusername=?"stmt,err:=db.Prepare(query)iferr!=nil{//Handleerror}err=stmt.QueryR

FindStringSubmatch 함수는 정규 표현식과 일치하는 첫 번째 하위 문자열을 찾습니다. 이 함수는 일치하는 하위 문자열이 포함된 조각을 반환합니다. 첫 번째 요소는 전체 일치 문자열이고 후속 요소는 개별 하위 문자열입니다. 코드 예: regexp.FindStringSubmatch(text,pattern)는 일치하는 하위 문자열의 조각을 반환합니다. 실제 사례: 이메일 주소의 도메인 이름을 일치시키는 데 사용할 수 있습니다. 예를 들어 이메일:="user@example.com", 패턴:=@([^\s]+)$를 사용하여 도메인 이름 일치를 가져옵니다. [1].
