최근 새로운 시도 제안 "제안: Go 2: 오류 처리: try 문 with handler[1]"이 커뮤니티에서 열띤 토론을 촉발했습니다. 다시 커뮤니티에 맞서 싸우자! ! !
오늘 Jianyu는 Go 오류 처리 메커니즘을 공개하고 재구성할 수 있는지 확인하기 위해 모든 사람과 함께 공개할 것입니다.
Background
PingCAP의 제안 작성자 @Greg Weber는 두 가지 요소를 기반으로 이를 수행합니다. 하나는 "Go 개발자 설문조사 2022 Q2 결과[2]"에 명확하게 언급되어 있습니다.

Go1.18 제네릭 출시와 함께 원래 가장 모순된 제네릭이 예비 솔루션을 받았습니다. 커뮤니티 설문조사에 따르면 Go를 사용할 때 개발자가 직면하는 가장 큰 과제는 오류 처리로 바뀌었고 이를 "해결"하려면 에너지를 투자해야 합니다.
또 다른 요인은 Go 오류 처리 코드가 상대적으로 번거롭다는 것이 잘 알려져 있다는 것입니다. 엔지니어들은 종종 Go 프로젝트의 30%가 err = nil이라고 농담합니다.
다음 코드는
_, err := f() if err != nil { ... } _, err = r() if err != nil { ... } _, err = w() if err != nil { ... }
좀 더 우아하게 만들어주셨으면 좋겠습니다. 많은 친구들도 이 디자인에 동의합니다. 이는 실제로 커뮤니티에서 투쟁을 형성한 간단하고 직관적인 처리입니다.
try-handler 제안
이 제안에서 언급된 솔루션은 간결한 오류 처리를 달성하고 if err != nil 처리를 원활하게 만들기 위해 새로운 문을 추가하는 것입니다.
다음 코드:
try err, handler
컴파일러에 의해 생성된 코드:
if err != nil { return handler(err) }
함수에서는 다음과 같을 수 있습니다.
func(args...) (rtype1, rtypes..., rtypeN, error) { try err, handler ... }
번역 후 생성된 코드:
func(args...) (rtype1, rtypes..., rtypeN, error) { if err != nil { return Zero(rtype1), Zeros(rtypes...)..., Zero(rtypeN), handler(err) } ... }
또한 err인 경우에만 처리할 수 있습니다. != 없음. 다음 코드:
try err
번역된 코드:
if err != nil { return err }
는 처리를 위해 존재하지 않는 핸들러를 호출하지 않고 직접 반환합니다. 세 줄(if err != nil의 논리)이 직접 3단어(try)로 변경됩니다.
함수를 작성하고 싶지 않다면 직접 작성할 수도 있습니다.
x, err := f() try err, fmt.Errorf("f fail: %w", err)
defer+try 시나리오는 다음과 같습니다.
func CopyFile(src, dst string) error { defer try func(err error) error { return fmt.Errorf("copy %s %s: %w", src, dst, err) } ... }
입력 매개변수는 더 유연하기를 바랍니다. 다양한 시나리오의 요구 사항에 적응할 수 있다는 것입니다.
示例和实践
针对本提案,原作者给出了各类使用场景的示例。如下代码:
import ( "fmt" ) // This helper should be defined in the fmt package func Handlew(format string, args ...any) func(error) error { return func(err error) error { args = append(args, err) return fmt.Errorf(format+": %w", args...) } } // This helper should be defined in the fmt package func Handlef(format string, args ...any) func(error) error { return func(err error) error { args = append(args, err) return fmt.Errorf(format+": %v", args...) } } func valAndError() (int, error) { return 1, fmt.Errorf("make error") } func newGo() (int, error) { x, err := valAndError() try err // Common formatting functions will already be provided i := 2 x, err = valAndError() try err, Handlew("custom Error %d", i) // Using a custom error type // For convenience the error type can expose a method to set the error x, err = valAndError() try err, TheErrorAsHandler(i) } type TheError struct{ num int err error } func (t TheError) Error() String { return fmt.Sprintf("theError %d %v", t.num, t.err) } func TheErrorAsHandler(num int) func(err) TheError { return func(err error) TheError { return theError{ num: i, err: err } } }
另外在日常的 Go 工程中,提案作者认为 CopyFile 函数是新提案语句的一种很好的实践。为此基于 try-handler 进行了一版改造和说明。
如下代码:
// This helper can be used with defer func handle(err *error, handler func(err error) error) { if err == nil { return nil } *err = handler(err) } func CopyFile(src, dst string) (err error) { defer handle(&err, func(err error) error { return fmt.Errorf("copy %s %s: %w", src, dst, err) }) r, err := os.Open(src) try err defer r.Close() w, err := os.Create(dst) try err, func(err error) error { os.Remove(dst) // only if Create fails return fmt.Errorf("dir %s: %w", dst, err) } defer w.Close() err = io.Copy(w, r) try err err = w.Close() try err return nil }
引入 try-hanlder 后,能够做到:
插入错误的返回语句,进行机制预设。 在返回错误之前将错误处理函数组合在一起,便于后续的处理。
总结
在这个新提案中,一旦实施,就可以减少如下代码的编写:
if err != nil { return ... }
在代码编写上会节省一些行数,且可以为错误处理机制引入一些新的 ”操作“,这是该提案的优势。
但是从 Go 开发者的角度而言,会引入一些新的副作用,例如:初学者的学习成本、Go 工具链的改造、程序理解的复杂度增加。
另外新的语句,似乎比较难与 Go1.13 引入的 error.Is 和 As 有较好的相关联性。如果是做一个第三方用户库引入倒可以,但若是作为标准进入 Go 源代码中,似乎又有些格格不入(提案作者希望进入)。
看了那么多提案,Go 错误处理机制的 ”升级“,似乎陷入了手心手背都是肉的阶段...
위 내용은 가서 시도해 보세요. 새로운 제안은 신뢰할 수 있나요? 오류 처리를 단순화하고 싶음의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

go语言有缩进。在go语言中,缩进直接使用gofmt工具格式化即可(gofmt使用tab进行缩进);gofmt工具会以标准样式的缩进和垂直对齐方式对源代码进行格式化,甚至必要情况下注释也会重新格式化。

本篇文章带大家了解一下golang 的几种常用的基本数据类型,如整型,浮点型,字符,字符串,布尔型等,并介绍了一些常用的类型转换操作。

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。 换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。 闭包会随着函数的创建而被同时创建。

go语言叫go的原因:想表达这门语言的运行速度、开发速度、学习速度(develop)都像gopher一样快。gopher是一种生活在加拿大的小动物,go的吉祥物就是这个小动物,它的中文名叫做囊地鼠,它们最大的特点就是挖洞速度特别快,当然可能不止是挖洞啦。

是,TiDB采用go语言编写。TiDB是一个分布式NewSQL数据库;它支持水平弹性扩展、ACID事务、标准SQL、MySQL语法和MySQL协议,具有数据强一致的高可用特性。TiDB架构中的PD储存了集群的元信息,如key在哪个TiKV节点;PD还负责集群的负载均衡以及数据分片等。PD通过内嵌etcd来支持数据分布和容错;PD采用go语言编写。

在写 Go 的过程中经常对比这两种语言的特性,踩了不少坑,也发现了不少有意思的地方,下面本篇就来聊聊 Go 自带的 HttpClient 的超时机制,希望对大家有所帮助。


핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

PhpStorm 맥 버전
최신(2018.2.1) 전문 PHP 통합 개발 도구

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

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

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