Go: 제안: Go 2: ||륌 사용하여 였류 처늬 닚순화 였류 접믞사

에 만든 2017년 07월 25음  Â·  519윔멘튞  Â·  출처: golang/go

Go에서 였류 처늬륌 닚순화하는 방법에 대한 많은 제안읎 있었습니닀. 몚두 Go 윔드에 행읎 너묎 많읎 포핚되얎 있닀는 음반적읞 불만을 Ʞ반윌로 합니닀.

if err != nil {
    return err
}

여Ʞ에 í•Žê²°í•Žì•Œ 할 묞제가 있는지 잘 몚륎겠지만 계속핎서 묞제가 발생하Ʞ 때묞에 읎 아읎디얎륌 낎놓습니닀.

였류 처늬륌 닚순화하Ʞ 위한 대부분의 제안의 핵심 묞제 쀑 하나는 였류륌 처늬하는 두 가지 방법만 닚순화하지만 싀제로는 ì„ž 가지가 있닀는 것입니닀.

  1. 였류륌 묎시
  2. 수정되지 않은 였류륌 반환
  3. 추가 컚텍슀튞 정볎와 핚께 였류 반환

였류륌 묎시하는 것은 읎믞 쉜습니닀(아마도 너묎 쉜습니닀)(#20803 ì°žì¡°). 였류 처늬에 대한 많은 êž°ì¡Ž 제안은 수정되지 않은 였류륌 반환하는 것을 더 쉜게 만듭니닀(예: #16225, #18721, #21146, #21155). 추가 정볎와 핚께 였류륌 더 쉜게 반환할 수 있는 사람은 거의 없습니닀.

읎 제안은 ì–žì–Ž 아읎디얎의 풍부한 소슀읞 Perl 및 Bourne ì…ž 얞얎에 느슚하게 Ʞ반을 두고 있습니닀. 표현식 명령묞곌 유사한 새로욎 종류의 명령묞을 소개합니닀. || 뒀따륎는 혞출 표현식입니닀. 묞법은 닀음곌 같습니닀.

PrimaryExpr Arguments "||" Expression

유사하게 우늬는 새로욎 종류의 할당묞을 소개합니닀:

ExpressionList assign_op PrimaryExpr Arguments "||" Expression

묞법은 할당되지 않은 겜우 || 읎후의 몚든 유형을 허용하지만 유음하게 허용되는 유형은 믞늬 선얞된 유형 error 입니닀. || 닀음에 였는 표현식에는 error 할당할 수 있는 유형읎 있얎알 합니닀. 부욞 유형읎 아닐 수도 있고 error 할당할 수 있는 명명된 부욞 유형도 아닐 수 있습니닀. (읎 후자의 제한은 읎 제안읎 êž°ì¡Ž 얞얎와 역혞환되도록 하Ʞ 위핎 필요합니닀.)

읎러한 새로욎 종류의 명령묞은 하나 읎상의 결곌 맀개변수가 있는 핚수의 볞묞에서만 허용되며 마지막 결곌 맀개변수의 유형은 믞늬 선얞된 유형 error 읎얎알 합니닀. 혞출되는 핚수에는 유사하게 하나 읎상의 결곌 맀개변수가 있얎알 하고 마지막 결곌 맀개변수의 유형은 믞늬 선얞된 유형 error 읎얎알 합니닀.

읎러한 명령묞을 싀행할 때 혞출 표현식은 평소와 같읎 평가됩니닀. 할당묞읞 겜우 혞출 결곌는 평소와 같읎 왌쪜 플연산자에 할당됩니닀. 귞런 닀음 위에서 섀명한 대로 error 유형읎얎알 하는 마지막 혞출 결곌가 nil 와 비교됩니닀. 마지막 혞출 결곌가 nil 가 아니멎 return 묞읎 암시적윌로 싀행됩니닀. 혞출하는 핚수에 여러 결곌가 있는 겜우 마지막 결곌륌 제왞한 몚든 결곌에 대핮 0 값읎 반환됩니닀. || 뒀에 였는 표현식읎 마지막 결곌로 반환됩니닀. 위에서 섀명한 것처럌 혞출 핚수의 마지막 결곌는 error 유형읎얎알 하고 표현식은 error 유형에 할당할 수 있얎알 합니닀.

할당되지 않은 겜우 표현식은 새 변수 err 가 도입되고 핚수 혞출의 마지막 결곌 값윌로 섀정되는 범위에서 평가됩니닀. 읎렇게 하멎 표현식읎 혞출에서 반환된 였류륌 쉜게 ì°žì¡°í•  수 있습니닀. 할당의 겜우 혞출 결곌의 범위 낎에서 표현식을 평가하므로 였류륌 직접 ì°žì¡°í•  수 있습니닀.

귞것읎 완전한 제안입니닀.

예륌 듀얎 os.Chdir 핚수는 현재

func Chdir(dir string) error {
    if e := syscall.Chdir(dir); e != nil {
        return &PathError{"chdir", dir, e}
    }
    return nil
}

읎 제안에 따띌 닀음곌 같읎 작성할 수 있습니닀.

func Chdir(dir string) error {
    syscall.Chdir(dir) || &PathError{"chdir", dir, err}
    return nil
}

나는 죌로 Go 였류 처늬륌 닚순화하렀는 사람듀읎 수정되지 않은 였류륌 반환하는 것읎 아니띌 였류 죌위에 컚텍슀튞륌 쉜게 감쌀 수 있는 방법에 대핮 생각하도록 권장하Ʞ 위핎 읎 제안을 작성합니닀.

FrozenDueToAge Go2 LanguageChange NeedsInvestigation Proposal error-handling

가장 유용한 댓Ꞁ

였류 장식을 지원하지만 더 곌감한 ì–žì–Ž 변겜(go1.10은 아님)읎 필요한 닚순한 아읎디얎는 새로욎 check 킀워드의 도입입니닀.

check A 및 check A, B 두 가지 형식읎 있습니닀.

A 및 B 는 몚두 error 여알 합니닀. 두 번짞 형식은 였류륌 장식할 때만 사용됩니닀. 자신의 였류륌 장식할 필요가 없거나 ꟞믞고 싶지 않은 사람듀은 더 ê°„ë‹ší•œ 형식을 사용합니닀.

첫 번짞 양식(A 첎크)

check A 는 A 평가합니닀. nil 읎멎 아묎 작업도 수행하지 않습니닀. nil 아니멎 check 는 return {<zero>}*, A 처럌 작동합니닀.

예

  • 핚수가 였류륌 반환하멎 check 읞띌읞윌로 사용할 수 있윌므로
err := UpdateDB()    // signature: func UpdateDb() error
if err != nil {
    return err
}

된닀

check UpdateDB()
  • 여러 반환 값읎 있는 핚수의 겜우 지ꞈ처럌 할당핎알 합니닀.
a, b, err := Foo()    // signature: func Foo() (string, string, error)
if err != nil {
    return "", "", err
}

// use a and b

된닀

a, b, err := Foo()
check err

// use a and b

두 번짞 형식(A, B 첎크)

check A, B 는 A 평가합니닀. nil 읎멎 아묎 작업도 수행하지 않습니닀. nil 아니멎 check 는 return {<zero>}*, B 처럌 작동합니닀.

읎것은 였류 장식을 위한 것입니닀. 우늬는 여전히 확읞 A , 귞러나입니닀 B 암시 적윌로 사용되는 return .

예시

a, err := Bar()    // signature: func Bar() (string, error)
if err != nil {
    return "", &BarError{"Bar", err}
}

된닀

a, err := Foo()
check err, &BarError{"Bar", err}

녾튾

컎파음 였류입니닀

  • error 평가되지 않는 항목에 check 묞 사용
  • { type }*, error 형식읎 아닌 반환 값읎 있는 핚수에서 check { type }*, error

두 개의 expr 형식 check A, B 읎 닚띜되었습니닀. B A 가 nil 읎멎 B 는 평가되지 않습니닀.

싀용성에 대한 ì°žê³  사항

였류 ꟞믞Ʞ에 대한 지원읎 있지만 싀제로 였류륌 장식핎알 할 때만 더 복잡한 check A, B 구묞에 대핮 비용을 지불합니닀.

if err != nil { return nil, nil, err } 상용구( 맀우 음반적임)의 겜우 check err 는 명확성을 희생하지 않고 가능한 한 간닚합니닀(아래 구묞에 대한 ì°žê³  ì°žì¡°).

구묞에 대한 ì°žê³  사항

읎런 종류의 구묞( check .. , 쀄 시작 부분에 return 와 유사)읎 제얎 흐멄 쀑닚을 숚Ʞ지 않고 상용구 검사 였류륌 제거하는 좋은 방법읎띌고 죌장합니닀. 암시적 반환읎 도입되었습니닀.

위의 <do-stuff> || <handle-err> 및 <do-stuff> catch <handle-err> 또는 닀륞 슀레드에서 제안된 a, b = foo()? 와 같은 아읎디얎의 닚점은 흐늄을 얎렵게 만드는 방식윌로 제얎 흐멄 수정을 숚ꞎ닀는 것입니닀. 따륎닀; 전자는 평범핎 볎읎는 쀄 끝에 || <handle-err> Ʞ계가 추가 되고, 후자는 평범한 윔드 쀄의 쀑간 곌 끝 을 포핚하여 몚든 곳에 나타날 수 있는 작은 Ʞ혞가 있습니닀. 아마도 여러 번.

check 묞은 현재 랔록에서 항상 최상위 수쀀읎 되며 제얎 흐늄을 수정하는 닀륞 묞(예: 쎈Ʞ return )곌 동음한 쀑요성을 갖습니닀.

몚든 519 댓Ꞁ

    syscall.Chdir(dir) || &PathError{"chdir", dir, e}

e 얎디에서 왔습니까? 였식?

또는 닀음을 의믞했나요?

func Chdir(dir string) (e error) {
    syscall.Chdir(dir) || &PathError{"chdir", dir, e}
    return nil
}

(슉, 암시적 err != nil 검사가 뚌저 결곌 맀개변수에 였류륌 할당하고 암시적 반환 전에 닀시 수정하도록 읎늄을 지정할 수 있습니까?)

한숚, 낮 자신의 예륌 망쳀습니닀. 읎제 수정되었습니닀: e 는 err 읎얎알 합니닀. 제안은 err 륌 대입묞에 없을 때 핚수 혞출의 였류 값을 유지하Ʞ 위핎 범위에 넣습니닀.

아읎디얎나 구묞에 동의하는지 확싀하지 않지만 였류륌 반환하Ʞ 전에 였류에 컚텍슀튞륌 추가하는 데 죌의륌 Ʞ욞읞 점을 읞정핎알 합니닀.

읎것은 https://github.com/pkg/errors 륌 작성한 @davecheney 에게 .

읎 윔드에서 음얎나는 음:

if foo, err := thing.Nope() || &PathError{"chdir", dir, err}; err == nil || ignoreError {
}

( || &PathError{"chdir", dir, e} 부분읎 없얎도 읎것읎 가능하지 않닀멎 사곌드늜니닀. 저는 읎것읎 êž°ì¡Ž 동작을 혌란슀럜게 재정의하는 것처럌 느껎지고 암시적 반환읎... 교활하닀고 표현하렀고 합니닀.)

@object88 if 및 for 및 switch 묞에서 사용되는 SimpleStmt에서 읎 새로욎 겜우륌 허용하지 않는 것읎 좋습니닀. 묞법읎 앜간 복잡핎지ꞎ 하지만 귞게 최선음 것입니닀.

하지만 귞렇게 하지 않윌멎 thing.Nope() 가 nil읎 아닌 였류륌 반환하멎 혞출 핚수가 &PathError{"chdir", dir, err} 와 핚께 반환됩니닀(여Ʞ서 err 는 thing.Nope() 혞출에 의핎 섀정된 변수). thing.Nope() 가 nil 였류륌 반환하멎 if 묞의 조걎에서 err == nil 가 찞임을 확싀히 알고 있윌므로 볞묞 if 묞읎 싀행됩니닀. ignoreError 변수는 읜지 않습니닀. 여Ʞ에는 êž°ì¡Ž 동작에 대한 몚혞성읎나 재정의가 없습니닀. 의 처늬 || 후 표현하멎 여Ʞ에서 소개에만 허용됩니닀 || 읎 현재 컎파음되지 것을 의믞 부욞 값읎 아닙니닀.

나는 암시적 반환읎 교활하닀는 데 동의합니닀.

예, 제 예는 맀우 좋지 않습니닀. 귞러나 if , for 또는 switch 낎부의 작업을 허용하지 않윌멎 많은 잠재적읞 혌란읎 핎결됩니닀.

고렀핎알 할 바는 음반적윌로 얞얎에서 귞대로 하Ʞ 얎렀욎 것읎Ʞ 때묞에 읎 변형읎 ì–žì–Žë¡œ 읞윔딩하는 것읎 얌마나 얎렀욎지 확읞하Ʞ로 결정했습니닀. 닀륞 것볎닀 얎렵지 않습니닀: https://play.golang.org/p/9B3Sr7kj39

나는 한 가지 유형의 값곌 반환 읞수의 한 위치륌 특별하게 만듀Ʞ 위한 읎러한 몚든 제안을 정말 싫얎합니닀. 읎것은 읎 특정 컚텍슀튞에서 err 륌 특별한 읎늄윌로 만듀Ʞ 때묞에 ì–Žë–€ 멎에서는 싀제로 더 나쁩니닀.

나는 확싀히 사람듀(저륌 포핚하여!)읎 추가 컚텍슀튞 없읎 였류륌 반환하는 데 지쳐알 한닀는 데 동의합니닀.

닀음곌 같은 닀륞 반환 값읎 있는 겜우

if err != nil {
  return 0, nil, "", Struct{}, wrap(err)
}

확싀히 읜Ʞ 지룚할 수 있습니닀. https://github.com/golang/go/issues/19642#issuecomment -288559297에서 return ..., err 에 대한 @nigeltao 의 제안읎 닀소 마음에 듀었습니닀.

ë‚Žê°€ 올바륎게 읎핎한닀멎 구묞 튞늬륌 구축하렀멎 파서는

boolean := BoolFunc() || BoolExpr

귞늬고

err := FuncReturningError() || Expr

좋지 않아 볎읞닀.

적은 것읎 더 ...

반환되는 ExpressionList에 두 개 읎상의 요소가 포핚되얎 있윌멎 얎떻게 작동합니까?

BTW, 나는 대신 panicIf륌 원합니닀.

err := doSomeThing()
panicIf(err)

err = doAnotherThing()
panicIf(err)

@ianlancetaylor 제안서의 예에서 err 는 여전히 명시적윌로 선얞되지 않고 '마법 같은'(ì–žì–Ž 사전 정의)윌로 당겚집니닀. 맞습니까?

아니멎 닀음곌 같을 것읞가

func Chdir(dir string) error {
    return (err := syscall.Chdir(dir)) || &PathError{"chdir", dir, err}
}

?

반멎에 (읎믞 "ì–žì–Ž 변겜"윌로 표시되얎 있Ʞ 때묞에 ...)
였류 != nil(또는 nullable?)에 대한 바로 가Ʞ륌 수행하는 새 연산자(!! 또는 ??)륌 도입합니닀.

func DirCh(dir string) (string, error) {
    return dir, (err := syscall.Chdir(dir)) !! &PathError{"chdir", dir, err}
}

너묎 멀었닀멎 죄송합니닀 :)

Go에서 였류 처늬가 반복될 수 있닀는 데 동의합니닀. 나는 반복에 신겜 쓰지 않지만 너묎 많은 반복은 가독성에 영향을 믞칩니닀. "Cyclomatic Complexity"(믿든 말든)가 제얎 흐늄을 복잡성에 대한 척도로 사용하는 읎유가 있습니닀. "if" 묞은 추가 녞읎슈륌 추가합니닀.

귞러나 제안된 구묞 "||" 특히 Ʞ혞가 음반적윌로 OR 연산자로 알렀젞 있Ʞ 때묞에 읜Ʞ가 맀우 직ꎀ적읎지 않습니닀. 또한 여러 값곌 였류륌 반환하는 핚수륌 얎떻게 처늬합니까?

나는 여Ʞ에 몇 가지 아읎디얎륌 던지고 있습니닀. 였류륌 출력윌로 사용하는 대신 였류륌 입력윌로 사용하는 것은 얎떻습니까? 예: https://play.golang.org/p/rtfoCIMGAb

몚든 의견에 감사드늜니닀.

@opennota 좋은 지적입니닀. 여전히 작동할 수 있지만 ê·ž 잡멎읎 얎색하닀는 데 동의합니닀.

@mattn 반환 ExpressionList가 없닀고 생각하므로 묎엇을 묻는지 잘 몚륎겠습니닀. 혞출 핚수에 여러 결곌가 있는 겜우 마지막을 제왞한 몚든 결곌가 유형의 0 값윌로 반환됩니닀.

@mattn panicif 는 읎 제안의 핵심 요소 쀑 하나륌 닀룚지 않습니닀. 읎는 추가 컚텍슀튞와 핚께 였류륌 반환하는 쉬욎 방법입니닀. 귞늬고 묌론 였늘날에도 충분히 쉜게 panicif ì“ž 수 있습니닀.

@tandr 예, err 는 마법처럌 정의되얎 있습니닀. 읎것은 맀우 끔찍합니닀. 또 닀륞 가능성은 error-expression읎 error 륌 사용하여 였류륌 찞조하도록 허용하는 것입니닀. 읎는 닀륞 방식윌로 끔찍합니닀.

@tandr 닀륞 연산자륌 사용할 수 있지만 큰 읎점은 없습니닀. 결곌륌 더 읜Ʞ 쉜게 만듀지 않는 것 같습니닀.

@henryas 제 생각에는 제안서가 여러 결곌륌 처늬하는 방법을 섀명한닀고 생각합니닀.

@henryas 예륌 듀얎 죌셔서 감사합니닀. 귞런 종류의 ì ‘ê·Œ 방식에 대핮 ë‚Žê°€ 싫얎하는 것은 였류 처늬륌 윔드의 가장 두드러진 잡멎윌로 만든닀는 것입니닀. 였류 처늬가 표시되고 표시되Ʞ륌 원하지만 쀄의 첫 번짞 항목읎 되는 것은 원하지 않습니닀. 읎것은 였늘날 if err != nil ꎀ용구와 였류 처늬 윔드의 듀여쓰Ʞ와 핚께 사싀읎며 였류 처늬륌 위핎 새로욎 Ʞ능읎 추가되는 겜우에도 사싀로 유지되얎알 합니닀.

닀시 한번 감사합니닀.

@ianlancetaylor 낮 놀읎터 링크륌 확읞했는지 몚륎겠지만 추가 컚텍슀튞륌 추가할 수 있는 "panicIf"가 있습니닀.

여Ʞ에서 닀소 닚순화된 버전을 재현하겠습니닀.

func panicIf(err error, transforms ...func(error) error) {
  if err == nil {
    return
  }
  for _, transform := range transforms {
    err = transform(err)
  }
  panic(err)
}

공교롭게도 저는 방ꞈ GopherCon 에서 였류 처늬 윔드륌 시각화하는 데 도움읎 되는 앜간의 구묞을 사용(심각하게 제안하지는 않았지만)했습니닀. 아읎디얎는 윔드륌 닚축하Ʞ 위한 마술에 의졎하지 않고 핎당 윔드륌 옆에 두얎 죌요 흐늄을 방핎하지 않도록 하는 것입니닀. 결곌는 닀음곌 같습니닀.

func DirCh(dir string) (string, error) {
    dir := syscall.Chdir(dir)        =: err; if err != nil { return "", err }
}

여Ʞ서 =: 는 구묞의 새로욎 비튞읎며 닀륞 방향윌로 할당하는 := 의 믞러입니닀. 분명히 우늬는 = 에도 묎얞가가 필요합니닀. 읎것은 분명히 묞제가 있습니닀. 귞러나 음반적읞 아읎디얎는 정볎륌 잃지 않고 독자가 행복한 Ꞟ을 더 쉜게 읎핎할 수 있도록 하는 것입니닀.

반멎에, 현재의 였류 처늬 방식은 닚음 Ʞ능에서 너묎 많은 음을 하고 있을 수 있고 음부 늬팩토링읎 지연될 수 있음을 눈부신 알늌 역할을 한닀는 점에서 몇 가지 장점읎 있습니닀.

@billyh가 제안한 구묞읎 정말 마음에 .

func Chdir(dir string) error {
    e := syscall.Chdir(dir) catch: &PathError{"chdir", dir, e}
    return nil
}

또는 https://github.com/pkg/errors 륌 사용하는 더 복잡한 예

func parse(input io.Reader) (*point, error) {
    var p point

    err := read(&p.Longitude) catch: nil, errors.Wrap(err, "Failed to read longitude")
    err = read(&p.Latitude) catch: nil, errors.Wrap(err, "Failed to read Latitude")
    err = read(&p.Distance) catch: nil, errors.Wrap(err, "Failed to read Distance")
    err = read(&p.ElevationGain) catch: nil, errors.Wrap(err, "Failed to read ElevationGain")
    err = read(&p.ElevationLoss) catch: nil, errors.Wrap(err, "Failed to read ElevationLoss")

    return &p, nil
}

였류 장식을 지원하지만 더 곌감한 ì–žì–Ž 변겜(go1.10은 아님)읎 필요한 닚순한 아읎디얎는 새로욎 check 킀워드의 도입입니닀.

check A 및 check A, B 두 가지 형식읎 있습니닀.

A 및 B 는 몚두 error 여알 합니닀. 두 번짞 형식은 였류륌 장식할 때만 사용됩니닀. 자신의 였류륌 장식할 필요가 없거나 ꟞믞고 싶지 않은 사람듀은 더 ê°„ë‹ší•œ 형식을 사용합니닀.

첫 번짞 양식(A 첎크)

check A 는 A 평가합니닀. nil 읎멎 아묎 작업도 수행하지 않습니닀. nil 아니멎 check 는 return {<zero>}*, A 처럌 작동합니닀.

예

  • 핚수가 였류륌 반환하멎 check 읞띌읞윌로 사용할 수 있윌므로
err := UpdateDB()    // signature: func UpdateDb() error
if err != nil {
    return err
}

된닀

check UpdateDB()
  • 여러 반환 값읎 있는 핚수의 겜우 지ꞈ처럌 할당핎알 합니닀.
a, b, err := Foo()    // signature: func Foo() (string, string, error)
if err != nil {
    return "", "", err
}

// use a and b

된닀

a, b, err := Foo()
check err

// use a and b

두 번짞 형식(A, B 첎크)

check A, B 는 A 평가합니닀. nil 읎멎 아묎 작업도 수행하지 않습니닀. nil 아니멎 check 는 return {<zero>}*, B 처럌 작동합니닀.

읎것은 였류 장식을 위한 것입니닀. 우늬는 여전히 확읞 A , 귞러나입니닀 B 암시 적윌로 사용되는 return .

예시

a, err := Bar()    // signature: func Bar() (string, error)
if err != nil {
    return "", &BarError{"Bar", err}
}

된닀

a, err := Foo()
check err, &BarError{"Bar", err}

녾튾

컎파음 였류입니닀

  • error 평가되지 않는 항목에 check 묞 사용
  • { type }*, error 형식읎 아닌 반환 값읎 있는 핚수에서 check { type }*, error

두 개의 expr 형식 check A, B 읎 닚띜되었습니닀. B A 가 nil 읎멎 B 는 평가되지 않습니닀.

싀용성에 대한 ì°žê³  사항

였류 ꟞믞Ʞ에 대한 지원읎 있지만 싀제로 였류륌 장식핎알 할 때만 더 복잡한 check A, B 구묞에 대핮 비용을 지불합니닀.

if err != nil { return nil, nil, err } 상용구( 맀우 음반적임)의 겜우 check err 는 명확성을 희생하지 않고 가능한 한 간닚합니닀(아래 구묞에 대한 ì°žê³  ì°žì¡°).

구묞에 대한 ì°žê³  사항

읎런 종류의 구묞( check .. , 쀄 시작 부분에 return 와 유사)읎 제얎 흐멄 쀑닚을 숚Ʞ지 않고 상용구 검사 였류륌 제거하는 좋은 방법읎띌고 죌장합니닀. 암시적 반환읎 도입되었습니닀.

위의 <do-stuff> || <handle-err> 및 <do-stuff> catch <handle-err> 또는 닀륞 슀레드에서 제안된 a, b = foo()? 와 같은 아읎디얎의 닚점은 흐늄을 얎렵게 만드는 방식윌로 제얎 흐멄 수정을 숚ꞎ닀는 것입니닀. 따륎닀; 전자는 평범핎 볎읎는 쀄 끝에 || <handle-err> Ʞ계가 추가 되고, 후자는 평범한 윔드 쀄의 쀑간 곌 끝 을 포핚하여 몚든 곳에 나타날 수 있는 작은 Ʞ혞가 있습니닀. 아마도 여러 번.

check 묞은 현재 랔록에서 항상 최상위 수쀀읎 되며 제얎 흐늄을 수정하는 닀륞 묞(예: 쎈Ʞ return )곌 동음한 쀑요성을 갖습니닀.

@ALTree , 귀하의 예륌 읎핎하지 못했습니닀.

a, b, err := Foo()
check err

원볞에서 ì„ž 가지 가치 있는 수익을 달성합니닀.

return "", "", err

최종 였류륌 제왞하고 선얞된 몚든 반환값에 대핮 0 값만 반환합니까? 였류와 핚께 유횚한 값을 반환하렀는 겜우(예: Write()가 싀팚할 때 작성된 바읎튞 수)는 얎떻습니까?

ì–Žë–€ 솔룚션을 사용하든 였류 처늬의 음반성을 최소한윌로 제한핎알 합니닀.

쀄의 시작 부분에 check 있는 값곌 ꎀ렚하여 낮 개읞적읞 선혞는 각 쀄의 시작 부분에서 Ʞ볞 제얎 흐늄을 볎고 였류 처늬가 Ʞ볞 제얎 흐늄의 가독성을 최소한윌로 방핎하도록 하는 것입니닀. 가능한 한. 또한 였류 처늬가 check 또는 catch 와 같은 예앜얎로 구분되얎 있윌멎 거의 몚든 최신 펞집Ʞ에서 예앜얎 구묞을 ì–Žë–€ 식윌로든 강조 표시하고 눈에 띄게 만듀 것입니닀. 였륞쪜에 있닀멎.

@billyh 읎것은 위에서 닀음곌 같은 쀄에 섀명되얎 있습니닀.

nil읎 아닌 겜우 check는 return {<zero>}*, A 처럌 작동합니닀.

check 는 였류(마지막 위치)륌 제왞한 몚든 반환 값의 0 값을 반환합니닀.

였류와 핚께 유횚한 값을 반환하렀는 겜우는 얎떻습니까?

귞런 닀음 if err != nil { ꎀ용구륌 사용합니닀.

볎닀 정교한 였류 복구 절찚가 필요한 겜우가 많습니닀. 예륌 듀얎 였류륌 포착한 후 묎얞가륌 례백하거나 로귞 파음에 Ʞ록핎알 할 수 있습니닀. 읎 몚든 겜우에 도구 상자에 여전히 음반적읞 if err ꎀ용구가 있윌며 읎륌 사용하여 새 랔록을 시작할 수 있습니닀. 싀시한닀.

ì–Žë–€ 솔룚션을 사용하든 였류 처늬의 음반성을 최소한윌로 제한핎알 합니닀.

위의 낮 대답을 찞조하십시였. 여전히 if 와 ì–žì–Žê°€ 제공하는 닀륞 몚든 것을 사용할 수 있습니닀.

거의 몚든 현대 펞집Ʞ는 예앜얎륌 강조 표시합니닀.

아마도. 귞러나 가독성을 위핎 구묞 강조 표시가 필요한 불투명한 구묞을 도입하는 것은 읎상적읎지 않습니닀.

읎 특정 버귞는 얞얎에 읎쀑 반환 Ʞ능을 도입하여 수정할 수 있습니닀.
읎 겜우 핚수 a()는 123을 반환합니닀.

핚수 a() 정수 {
비()
반환 456
}
핚수 b() {
반환 반환 int(123)
}

읎 Ʞ능을 사용하여 닀음곌 같읎 였류 처늬륌 닚순화할 수 있습니닀.

func í•žë“€(var *foo, err error )(var *foo, err error ) {
였류 != nil {
반환 반환 없음, 였류
}
반환 var, nil
}

func client_code() (*client_object, 였류) {
var obj, err =handle(something_that_can_fail())
// 싀팚하지 않은 겜우에만 도달
// 귞렇지 않윌멎 client_code 핚수가 였류륌 슀택 위로 전파합니닀.
죌장(였류 == 없음)
}

읎륌 통핎 사람듀은 슀택 위로 였류륌 전파할 수 있는 였류 처늬Ʞ 핚수륌 작성할 수 있습니닀.
읎러한 였류 처늬 Ʞ능은 Ʞ볞 윔드와 분늬될 수 있습니닀.

제가 잘못 읎핎했닀멎 죄송합니닀. 하지만 요점을 명확히 하고 싶습니닀. 아래 핚수는 였류, vet 겜고륌 생성하거나 허용됩니까?

func Chdir(dir string) (err error) {
    syscall.Chdir(dir) || err
    return nil
}

@rodcorsi 읎 제안에 따띌 귀하의 예는 수의사 겜고 없읎 받아듀여질 것입니닀. 귞것은 동등 할 것입니닀

if err := syscall.Chdir(dir); err != nil {
    return err
}

Context의 사용을 확장하여 였류륌 처늬하는 것은 얎떻습니까? 예륌 듀얎 닀음곌 같은 정의가 죌얎집니닀.
type ErrorContext interface { HasError() bool SetError(msg string) Error() string }
읎제 였류가 발생하Ʞ 쉬욎 Ʞ능에서 ...
func MyFunction(number int, ctx ErrorContext) int { if ctx.HasError() { return 0 } return number + 1 }
쀑간 Ʞ능에서 ...
func MyIntermediateFunction(ctx ErrorContext) int { if ctx.HasError() { return 0 } number := 0 number = MyFunction(number, ctx) number = MyFunction(number, ctx) number = MyFunction(number, ctx) return number }
귞늬고 상위 레벚 Ʞ능에서
func main() { ctx := context.New() no := MyIntermediateFunction(ctx) if ctx.HasError() { log.Fatalf("Error: %s", ctx.Error()) return } fmt.Printf("%d\n", no) }
읎 ì ‘ê·Œ 방식을 사용하멎 몇 가지 읎점읎 있습니닀. 첫짞, 죌요 싀행 겜로에서 독자륌 산만하게 하지 않습니닀. Ʞ볞 싀행 겜로와의 펞찚륌 나타낮는 최소한의 "if" 묞읎 있습니닀.

둘짞, 였류륌 숚Ʞ지 않습니닀. 메서드 서명에서 ErrorContext륌 수띜하멎 핚수에 였류가 있을 수 있음읎 분명합니닀. 핚수 낎에서 음반적읞 Go 윔드륌 사용하여 였류륌 처늬하는 방법을 볎여죌는 음반적읞 분Ʞ 묞(예: "if")을 사용합니닀.

셋짞, 였류는 읎 겜우 컚텍슀튞 소유자읞 읎핎 당사자에게 자동윌로 버랔링됩니닀. 추가 처늬 였류가 있는 겜우 명확하게 표시됩니닀. 예륌 듀얎 êž°ì¡Ž 였류륌 래핑하Ʞ 위핎 쀑간 핚수륌 앜간 변겜핎 볎겠습니닀.
func MyIntermediateFunction(ctx ErrorContext) int { if ctx.HasError() { return 0 } number := 0 number = MyFunction(number, ctx) number = MyFunction(number, ctx) number = MyFunction(number, ctx) if ctx.HasError() { ctx.SetError(fmt.Sprintf("wrap msg: %s", ctx.Error()) return } number *= 20 number = MyFunction(number, ctx) return number }
Ʞ볞적윌로 필요에 따띌 였류 처늬 윔드륌 작성하멎 됩니닀. 수동윌로 버랔링할 필요가 없습니닀.

마지막윌로, 핚수 작성자는 였류륌 처늬핎알 하는지 여부륌 결정할 수 있습니닀. 현재 Go ì ‘ê·Œ 방식을 사용하멎 읎 작업을 쉜게 수행할 수 있습니닀.
````
// 닀음 정의가 죌얎졌을 때
func MyFunction(숫자 정수) 였류

//귞러멎 읎렇게
MyFunction(8) //였류륌 확읞하지 않고
With the ErrorContext, you as the function owner can make the error checking optional with this:
func MyFunction(ctx ErrorContext) {
ctx != nil && ctx.HasError() {
반품
}
//...
}
Or make it compulsory with this:
func MyFunction(ctx ErrorContext) {
if ctx.HasError() { //ctx가 nil읎멎 팹닉
반품
}
//...
}
If you make error handling compulsory and yet the user insists on ignoring error, they can still do that. However, they have to be very explicit about it (to prevent accidental ignore). For instance:
func UpperFunction(ctx ErrorContext) {
묎시됚 := context.New()
MyFunction(ignored) // 읎것은 묎시됩니닀.

 MyFunction(ctx) //this one is handled

}
````
읎 ì ‘ê·Œ 방식은 êž°ì¡Ž 얞얎륌 변겜하지 않습니닀.

@ALTree Alberto, check 와 @ianlancetaylor가 제안한 것을 ì–Žë–» 습니까?

귞래서

func F() (int, string, error) {
   i, s, err := OhNo()
   if err != nil {
      return i, s, &BadStuffHappened(err, "oopsie-daisy")
   }
   // all is good
   return i+1, s+" ok", nil
}

된닀

func F() (int, string, error) {
   i, s, err := OhNo()
   check i, s, err || &BadStuffHappened(err, "oopsie-daisy")
   // all is good
   return i+1, s+" ok", nil
}

또한 였류 유형만 처늬하도록 check 륌 제한할 수 있윌므로 여러 반환 값읎 필요한 겜우 읎늄을 지정하고 할당핎알 하므로 얎떻게든 "in-place"륌 할당하고 ê°„ë‹ší•œ "return"처럌 작동합니닀.

func F() (a int, s string, err error) {
   i, s, err = OhNo()
   check err |=  &BadStuffHappened(err, "oopsy-daisy")  // assigns in place and behaves like simple "return"
   // all is good
   return i+1, s+" ok", nil
}

return 가 ì–žì  ê°€ 표현식에서 허용된닀멎 check 는 필요하지 않거나 표쀀 핚수가 됩니닀.

func check(e error) bool {
   return e != nil
}

func F() (a int, s string, err error) {
   i, s, err = OhNo()
   check(err) || return &BadStuffHappened(err, "oopsy-daisy")
   // all is good
   return i+1, s+" ok", nil
}

마지막 솔룚션은 Perl처럌 느껎지지만 😄

누가 처음 제안했는지 Ʞ억나지 않지만 여Ʞ에 또 닀륞 구묞 아읎디얎가 있습니닀(몚두가 가장 좋아하는 자전거 볎ꎀ소 :-). 나는 귞것읎 좋은 것읎띌고 말하지는 않지만 우늬가 아읎디얎륌 냄비에 던지멎 ...

x, y := try foo()

닀음곌 같습니닀.

x, y, err := foo()
if err != nil {
    return (an appropriate number of zero values), err
}

귞늬고

x, y := try foo() catch &FooErr{E:$, S:"bad"}

닀음곌 같습니닀.

x, y, err := foo()
if err != nil {
    return (an appropriate number of zero values), &FooErr{E:err, S:"bad"}
}

try 형식은 몚듈로 플상적읞 구묞 찚읎로 읎전에 여러 번 제안된 적읎 있습니닀. try ... catch 형식은 덜 자죌 제안되지만 @ALTree 의 check A, B 구성 및 @tandr 의 후속 제안곌 분명히 유사합니닀. 한 가지 찚읎점은 읎것읎 묞읎 아니띌 표현읎띌는 점읎므로 닀음곌 같읎 말할 수 있습니닀.

z(try foo() catch &FooErr{E:$, S:"bad"})

닚음 묞에 여러 개의 try/catch가 있을 수 있습니닀.

p = try q(0) + try q(1)
a = try b(c, d() + try e(), f, try g() catch &GErr{E:$}, h()) catch $BErr{E:$}

비록 우늬가 귞것을 장렀하고 싶지 않닀고 생각하지만. 여Ʞ에서 평가 순서에 대핎서도 죌의핎알 합니닀. 예륌 듀얎 e() 가 nil읎 아닌 였류륌 반환하는 겜우 h() 가 부작용에 대핮 평가되는지 여부.

분명히 try 및 catch 와 같은 새 킀워드는 Go 1.x 혞환성을 깚뜚늎 것입니닀.

나는 우늬가 읎 제안의 목표륌 짜알 한닀고 제안합니닀. 읎 제안윌로 ì–Žë–€ 묞제가 핎결됩니까? 닀음 ì„ž 쀄을 두 쀄 또는 한 쀄로 쀄읎십시였. 읎것은 반환/만앜의 ì–žì–Žê°€ 변겜될 수 있습니닀.

if err != nil {
    return err
}

아니멎 였류륌 확읞하는 횟수륌 쀄입니까? 읎륌 위한 try/catch 솔룚션음 수 있습니닀.

였류 처늬륌 위한 합늬적읞 바로 가Ʞ 구묞에는 ì„ž 가지 속성읎 있닀고 제안하고 싶습니닀.

  1. 였류가 아닌 겜로가 눈에 띄도록 검사 쀑읞 윔드 앞에 나타나지 ì•Šì•„ì•Œ 합니닀.
  2. 동음한 읎늄을 가진 명시적 변수가 있을 때 독자가 혌동하지 않도록 암시적 변수륌 범위에 도입핎서는 안 됩니닀.
  3. 하나의 복구 작업(예: return err )을 닀륞 작업볎닀 쉜게 ​​만듀지 ì•Šì•„ì•Œ 합니닀. 때로는 완전히 닀륞 작업읎 선혞될 수 있습니닀(예 t.Fatal 혞출). 또한 사람듀읎 추가 컚텍슀튞륌 추가하는 것을 막고 싶지 않습니닀.

읎러한 제앜 조걎을 감안할 때 거의 최소한의 구묞은 닀음곌 같습니닀.

STMT SEPARATOR_TOKEN VAR BLOCK

예륌 듀얎,

syscall.Chdir(dir) :: err { return err }

에 핎당하는

if err := syscall.Chdir(dir); err != nil {
    return err
}
````
Even though it's not much shorter, the new syntax moves the error path out of the way. Part of the change would be to modify `gofmt` so it doesn't line-break one-line error-handling blocks, and it indents multi-line error-handling blocks past the opening `}`.

We could make it a bit shorter by declaring the error variable in place with a special marker, like

syscall.Chdir(dir) :: { @err 반환 }
```

읎것읎 0읎 아닌 값곌 였류가 몚두 반환된 겜우 얎떻게 작동하는지 궁ꞈ합니닀. 예륌 듀얎 bufio.Peek은 0읎 아닌 값곌 ErrBufferFull을 동시에 반환할 수 있습니닀.

@mattn 여전히 읎전 구묞을 사용할 수 있습니닀.

@nigeltao ë„€,

ret, err := doSomething() :: err { return err }
return ret, err

@jba 섀명하고 있는 것은 전치된 핚수 구성 연산자와 앜간 비슷합니닀.

syscall.Chdir(dir) ⫱ func (err error) { return &PathError{"chdir", dir, err} }

귞러나 우늬가 대부분 명령적읞 윔드륌 작성하고 있닀는 사싀은 요점의 음부가 조Ʞ에 반환할 수 있닀는 것읎Ʞ 때묞에 두 번짞 위치에 핚수륌 사용 하지 ì•Šì•„ì•Œ 한닀는 것을 요구합니닀.

읎제 저는 몚든 종류의 ꎀ렚읎 있는 ì„ž 가지 ꎀ찰에 대핮 생각하고 있습니닀.

  1. 였류 처늬는 핚수 구성곌 비슷하지만 Go에서 작업을 수행하는 방식은 Haskell의 Error 몚나드 와 정반대입니닀. 우늬는 대부분 순찚 윔드 대신 명령형 윔드륌 작성하Ʞ 때묞에

  2. (x, y, error) 륌 반환하는 Go 핚수는 음반적윌로 (x, y) | error 의 합집합(#19412)곌 같은 것을 의믞합니닀.

  3. unpack 또는 pattern-match 공용첎 얞얎에서 겜우는 별도의 범위읎며 Go에서 였류가 발생하는 많은 묞제는 핎당 범위륌 분늬하여 개선될 수 있는 재선얞된 변수의 예Ʞ치 않은 귞늌자 때묞에 발생합니닀(#21114).

귞래서 아마도 우늬가 정말로 원하는 것은 =: 연산자와 같지만 음종의 조합 음치 조걎읎 있는 것입니닀.

syscall.Chdir(dir) =? err { return &PathError{"chdir", dir, err} }

```가닀
n := io.WriteString(w, s) =? 였류 { 였류 반환 }

and perhaps a boolean version for `, ok` index expressions and type assertions:
```go
y := m[x] =! { return ErrNotFound }

범위 지정을 제왞하고는 gofmt 륌 닚음 띌읎너에 더 적합하도록 변겜하는 것곌 크게 닀륎지 않습니닀.

err := syscall.Chdir(dir); if err != nil { return &PathError{"chdir", dir, err} }

```가닀
n, 였류 := io.WriteString(w, s); if err != nil { 였류륌 반환 }

```go
y, ok := m[x]; if !ok { return ErrNotFound }

하지만 범위 지정은 쀑요합니닀! 범위 지정 묞제는 읎러한 종류의 윔드가 "닀소 못생ꞎ"에서 "믞묘한 버귞"로 선을 넘는 위치입니닀.

@ianlancetaylor
나는 전반적읞 아읎디얎의 팬읎지만 귞것에 대한 비밀슀러욎 펄곌 같은 구묞의 엎렬한 지지자는 아닙니닀. 아마도 닀음곌 같읎 더 장황한 구묞읎 덜 혌란슀러욞 것입니닀.

syscall.Chdir(dir) or dump(err): errors.Wrap(err, "chdir failed")

syscall.Chdir(dir) or dump

또한 할당의 겜우 마지막 읞수가 표시되는지 여부륌 읎핎하지 못했습니닀. 예:

resp := http.Get("https://example.com") or dump

였류는 특별한 유형읎 아니띌 go의 값읎띌는 것을 잊지 마십시였.
우늬가 닀륞 구조첎에 대핮 할 수 있는 것은 였류에 대핮 할 수 없고 ê·ž 반대입니닀. 읎것은 음반적윌로 구조첎륌 읎핎한닀멎 였류와 처늬 방법을 읎핎한닀는 것을 의믞합니닀(장황하닀고 생각하더띌도)

읎 구묞은 신규 및 êž°ì¡Ž 개발자가 핎당 정볎륌 사용하는 윔드륌 읎핎하Ʞ 시작하Ʞ 전에 새로욎 정볎륌 배워알 합니닀.

귞것만윌로도 읎 제안은 IMHO의 가치가 없습니닀.

개읞적윌로 읎 구묞을 선혞합니닀

err := syscall.Chdir(dir)
if err != nil {
    return err
}
return nil

~ 위에

if err := syscall.Chdir(dir); err != nil {
    return err
}
return nil

한 쀄 더 있지만 의도한 작업곌 였류 처늬륌 구분합니닀. 읎 양식읎 가장 읜Ʞ 쉜습니닀.

@bcmills :

범위 지정을 제왞하고는 gofmt륌 닚음 띌읎너에 더 적합하도록 변겜하는 것곌 크게 닀륎지 않습니닀.

범위 지정뿐만 아니띌 왌쪜 가장자늬도 있습니닀. 나는 귞것읎 가독성에 정말 영향을 믞친닀고 생각합니닀. 제 생각에는

syscall.Chdir(dir) =: err; if err != nil { return &PathError{"chdir", dir, err} } 

볎닀 훚씬 명확하닀

err := syscall.Chdir(dir); if err != nil { return &PathError{"chdir", dir, err} } 

특히 연속된 여러 쀄에서 발생하는 겜우 눈읎 왌쪜 가장자늬륌 슀캔하여 였류 처늬륌 묎시할 수 있Ʞ 때묞입니닀.

@bcmills 띌는 아읎디얎륌 혌합하여 조걎부 파읎프 전달 연산자륌 도입할 수 있습니닀.

F2 핚수는 마지막 값읎 nil 읎

func F1() (foo, bar){}

first := F1() ?> last: F2(first, last)

return 묞을 사용한 파읎프 전달의 특별한 겜우

func Chdir(dir string) error {
    syscall.Chdir(dir) ?> err: return &PathError{"chdir", dir, err}
    return nil
}

닀륞 혞에서 @urandom 읎 가젞옚 싀제 예
Ʞ볞 흐늄에 쀑점을 두얎 훚씬 더 읜Ʞ 쉜습니닀.

func configureCloudinit(icfg *instancecfg.InstanceConfig, cloudcfg cloudinit.CloudConfig) (cloudconfig.UserdataConfig, error) {
    // When bootstrapping, we only want to apt-get update/upgrade
    // and setup the SSH keys. The rest we leave to cloudinit/sshinit.
    udata := cloudconfig.NewUserdataConfig(icfg, cloudcfg) ?> err: return nil, err
    if icfg.Bootstrap != nil {
        udata.ConfigureBasic() ?> err: return nil, err
        return udata, nil
    }
    udata.Configure() ?> err: return nil, err
    return udata, nil
}

func ComposeUserData(icfg *instancecfg.InstanceConfig, cloudcfg cloudinit.CloudConfig, renderer renderers.ProviderRenderer) ([]byte, error) {
    if cloudcfg == nil {
        cloudcfg = cloudinit.New(icfg.Series) ?> err: return nil, errors.Trace(err)
    }
    _ = configureCloudinit(icfg, cloudcfg) ?> err: return nil, errors.Trace(err)
    operatingSystem := series.GetOSFromSeries(icfg.Series) ?> err: return nil, errors.Trace(err)
    udata := renderer.Render(cloudcfg, operatingSystem) ?> err: return nil, errors.Trace(err)
    logger.Tracef("Generated cloud init:\n%s", string(udata))
    return udata, nil
}

였류 처늬가 읞첎 공학적읎지 않닀는 데 동의합니닀. 슉, 아래 윔드륌 읜을 때 if error not nil then 로 발음핎알 합니닀. 읎는 if there is an error then 변환됩니닀.

if err != nil {
    // handle error
}

위의 윔드륌 귞런 식윌로 표현할 수 있는 능력을 갖고 싶습니닀. 제 생각에는 더 읜Ʞ 쉜습니닀.

if err {
    // handle error
}

저의 소박한 제안입니닀 :)

펄처럌 볎읎지만 맀직 변수도 있습니닀.
ì°žê³ ë¡œ 펄에서는

open (FILE, $file) or die("$file을 ì—Ž 수 없습니닀: $!");

IMHO, 귞럎 가치가 없습니닀. ë‚Žê°€ go에 대핮 좋아하는 한 가지는 였류 처늬입니닀.
녞곚적읎며 '당신의 얌굎에'

우늬가 귞것을 고수한닀멎 마법의 변수가 없Ʞ 륌 바랍니닀 .
였류 변수의 읎늄을 지정할 수 있습니닀.

e := syscall.Chdir(dir) ?> e: &PathError{"chdir", dir, e}

귞늬고 ||와 닀륞 Ʞ혞륌 사용할 수도 있습니닀. 읎 작업에 특정한
나는 거꟞로 때묞에 '또는'곌 같은 텍슀튞 Ʞ혞가 불가능하닀고 생각합니닀.
혞환성

n, _, err, _ = somecall(...) ?> err: &PathError{"somecall", n, err}

2017년 8월 1음 화요음 였후 2시 47분에 Rodrigo [email protected] 은 닀음곌 같읎 썌습니닀.

아읎디얎 혌합 @bcmills https://github.com/bcmills 우늬가 소개할 수 있습니닀.
조걎부 파읎프 전달 연산자.

F2 핚수는 마지막 값읎 nil 읎

func F1()(foo, bar){}
첫 번짞 := F1() ?> 마지막: F2(처음, 마지막)

return 묞을 사용한 파읎프 전달의 특별한 겜우

func Chdir(dir 묞자엎) 였류 {
syscall.Chdir(dir) ?> err: return &PathError{"chdir", dir, err}
반환 없음
}

싀제 예
https://github.com/juju/juju/blob/01b24551ecdf20921cf620b844ef6c2948fcc9f8/cloudconfig/providerinit/providerinit.go
@urandom https://github.com/urandom 읎 닀륞 묞제에서 가젞왔습니닀.
Ʞ볞 흐늄에 쀑점을 두얎 훚씬 더 읜Ʞ 쉜습니닀.

func configureCloudinit(icfg *instancecfg.InstanceConfig, cloudcfg cloudinit.CloudConfig) (cloudconfig.UserdataConfig, 였류) {
// 부튞슀튞랩할 때 apt-get 업데읎튞/업귞레읎드만 원합니닀.
// SSH 킀륌 섀정합니닀. 나뚞지는 cloudinit/sshinit에 맡깁니닀.
udata := cloudconfig.NewUserdataConfig(icfg, cloudcfg) ?> 였류: 반환 없음, 였류
if icfg.Bootstrap != nil {
udata.ConfigureBasic() ?> err: 반환 없음, 였류
udata륌 반환, nil
}
udata.Configure() ?> err: 반환 없음, 였류
udata륌 반환, nil
}
func ComposeUserData(icfg *instancecfg.InstanceConfig, cloudcfg cloudinit.CloudConfig, renderer renderers.ProviderRenderer) ([]byte, error) {
만앜 cloudcfg == nil {
cloudcfg = cloudinit.New(icfg.Series) ?> err: 반환 없음, errors.Trace(err)
}
configureCloudinit(icfg, cloudcfg) ?> err: 반환 없음, 였류.Trace(err)
OperatingSystem := series.GetOSFromSeries(icfg.Series) ?> err: 반환 없음, 였류.Trace(err)
udata := renderer.Render(cloudcfg, operatingSystem) ?> err: 반환 없음, 였류.Trace(err)
logger.Tracef("생성된 큎띌우드 쎈Ʞ화:\n%s", 묞자엎(udata))
udata륌 반환, nil
}

—
읎 슀레드에 가입했Ʞ 때묞에 읎 메시지륌 받고 있습니닀.
읎 읎메음에 직접 답장하고 GitHub에서 확읞하섞요.
https://github.com/golang/go/issues/21161#issuecomment-319359614 또는 음소거
슀레드
https://github.com/notifications/unsubscribe-auth/AbwRO_J0h2dQHqfysf2roA866vFN4_1Jks5sTx5hgaJpZM4Oi1c-
.

읎 제안된 몚든 변겜 사항읎 현재 형식볎닀 더 복잡할 것읎띌고 생각하는 유음한 사람입니까?

닚순핚곌 간결핚은 동등하거나 상혞 교환할 수 없닀고 생각합니닀. 예, 읎러한 몚든 변겜 사항은 한 쀄 읎상 더 짧지만 ì–žì–Ž 사용자가 배워알 하는 연산자나 킀워드륌 도입합니닀.

@rodcorsi 사소한 것처럌 볎읎지만 두 번짞 부분읎 Block 읎 되는 것읎 쀑요하닀고 생각합니닀. êž°ì¡Ž if 및 for 묞은 몚두 랔록을 사용하고 select 및 switch 둘 ë‹€ 쀑ꎄ혞로 구분된 구묞을 사용하므로 읎 특정 제얎 흐멄 작업에 대핮 쀑ꎄ혞륌 생략하는 것읎 얎색핎 볎입니닀.

또한 새 Ʞ혞 닀음에 였는 임의의 표현식에 대핮 걱정할 필요가 없닀멎 구묞 분석 튞늬가 몚혞하지 않은지 확읞하는 것읎 훚씬 쉜습니닀.

슀쌀치륌 위핎 엌두에 두었던 구묞곌 의믞는 닀음곌 같습니닀.


NonZeroGuardStmt = ( Expression | IdentifierList ":=" Expression |
                     ExpressionList assign_op Expression ) "=?" [ identifier ] Block .
ZeroGuardStmt = ( Expression | IdentifierList ":=" Expression |
                  ExpressionList assign_op Expression ) "=!" Block .

NonZeroGuardStmt 가 싀행 Block 의 마지막 값 겜우 Expression 되지 않고, ê·ž 종류의 제로 값곌 동음. identifier 읎 있윌멎 Block 낎의 핎당 값에 바읞딩됩니닀. ZeroGuardStmt 는 Expression 의 마지막 값읎 핎당 유형의 0 값곌 같윌멎 Block ZeroGuardStmt 싀행합니닀.

듀얎 := 형태의 닀륞 (선도) 값 Expression 받는 바읞딩 IdentifierList A의 같은 ShortVarDecl . 식별자는 포핚 범위에서 선얞되며 읎는 Block 낎에서도 볌 수 있음을 의믞합니닀.

assign_op 형식의 겜우 각 왌쪜 플연산자는 죌소 지정 가능, 지도 색읞 표현식 또는 ( = 할당의 겜우에만) 빈 식별자여알 합니닀. 플연산자는 ꎄ혞로 묶을 수 있습니닀. 였륞쪜 Expression 의 닀륞 (선행) 값은 Assignment 에서와 같읎 평가됩니닀. 할당은 Block 싀행 전에 발생하며 Block 싀행 여부에 ꎀ계없읎 발생합니닀.


여Ʞ에 제안된 묞법읎 Go 1곌 혞환된닀고 생각합니닀. ? 는 유횚한 식별자가 아니며 핎당 묞자륌 사용하는 êž°ì¡Ž Go 연산자가 없윌며 ! 가 유횚한 연산자읎지만 없음 { 닀음에 올 수 있는 êž°ì¡Ž 프로덕션.

@bcmills LGTM,

=? 및 =! 각각 자첎 토큰윌로 만듀멎 묞법읎 쉜게 혾환될 것읎띌고 생각했을 것입니닀.

나는 당신읎 할 것읎띌고 생각했을 것입니닀 =? 귞늬고 =! 각각의 토큰은 고유한 권한을 가지므로 묞법읎 거의 혞환되지 않습니닀.

묞법에서는 귞렇게 할 수 있지만 얎휘분석Ʞ에서는 할 수 없습니닀. 시퀀슀 "=!" 유횚한 Go 1 윔드(https://play.golang.org/p/pMTtUWgBN9)에 나타날 수 있습니닀.

쀑ꎄ혞는 낮 제안에서 구묞 분석을 명확하게 만드는 것입니닀. =! 는 현재 부욞 변수 ì„ ì–ž 또는 할당에만 나타날 수 있윌며 ì„ ì–ž 및 할당은 현재 쀑ꎄ혞(https 암시적 섞믞윜론 (https://play.golang.org/p/lhcqBhr7Te)윌로

@romainmenke 아니요. 당신은 유음한 사람읎 아닙니닀. 한 쀄짜늬 였류 처늬의 가치륌 볎지 못했습니닀. 한 쀄은 절앜할 수 있지만 훚씬 더 복잡핎집니닀. 묞제는 읎러한 제안 쀑 많은 부분에서 였류 처늬 부분읎 숚겚젞 있닀는 것입니닀. 아읎디얎는 였류 처늬가 쀑요하Ʞ 때묞에 눈에 띄지 않게 만드는 것읎 아니띌 윔드륌 읜Ʞ 쉜게 만드는 것입니닀. 간결핚은 쉬욎 가독성곌 같지 않습니닀. êž°ì¡Ž 였류 처늬 시슀템을 변겜핎알 하는 겜우 Ʞ졎의 try-catch-finally가 많은 아읎디얎 목적볎닀 훚씬 더 맀력적입니닀.

check 제안읎 마음에 듭니닀. 처늬하도록 확장할 수도 있Ʞ 때묞입니닀.

f, err := os.Open(myfile)
check err
defer check f.Close()

닀륞 제안도 defer 와 섞음 수 없는 것 같습니닀. check 도 맀우 읜Ʞ 쉜고 Google에서 몚륎는 겜우 간닚합니닀. error 유형윌로 제한할 필요는 없닀고 생각합니닀. 마지막 위치에 있는 반환 맀개변수띌멎 묎엇읎든 사용할 수 있습니닀. 귞래서하는 반복자는있을 수 있습니닀 check A에 대한 Next() bool .

나는 한 번 닀음곌 같은 슀캐너륌 작성했습니닀.

func (s *Scanner) Next() bool {
    if s.Error != nil || s.pos >= s.RecordCount {
        return false
    }
    s.pos++

    var rt uint8
    if !s.read(&rt) {
        return false
    }
...

마지막 비튞는 대신 check s.read(&rt) 수 있습니닀.

@carlmjohnson

닀륞 제안도 defer 와 섞음 수 없는 것 같습니닀.

새 구묞을 사용하여 왞부 핚수에서 반환할 수 있도록 defer 륌 확장한닀고 가정하멎 핎당 가정을 닀륞 제안에도 똑같읎 적용할 수 있습니닀.

defer f.Close() =? err { return err }

@ALTree 의 check 제안은 별도의 명령묞을 도입하Ʞ 때묞에 닚순히 였류륌 반환하는 것 왞에 닀륞 작업을 수행하는 defer 와 읎륌 얎떻게 혌합할 수 있는지 몚륎겠습니닀.

defer func() {
  err := f.Close()
  check err, fmt.Errorf(
, err) // But this func() doesn't return an error!
}()

찚읎:

defer f.Close() =? err { return fmt.Errorf(
, err) }

읎러한 제안 쀑 많은 부분에 대한 정당성은 "읞첎 공학"읎 더 낫닀는 것읎지만 입력할 낎용읎 앜간 쀄얎듀도록 만드는 것 왞에 ì–Žë–€ 것읎 더 나은지 잘 몚륎겠습니닀. 읎것듀읎 얎떻게 윔드의 유지볎수성을 슝가시킀는가? 합성 가능성? 가독성? 제얎 흐늄을 읎핎하Ʞ 쉜습니까?

@jimmyfrasche

읎것듀읎 얎떻게 윔드의 유지볎수성을 슝가시킀는가? 합성 가능성? 가독성? 제얎 흐늄을 읎핎하Ʞ 쉜습니까?

앞서 얞꞉했듯읎 읎러한 제안의 죌요 읎점은 할당 및 err 변수의 범위륌 볎닀 명확하게 지정하는 것입니닀. #19727, #20148, #5634, #21114 및 닀양한 사람듀읎 였류 처늬와 ꎀ렚하여 범위 지정 묞제에 직멎하는 방식.

@bcmills 동Ʞ 부여륌 제공

귞러나 ê·ž 전제륌 감안할 때 몚든 변수에서 사용할 수 있는 "할당의 볎닀 명확한 범위 지정"을 위핎 볎닀 음반적읞 Ʞ능을 제공하는 것읎 더 좋지 않을까요? 나는 의도치 않게 였류가 아닌 변수에 대핎서도 귞늌자륌 드늬웠습니닀.

:= 의 현재 동작읎 도입되었을 때륌 Ʞ억합니닀. 많은 슀레드가 '핎당 변수가 정확히 현재 범위"가 낮 겜험상 볎Ʞ 힘든 몚든 믞묘한 묞제가 나타나는 곳입니닀.

† 링크가 있는 슀레드륌 찟을 수 없습니까?

바둑에 대핮 개선할 수 있는 부분읎 많읎 있지만 := 의 행동은 항상 한 가지 심각한 싀수로 저륌 놀띌게 했습니닀. := 의 동작을 닀시 방묞하는 것읎 귌볞 묞제륌 핎결하거나 최소한 닀륞 극닚적읞 변겜의 필요성을 쀄읎는 방법음 수 있습니닀.

@jimmyfrasche

귞러나 ê·ž 전제륌 감안할 때 몚든 변수에서 사용할 수 있는 "할당의 볎닀 명확한 범위 지정"을 위핎 볎닀 음반적읞 Ʞ능을 제공하는 것읎 더 좋지 않을까요?

예. 귞것은 @jba 와 ë‚Žê°€ 제안한 =? 또는 :: 연산자에 대핮 ë‚Žê°€ 좋아하는 것 쀑 하나입니닀. 또한 였류가 아닌 (확싀히 제한된 하위 집합)까지 멋지게 확장됩니닀.

개읞적윌로, 나는 더 명시적읞 태귞 결합/변수/대수 데읎터 유형 Ʞ능(#19412 ì°žì¡°)을 사용하멎 장Ʞ적윌로 더 행복할 것읎띌고 생각하지만 얞얎에 대한 훚씬 더 큰 변겜 사항입니닀. 우늬가 얎떻게 개조할지 볎Ʞ가 얎렵습니닀. Go 1 / Go 2 혌합 환겜의 êž°ì¡Ž API에 추가합니닀.

제얎 흐늄을 읎핎하Ʞ 쉜습니까?

my 와 @bcmills 의 제안에서 당신의 눈은 왌쪜을 훑얎볎고 였류가 없는 제얎 흐늄을 쉜게 받아듀음 수 있습니닀.

@bcmills 제 생각에 #19412 닚얎의 적얎도 절반은 제가 책임지고 있닀고 생각하므로 합계 유형에 대핮 저륌 팔 필요가 없습니닀 ;)

였류가 있는 묌걎을 반환하는 겜우에는 4가지 겜우가 있습니닀.

  1. 귞냥 였류 (아묎것도 할 필요가 없습니닀, 귞냥 였류륌 반환)
  2. 묌걎 및 였류(지ꞈ처럌 정확하게 처늬할 수 있음)
  3. 한 가지 또는 였류(합계 유형을 사용할 수 있습니닀! :tada: )
  4. 둘 읎상의 것 또는 였류

4륌 치멎 상황읎 복잡핎집니닀. 튜플 유형(구조첎의 레읎랔읎 지정된 제품 유형곌 핚께 사용할 레읎랔읎 없는 제품 유형)을 도입하지 않고 합계 유형을 사용하여 "읎것 또는 였류"륌 몚덞링하렀는 겜우 몚든 것을 구조첎에 번듀링하여 묞제륌 사례 3윌로 쀄여알 합니닀.

튜플 유형을 도입하멎 몚든 종류의 묞제와 혞환성 묞제 및 읎상한 겹칚읎 발생합니닀( func() (int, string, error) 암시적윌로 정의된 튜플 또는 닀쀑 반환 값읎 별도의 개념입니까? 암시적윌로 정의된 튜플읎멎 func() (n int, msg string, err error) 을 의믞합니까?

나는 여전히 합계 유형읎 많은 읎점을 제공한닀고 생각하지만 범위 지정 묞제륌 핎결하Ʞ 위핎 아묎 것도 하지 않습니닀. 결곌 쌀읎슀에 묎얞가가 있을 때 였류 쌀읎슀륌 섀도잉하는 대신 전첎 '결곌 또는 였류' 합계륌 섀도잉할 수 있Ʞ 때묞에 묞제가 더 악화될 수 있습니닀.

@jba 귞것읎 바람직한 속성읞지

튜플 유형을 도입하지 않고 [
] 합계 유형을 사용하여 "읎것 또는 였류"륌 몚덞링하렀멎 몚든 것을 구조첎에 [묶음]í•Žì•Œ 합니닀.

저는 ꎜ찮습니닀. 귞런 식윌로 혞출 사읎튞륌 훚씬 더 읜Ʞ 쉜게 만듀 수 있윌며(더 읎상 싀수로 위치 바읞딩읎 바뀌지 않습니닀!) #12854는 현재 구조첎 반환곌 ꎀ렚된 많은 였버헀드륌 완화할 것입니닀.

가장 큰 묞제는 마읎귞레읎션입니닀. 특히 싀제로 "값을 반환하는 io.Writer 와 같은 API가 있는 겜우 Go 1의 "값 및 였류" 몚덞에서 Go 2의 잠재적읞 "값 귞늬고 였류"?

나는 여전히 합계 유형읎 많은 읎점을 제공한닀고 생각하지만 범위 지정 묞제륌 핎결하Ʞ 위핎 아묎 것도 하지 않습니닀.

귞것은 당신읎 귞것듀을 얎떻게 풀느냐에 달렀 있윌며, 귞것읎 우늬륌 였늘날의 위치로 되돌렀놓을 것읎띌고 생각합니닀. 공용첎륌 선혞하는 겜우 =? 버전을 "비대칭 팹턮 음치" API로 구상할 수 있습니닀.

i := match strconv.Atoi(str) | err error { return err }

여Ʞ서 match 는 전통적읞 ML 슀타음 팹턮 음치 작업읎지만 완전하지 않은 음치의 겜우 값을 반환합니닀(union에 음치하지 않는 대안읎 두 개 읎상 있는 겜우 interface{} ). 불완전한 겜Ʞ 싀팚로 당황하Ʞ볎닀는.

https://github.com/mpvl/errd 에서 여Ʞ에서 프로귞래밍 방식윌로 녌의된 묞제륌 핎결하는 팚킀지륌 첎크읞했습니닀(ì–žì–Ž 변겜 없음). 읎 팚킀지의 가장 쀑요한 잡멎은 였류 처늬륌 닚축할 뿐만 아니띌 올바륎게 수행하Ʞ가 더 쉜닀는 것입니닀. 나는 특히 defer와의 상혞 작용에서 전통적읞 ꎀ용적 였류 처늬가 볎읎는 것볎닀 더 까닀로욎 방법에 대한 묞서의 예륌 제공합니닀.

하지만 나는 읎것을 "버너" 팚킀지띌고 생각합니닀. 목표는 얞얎륌 가장 잘 확장하는 방법에 대한 좋은 겜험곌 통찰력을 얻는 것입니닀. 읎것읎 음읎 될 겜우 제넀늭곌 맀우 잘 상혞 작용합니닀.

아직 몇 가지 더 많은 예제륌 작업하고 있지만 읎 팚킀지는 싀험할 쀀비가 되얎 있습니닀.

@bcmills a million :+1: #12854

얞꞉했듯읎 "반환 X 및 였류" 및 "반환 X 또는 였류"가 있윌므로 요청 시 읎전 방식을 새로욎 방식윌로 변환하는 음부 맀크로 없읎는 싀제로 읎 묞제륌 í•Žê²°í•  수 없습니닀. 또는 "X 및 였류" Ʞ능에 불가플하게 사용되었을 때 적얎도 런타임 팹닉).

나는 특별한 맀크로륌 얞얎에 도입하는 아읎디얎륌 정말로 좋아하지 않습니닀. 특히 읎것읎 닚지 였류 처늬륌 위한 것읎띌멎, 읎는 읎러한 제안의 많은 부분에서 저의 죌요 묞제입니닀.

Go는 섀탕읎나 마법에 대핮 큰 ꎀ심을 갖고 있지 않윌며 귞것읎 장점입니닀.

볎닀 Ʞ능적읞 였류 처늬 팚러닀임윌로의 대규몚 도앜을 처늬하Ʞ에는 현재 ꎀ행에 읞윔딩된 정볎가 너묎 많고 정볎가 너묎 적습니닀.

Go 2가 합계 유형을 가젞였멎(솔직히 좋은 의믞로!) 충격을 받을 것입니닀. 얎욌든 "새로욎 슀타음"로 읎동하렀멎 맀우 느며 점진적 프로섞슀가 필요하며 ê·ž 동안에도 였류륌 처늬하는 방법에서 더 많은 조각화와 혌란읎 발생하므로 순 Ɥ정적윌로 볎지 않습니닀. (귞러나 슉시 ì„ž 개의 채널 대신 chan union { Msg1 T; Msg2 S; Err error } 와 같은 항목에 사용하Ʞ 시작합니닀.)

읎것읎 Go1 읎전읎고 바둑 팀읎 "앞윌로 6개월 동안 몚든 것을 옮Ʞ고 묞제가 발생하멎 계속 따띌와알 한닀"ê³  말할 수 있닀멎 귞것은 한 가지가 될 것읎지만, 지ꞈ 우늬는 Ʞ볞적윌로 막혀 있습니닀. 합계 유형을 얻더띌도.

얞꞉했듯읎 "반환 X 및 였류" 및 "반환 X 또는 였류"가 있윌므로 요청 시 읎전 방식을 새로욎 방식윌로 변환하는 음부 맀크로 없읎는 읎 묞제륌 í•Žê²°í•  수 없습니닀.

위에서 말했듯읎 "반환 X 및 였류"륌 닀룚는 새로욎 방법읎 묎엇읎든간에 필요하지 않닀고 생각합니닀. 대닀수의 겜우가 "반환 X 또는 였류"읎고 새로욎 방법읎 ê·ž 점만 개선한닀멎 훌륭하고 더 희귀한 "반환 X 및 였류"에 대핮 읎전 Go 1 혾환 방법을 계속 사용할 수 있습니닀.

@nigeltao 사싀읎지만 전첎 표쀀 띌읎람러늬륌 êž°ì¡Ž 슀타음로 유지하도록 제안하지 않는 한 전환하는 동안 구분할 방법읎 여전히 필요합니닀.

@jimmyfrasche 나는 귞것에 대한 녌쟁을 구성 할 수 있닀고 생각하지 않습니닀. 낮 읎알Ʞ륌 볎거나 repo README 에서 예제륌 볌 수 있습니닀. 귞러나 시각적 슝거가 당신에게 섀득력읎 없닀멎 ë‚Žê°€ 말할 수 있는 것읎 없습니닀.

@jba 는

목표가 더 나은 ìš©ì–Žê°€ 없Ʞ 때묞에 불행한 겜로륌 옆윌로 옮Ʞ는 것읎띌멎 $EDITOR 플러귞읞은 ì–žì–Ž 변겜 없읎 작동하고 윔드 작성자의 Ʞ볞 섀정에 ꎀ계없읎 몚든 êž°ì¡Ž 윔드에서 작동합니닀.

얞얎륌 변겜하멎 구묞읎 좀 더 간결핎집니닀. @bcmills 는 읎것읎 범위 지정을 개선 := 와 닀륞 범위 지정 규칙읎 없윌멎 얎떻게 할 수 있는지 싀제로 알지 못하지만 더 많은 혌란을 음윌킬 것 같습니닀.

@bcmills 귀하의 의견을 읎핎할 수 없습니닀. 분명히 구분할 수 있습니닀. 읎전 방법은 닀음곌 같습니닀.

err := foo()
if err != nil {
  return n, err  // n can be non-zero
}

새로욎 방법은 닀음곌 같습니닀.

check foo()

또는

foo() || &FooError{err}

또는 자전거 볎ꎀ소의 색상읎 묎엇읎든 상ꎀ없습니닀. 대부분의 표쀀 띌읎람러늬가 전환될 수 있지만 몚든 것읎 전환되얎알 하는 것은 아닙니닀.

@ianlancetaylor 의 요구 사항에 추가하렀멎: 였류 메시지륌 닚순화하멎 낎용읎 짧아질 뿐만 아니띌 였류 처늬가 더 쉬워젞알 합니닀. Ʞ능을 연Ʞ하Ʞ 위핎 팚닉곌 닀욎슀튞늌 였류륌 전달하는 것은 제대로 하Ʞ가 까닀롭습니닀.

예륌 듀얎 였류가 발생하멎 파음 쓰Ʞ륌 쀑닚하렀는 Google Cloud Storage 파음에 쓰는 것을 고렀하십시였.

func writeToGS(ctx context.Context, bucket, dst string, r io.Reader) (err error) {
    client, err := storage.NewClient(ctx)
    if err != nil {
        return err
    }
    defer client.Close()

    w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
    defer func() {
        if r := recover(); r != nil {
            w.CloseWithError(fmt.Errorf("panic: %v", r))
            panic(r)
        }
        if err != nil {
            _ = w.CloseWithError(err)
        } else {
            err = w.Close()
        }
    }
    _, err = io.Copy(w, r)
    return err
}

읎 윔드의 믞묘핚은 닀음곌 같습니닀.

  • Copy의 였류는 명명된 반환 읞수륌 통핎 defer 핚수에 몰래 전달됩니닀.
  • 완전히 안전하Ʞ 위핎 우늬는 r에서 팚닉을 포착하고 팚닉을 재개하Ʞ 전에 쓰Ʞ륌 쀑닚했는지 확읞합니닀.
  • 첫 번짞 닫Ʞ의 였류륌 묎시하는 것은 의도적읎지만 앜간 게윌륞 프로귞래뚞 읞공묌처럌 볎입니닀.

팚킀지 errd륌 사용하멎 읎 윔드는 닀음곌 같습니닀.

func writeToGS(ctx context.Context, bucket, dst, src string, r io.Reader) error {
    return errd.Run(func(e *errd.E) {
        client, err := storage.NewClient(ctx)
        e.Must(err)
        e.Defer(client.Close, errd.Discard)

        w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
        e.Defer(w.CloseWithError)

        _, err = io.Copy(w, r)
        e.Must(err)
    })
}

errd.Discard 는 였류 처늬Ʞ입니닀. 였류 처늬Ʞ륌 사용하여 몚든 였류륌 래핑, Ʞ록할 수도 있습니닀.

e.Must 는 foo() || wrapError

e.Defer 는 추가읎며 지연에 였류륌 전달하는 것을 처늬합니닀.

제넀늭을 사용하멎 읎 윔드는 닀음곌 같읎 볎음 수 있습니닀.

func writeToGS(ctx context.Context, bucket, dst, src string, r io.Reader) error {
    return errd.Run(func(e *errd.E) {
        client := e.Must(storage.NewClient(ctx))
        e.Defer(client.Close, errd.Discard)

        w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
        e.Defer(w.CloseWithError)

        _ = e.Must(io.Copy(w, r))
    })
}

Defer에 사용할 메서드륌 표쀀화하멎 닀음곌 같읎 볎음 수도 있습니닀.

func writeToGS(ctx context.Context, bucket, dst, src string, r io.Reader) error {
    return errd.Run(func(e *errd.E) {
        client := e.DeferClose(e.Must(storage.NewClient(ctx)), errd.Discard)
       e.Must(io.Copy(e.DeferClose(client.Bucket(bucket).Object(dst).NewWriter(ctx)), r)
    })
}

DeferClose는 Close 또는 CloseWithError륌 선택합니닀. 읎것읎 더 낫닀는 것읎 아니띌 가능성을 볎여죌는 것뿐입니닀.

얎욌든, 나는 지난 죌에 암슀테륎닎 밋업에서 읎 죌제에 대핮 프레젠테읎션을 했고 였류 처늬륌 올바륎게 하는 것을 더 쉜게 만드는 Ʞ능읎 더 짧게 만드는 것볎닀 더 유용하닀고 생각되는 것 같았습니닀.

였류륌 개선하는 솔룚션은 적얎도 음을 더 짧게 만드는 것볎닀 올바륞 음을 더 쉜게 하는 데 쀑점을 두얎알 합니닀.

@ALTree errd는 "정교한 였류 복구"륌 슉시 처늬합니닀.

@jimmyfrasche : errd는 플레읎귞띌욎드 예제가 하는 음을 대략적윌로 수행하지만 지연을 위핎 였류와 팚닉을 전달하Ʞ도 합니닀.

@jimmyfrasche : 대부분의 제안읎 윔드에서 읎믞 달성할 수 있는 것에 많은 것을 추가하지 않는닀는 데 동의합니닀.

@romainmenke : 간결핚에 너묎 많은 쎈점을 맞추고 있닀는 데 동의합니닀. 음을 더 쉜게 올바륎게 하렀멎 더 큰 쎈점을 두얎알 합니닀.

@jba : errd ì ‘ê·Œ 방식을 사용하멎 왌쪜을 볎멎 였류가 아닌 흐멄 대 비 였류 흐늄을 맀우 쉜게 슀캔할 수 있습니닀(e.로 시작하는 몚든 것은 였류 또는 처늬 ì—°êž°ìž„). 또한 ì–Žë–€ 반환 값읎 였류 또는 지연에 대핮 처늬되고 얎느 것읎 처늬되지 않는지륌 맀우 쉜게 슀캔할 수 있습니닀.

@bcmills : errd는 자첎적윌로 범위 지정 묞제륌 핎결하지 않지만 읎전에 선얞된 였류 변수 및 몚든 것에 닀욎슀튞늌 였류륌 전달할 필요가 없윌므로 였류 처늬 AFAICT에 대한 묞제륌 상당히 완화합니닀.

errd는 팚닉곌 회복에 전적윌로 의졎하는 것 같습니닀. 상당한 성능 저하가 수반되는 것처럌 듀늜니닀. 읎것 때묞에 전반적읞 솔룚션읞지 확신할 수 없습니닀.

@urandom : 낎부적윌로는 더 비용읎 많읎 듀지만 닚음 ì—°êž°ë¡œ 구현됩니닀.
원래 윔드읞 겜우:

  • 지연을 사용하지 않음: errd륌 사용하는 데 따륞 팹널티는 ì•œ 100ns*로 큜니닀.
  • ꎀ용적 지연 사용: 싀행 시간 또는 였류는 닀소 느늬지만 동음한 순서입니닀.
  • 지연에 대핮 적절한 였류 처늬륌 사용합니닀. 싀행 시간은 거의 같습니닀. 지연 수가 > 1읎멎 errd가 더 빠륌 수 있습니닀.

Ʞ타 간접비:

  • Defer에 큎로저(w.Close)륌 전달하멎 현재 DeferClose 또는 DeferFunc API륌 사용하는 것곌 비교하여 ì•œ 25ns* 였버헀드가 추가됩니닀(늎늬슀 v0.1.0 ì°žì¡°). @rsc 와
  • 읞띌읞 였류 묞자엎을 핞듀러( e.Must(err, msg("oh noes!") )로 래핑하는 데 Go 1.8에서 ì•œ 30ns가 소요됩니닀. 귞러나 팁(1.9)을 사용하멎 여전히 할당되지만 2ns에서 비용을 Ʞ록했습니닀. 묌론 믞늬 선얞된 였류 메시지의 겜우 비용은 여전히 ​​묎시할 수 있습니닀.

(*) 낮 2016 MacBook Pro에서 싀행되는 몚든 숫자.

대첎로 원래 윔드가 defer륌 사용하는 겜우 비용읎 허용되는 것윌로 볎입니닀. 귞렇지 않은 겜우 Austin은 ì—°êž° 비용을 크게 쀄읎Ʞ 위핎 녞력하고 있윌므로 시간읎 지낚에 따띌 비용읎 쀄얎듀 수도 있습니닀.

얎욌든,읎 팚킀지의 요점은 우늬가 포읞튞로 읎동 2. 사례에서 최고의 ì–žì–Ž 추가륌 구축 할 수 있도록 느낌곌 지ꞈ은 유용 할 것읎닀 닀륞 였류 처늬륌 사용하는 방법에 대한 겜험을 얻을 수입니닀 현재의 녌의는, 귞것은을 감소에 너묎 많읎 집쀑한닀 ê°„ë‹ší•œ 겜우에는 몇 쀄의 쀄읎 필요하지만 얻을 수 있는 것읎 훚씬 더 많윌며 틀늌없읎 닀륞 점읎 더 쀑요합니닀.

@jimmyfrasche :

귞러멎 $EDITOR 플러귞읞은 ì–žì–Ž 변겜 없읎 작동합니닀.

예, 귞것읎 제가 대화에서 죌장하는 바입니닀. 여Ʞ에 우늬가 ì–žì–Ž 변겜을 할 겜우, 귞것은 "(!) ì°žê³ "개념에 있던핎알한닀고 죌장하고있닀.

@nigeltao

분명히 구분할 수 있습니닀. 읎전 방법은 닀음곌 같습니닀.

나는 사용 지점읎 아니띌 ì„ ì–ž 지점에 대핮 읎알Ʞ하고 있습니닀.

여Ʞ에서 녌의된 제안 쀑 음부는 혞출 사읎튞에서 둘을 구별하지 않지만 음부는 구별합니닀. || , try 
 catch 또는 match 와 같읎 "값 또는 였류"륌 가정하는 옵션 쀑 하나륌 선택하멎 사용할 컎파음 타임 였류여알 합니닀. "값 및 였류" Ʞ능읎 있는 핎당 구묞읎 묎엇읞지 정의하는 것은 핎당 Ʞ능의 구현자에게 달렀 있습니닀.

ì„ ì–ž 시점에서 현재 "값곌 였류"와 "값 또는 였류"륌 구별할 수 있는 방법은 없습니닀.

func Atoi(string) (int, error)

귞늬고

func WriteString(Writer, String) (int, error)

반환 유형은 같지만 였류 의믞는 닀늅니닀.

@mpvl 나는

WithDefault()의 결곌에 대한 작업을 위한 최상위 핚수와 같은 음반적읞 도우믞륌 묎시하고 닚순성을 위핎 항상 컚텍슀튞륌 사용하고 성능에 대한 결정을 묎시한닀고 가정하멎 절대 최소 베얎볞 API가 닀음윌로 축소됩니닀. 아래 작업?

type Handler = func(ctx context.Context, panicing bool, err error) error
Run(context.Context, func(*E), defaults ...Handler) //egregious style but most minimal
type struct E {...}
func (*E) Must(err error, handlers ...Handler)
func (*E) Defer(func() error, handlers ...Handler)

윔드륌 볎멎 위와 같읎 정의되지 않은 몇 가지 좋은 읎유륌 알 수 있지만 개념을 더 잘 읎핎하Ʞ 위핎 핵심 의믞륌 파악하렀고 합니닀. 예륌 듀얎 IsSentinel 읎 윔얎에 있는지 여부는 확싀하지 않습니닀.

@jimmyfrasche

@bcmills 는 읎것읎 범위 지정을 개선

죌요 개선 사항은 err 변수륌 범위 밖윌로 유지하는 것입니닀. 귞러멎 https://github.com/golang/go/issues/19727 에서 링크된 것곌 같은 버귞륌 플할 수

    res, err := ctxhttp.Get(ctx, c.HTTPClient, dirURL)
    if err != nil {
        return Directory{}, err
    }
    defer res.Body.Close()
    c.addNonce(res.Header)
    if res.StatusCode != http.StatusOK {
        return Directory{}, responseError(res)
    }

    var v struct {
        

    }
    if json.NewDecoder(res.Body).Decode(&v); err != nil {
        return Directory{}, err
    }

버귞는 마지막 if 묞에서 발생합니닀. Decode 의 였류가 삭제되었지만 읎전 검사의 err 가 여전히 범위 낎에 있Ʞ 때묞에 명확하지 않습니닀. 대조적윌로 :: 또는 =? 연산자륌 사용하멎 닀음곌 같읎 작성됩니닀.

    res := ctxhttp.Get(ctx, c.HTTPClient, dirURL) =? err { return Directory{}, err }
    defer res.Body.Close()
    c.addNonce(res.Header)
    (res.StatusCode == http.StatusOK) =! { return Directory{}, responseError(res) }

    var v struct {
        

    }
    json.NewDecoder(res.Body).Decode(&v) =? err { return Directory{}, err }

여Ʞ에 도움읎 되는 두 가지 범위 지정 개선 사항읎 있습니닀.

  1. 첫 번짞 err (읎전 Get 혞출에서)는 return 랔록의 범위에만 있윌므로 후속 검사에서 싀수로 사용할 수 없습니닀.
  2. err from Decode 는 nilness가 검사되는 동음한 묞에서 선얞되Ʞ 때묞에 선얞곌 검사 사읎에 왜곡읎 있을 수 없습니닀.

(1)만윌로도 컎파음 타임에 였류륌 드러낎Ʞ에 충분했지만 (2) 명백한 방식윌로 가드 묞을 사용할 때 쉜게 플할 수 있습니닀.

@bcmills 섀명 감사합니닀

따띌서 res := ctxhttp.Get(ctx, c.HTTPClient, dirURL) =? err { return Directory{}, err } 에서 =? 맀크로는

var res *http.Reponse
{
  var err error
  res, err = ctxhttp.Get(ctx, c.HTTPClient, dirURL)
  if err != nil {
    return Directory{}, err 
  }
}

귞것읎 맞닀멎 := 와 닀륞 의믞륌 가젞알 한닀고 말했을 때 의믞했던 것입니닀.

닀음곌 같은 자첎 혌란을 음윌킬 것 같습니닀.

func f() error {
  var err error
  g() =? err {
    if err != io.EOF {
      return err
    }
  }
  //one could expect that err could be io.EOF here but it will never be so
}

ë‚Žê°€ 뭔가륌 잘못 읎핎하지 않는 한.

ë„€, 정확한 확장입니닀. := 와 닀륎닀는 것읎 옳습니닀. 읎는 의도된 것입니닀.

나늄대로 혌선을 빚을 것 같닀.

귞걎 사싀읎알. 귞것읎 싀제로 혌란슀러욞지 여부는 나에게 분명하지 않습니닀. 귞렇닀멎 선얞을 위핎 볎혞 묞의 ":" 변형을 제공할 수 있습니닀(및 "=" 변형만 할당).

(귞늬고 읎제는 연산자륌 =? 및 =! 대신 ? 및 ! 로 썚알 한닀고 생각합니닀.)

res := ctxhttp.Get(ctx, c.HTTPClient, dirURL) ?: err { return Directory{}, err }

하지만

func f() error {
  var err error
  g() ?= err { (err == io.EOF) ! { return err } }
  // err may be io.EOF here.
}

@mpvl errd 에 대한 나의 죌요 ꎀ심사는 Handler 읞터페읎슀입니닀. 윜백의 Ʞ능적 슀타음 파읎프띌읞을 권장하는 것처럌 볎읎지만 윜백/연속 슀타음 윔드에 대한 제 겜험(Go 및 C++곌 같은 명령형 ì–žì–Ž 및 Ʞ능적 ML 및 Haskell곌 같은 ì–žì–Ž)는 Go ꎀ용구의 나뚞지 부분곌도 음치하는 동음한 순찚/명령형 슀타음볎닀 따륎Ʞ가 훚씬 더 얎렵닀는 것입니닀.

Handler -슀타음 첎읞을 API의 음부로 구상하고 있습니까, 아니멎 Handler 륌 ê³ ë € 쀑읞 닀륞 구묞(예: Block 에슀?)

@bcmills 저는 여전히 한 쀄에 수십 가지 개념을 얞얎에 도입하고 한 가지 작업윌로만 작동하는 마법의 Ʞ능을 사용하지 않지만 마칚낎 x, err := f(); if err != nil { return err } 륌 작성하는 앜간 더 짧은 방법 읎상읞 읎유륌 알게 되었습니닀.

@bcmills 항상 새로욎 err 변수륌 선얞하지 않는 최신 =? 제안을 사용하여 앜간의 였류 처늬가 있는 @mpvl 의 동Ʞ 부여 예제륌 닀시 작성

func writeToGS(ctx context.Context, bucket, dst string, r io.Reader) (err error) {
        client := storage.NewClient(ctx) =? err { return err }
        defer client.Close()

        w := client.Bucket(bucket).Object(dst).NewWriter(ctx)

        defer func() {
                if r := recover(); r != nil { // r is interface{} not error so we can't use it here
                        _ = w.CloseWithError(fmt.Errorf("panic: %v", r))
                        panic(r)
                }

                if err != nil { // could use =! here but I don't see how that simplifies anything
                        _ = w.CloseWithError(err)
                } else {
                        err = w.Close()
                }
        }()

        io.Copy(w, r) =? err { return err } // what about n? does this need to be prefixed by a '_ ='?
        return nil
}

대부분의 였류 처늬는 변겜되지 않습니닀. =? 는 두 곳에서만 사용할 수 있습니닀. 처음에는 싀제로 ë‚Žê°€ 볌 수 있는 ì–Žë–€ 읎점도 제공하지 않았습니닀. 두 번짞에서는 윔드륌 더 Ꞟ게 만듀고 io.Copy 가 두 가지륌 반환한닀는 사싀을 흐늬게 하므로 거Ʞ에서 사용하지 않는 것읎 더 나았을 것입니닀.

@jimmyfrasche ê·ž 윔드는 규칙읎 아니띌 예왞입니닀. 우늬는 더 쉜게 작성할 수 있도록 Ʞ능을 섀계핎서는 안 됩니닀.

또한 recover 가 있얎알 하는지도 의묞입니닀. w.Write 또는 r.Read (또는 io.Copy !)가 팹닉 상태읎멎 종료하는 것읎 가장 좋습니닀.

recover 가 없윌멎 defer 가 싀제로 필요하지 않윌며 핚수의 맚 아래가 닀음곌 같읎 될 수 있습니닀.

_ = io.Copy(w, r) =? err { _ = w.CloseWithError(err); return err }
return w.Close()

@jimmyfrasche

// r is interface{} not error so we can't use it here

낮 특정 묞구(https://github.com/golang/go/issues/21161#issuecomment-319434101)는 특별히 였류가 아니띌 0 값에 ꎀ한 것입니닀.

// what about n? does this need to be prefixed by a '_ ='?

ë‚Žê°€ 귞것에 대핮 더 명확하게 말할 수 있었지만 귞렇지 않습니닀.

나는 ê·ž 예에서 @mpvl 의 recover 사용을 특히 좋아하지 않습니닀. ꎀ용적 제얎 흐늄에 대한 팚닉의 사용을 권장하는 반멎, 제 생각에는 불필요한 recover 혞출을 제거핎알 한닀고 생각합니닀( Go 2의 표쀀 띌읎람러늬에서 fmt 에 있는 것곌 같은 것입니닀.

ê·ž ì ‘ê·Œ 방식을 사용하멎 핎당 윔드륌 닀음곌 같읎 작성합니닀.

func writeToGS(ctx context.Context, bucket, dst string, r io.Reader) (err error) {
        client := storage.NewClient(ctx) =? err { return err }
        defer client.Close()

        w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
        io.Copy(w, r) =? err {
                w.CloseWithError(err)
                return err
        }
        return w.Close()
}

반멎에, 닚ꎀ적 복구륌 사용하멎 ꎀ용적 였류 처늬륌 지원하Ʞ 위한 Ʞ능을 적용할 Ʞ회가 거의 없닀는 것읎 맞습니닀. 귞러나 Close 작업에서 복구륌 분늬하멎 IMO에서 윔드가 닀소 깔끔핎집니닀.

func writeToGS(ctx context.Context, bucket, dst string, r io.Reader) (err error) {
        client := storage.NewClient(ctx) =? err { return err }
        defer client.Close()

        w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
        defer func() {
                if err != nil {
                        _ = w.CloseWithError(err)
                } else {
                        err = w.Close()
                }
        }()
        defer func() {
                recover() =? r {
                        err = fmt.Errorf("panic: %v", r)
                        panic(r)
                }
        }()

        io.Copy(w, r) =? err { return err }
        return nil
}

@jba 지연 처늬Ʞ는 닀시 팹닉: 닀륞 컎퓚터의 프로섞슀에 알늬렀고 시도하여 싀수로 잘못된 튞랜잭션을 컀밋하지 않도록 합니닀(잠재적읞 였류 상태에서 여전히 가능하닀고 가정). 귞것읎 ꜀ 음반적읎지 않닀멎 아마도 귞래알 할 것입니닀. Read/Write/Copy가 당황하지 ì•Šì•„ì•Œ 한닀는 데 동의하지만 ê·ž 안에 합늬적윌로 당황할 수 있는 닀륞 윔드가 있닀멎 ì–Žë–€ 읎유에서든 처음 시작했던 곳윌로 바로 돌아갈 수 있습니닀.

@bcmills ê·ž 마지막 개정판읎 더 좋아 볎입니닀 ( =? 빌도 정말)

@jba :

_ = io.Copy(w, r) =? err { _ = w.CloseWithError(err); return err }
return w.Close()

귞것은 여전히 ​​독자의 공황의 겜우륌 닀룚지 않습니닀. 분명히 읎것은 드묞 겜우읎지만 맀우 쀑요한 겜우입니닀. 팚닉읎 발생한 겜우 여Ʞ에서 Close륌 혞출하는 것은 맀우 나쁩니닀.

ê·ž 윔드는 규칙읎 아니띌 예왞입니닀. 우늬는 더 쉜게 작성할 수 있도록 Ʞ능을 섀계핎서는 안 됩니닀.

@jba : 저는 읎 겜우에 전적윌로 동의하지 않습니닀. 였류 처늬륌 올바륎게 하는 것읎 쀑요합니닀. ê°„ë‹ší•œ 겜우륌 더 쉜게 허용하멎 사람듀읎 적절한 였류 처늬에 대핮 생각하지 않게 됩니닀. errd 와 같읎 볎수적읞 였류 처늬륌 사소하게 쉜게 만드는 ì ‘ê·Œ 방식을 볎고 싶습니닀. 반멎에 규칙을 완화하Ʞ 위핎 앜간의 녞력읎 필요합니닀. 닀륞 방향윌로 조ꞈ읎띌도 움직읎지 ì•Šì•„ì•Œ 합니닀.

@jimmyfrasche : 귀하의 닚순화와 ꎀ렚하여 : 귀하가 대략 맞습니닀.

  • IsSentinel은 필수가 아니띌 펞늬하고 음반적입니닀. 나는 귞것을 떚얎뜚렞닀, 적얎도 지ꞈ은.
  • Err in State는 err곌 닀륎므로 API가 읎륌 삭제합니닀. 귞러나 읎핎에는 쀑요하지 않습니닀.
  • 핞듀러는 핚수음 수 있지만 대부분 성능상의 읎유로 읞터페읎슀입니닀. 팚킀지가 최적화되지 않윌멎 많은 사람듀읎 팚킀지륌 사용하지 않는닀는 것을 알고 있습니닀. (읎 혞의 errd에 대한 첫 번짞 의견을 찞조하십시였)
  • 맥띜읎 아쉜습니닀. AppEngine은 읎륌 필요로 하지만 ê·ž 왞에는 귞닀지 많지 않닀고 생각합니닀. 사람듀읎 죌저할 때까지 지지륌 제거하는 것읎 좋습니닀.

@mpvl 작동 방식, 사용 방법, ë‚Žê°€ 작성한 윔드에 얎떻게 맞을지 상상하Ʞ 쉜도록 몇 가지로

@jimmyfrasche : API가 귞렇게 할 것을 요구하지 않는닀멎 좋지만 읎핎합니닀. :)

@bcmills : 핞듀러는 예륌 듀얎 쀑요도에 따띌 몇 가지 용도로 사용됩니닀.

  • 였류륌 래핑
  • 였류륌 묎시하도록 정의(명시하게 만듀Ʞ 위핎. 예 ì°žì¡°)
  • 로귞 였류
  • 였류 메튞늭

닀시 쀑요도에 따띌 닀음곌 같읎 범위륌 지정핎알 합니닀.

  • 랔록
  • 띌읞
  • 팚킀지

Ʞ볞 였류는 였류가 얎딘가에서 처늬된닀는 것을 쉜게 볎장할 수 있도록 하Ʞ 위한 것입니닀.
하지만 랔록 수쀀윌로만 ì‚Ž 수 있었습니닀. 원래 핞듀러 대신 옵션읎 있는 API가 있었습니닀. ê·ž 결곌 더 느늬고 더 크고 서투륞 API가 생성되었습니닀.

나는 여Ʞ서 윜백 묞제가 귞렇게 나쁘닀고 볎지 않습니닀. 사용자는 였류가 있는 겜우 혞출되는 핞듀러륌 전달하여 Runner륌 정의합니닀. 특정 러너는 였류가 처늬되는 랔록에 명시적윌로 지정됩니닀. 많은 겜우 핞듀러는 읞띌읞윌로 전달된 음부 래핑된 묞자엎 늬터럎음 뿐입니닀. 나는 유용한 것곌 귞렇지 않은 것을 볎Ʞ 위핎 앜간의 플레읎륌 할 것입니닀.

BTW, 처늬Ʞ에서 로깅 였류륌 권장하지 ì•Šì•„ì•Œ 하는 겜우 컚텍슀튞 지원읎 쀑닚될 수 있습니닀.

@jba :

또한 회복읎 거Ʞ에 있얎알 하는지도 의묞입니닀. w.Write 또는 r.Read(또는 io.Copy!)가 팹닉 상태읞 겜우 종료하는 것읎 가장 좋습니닀.

writeToGS는 팚닉읎 발생하멎 종료되지만(!!!), nil읎 아닌 였류와 핚께 CloseWithError륌 혞출하는 것만 확읞합니닀. 팚닉읎 처늬되지 않윌멎 defer가 계속 혞출되지만 err == nil곌 핚께 결곌적윌로 잠재적윌로 손상된 파음읎 Cloud Storage에서 구첎화됩니닀. 여Ʞ서 í•Žì•Œ 할 올바륞 음은 음시적읞 였류와 핚께 CloseWithError륌 혞출한 닀음 팚닉을 계속하는 것입니닀.

Go 윔드에서 읎와 같은 예제륌 많읎 찟았습니닀. io.Pipes륌 닀룚는 것은 종종 앜간 너묎 믞묘한 윔드륌 쎈래합니닀. 였류륌 처늬하는 것은 종종 여러분읎 지ꞈ 볞 것처럌 간닚하지 않습니닀.

@bcmills

나는 ê·ž 예에서 @mpvl 의 복구 사용을 특히 좋아하지 않습니닀. ꎀ용적 제얎 흐늄볎닀 팚닉을 사용하도록 권장합니닀.

공황의 사용을 조ꞈ도 장렀하지 않습니닀. CloseWithError 직후에 팚닉읎 닀시 발생하므로 제얎 흐늄을 변겜하지 않습니닀. 팚닉은 팚닉윌로 ë‚šì•„ 있습니닀.
하지만 여Ʞ에서 복구륌 사용하지 않는 것은 잘못된 것입니닀. 팚닉읎 발생하멎 defer가 nil 였류와 핚께 혞출되얎 지ꞈ까지 작성된 낎용읎 컀밋될 수 있닀는 신혞가 발생하Ʞ 때묞입니닀.

여Ʞ에서 복구륌 사용하지 않는 닀소 유횚한 죌장은 임의의 늬더(읎 예에서 늬더가 알 수 없는 유형읞 읎유가 있음 :))의 겜우에도 팚닉읎 발생할 가능성읎 맀우 낮닀는 것입니닀.
귞러나 프로덕션 윔드의 겜우 읎는 용납할 수 없는 입장입니닀. 특히 충분히 큰 규몚로 프로귞래밍할 때 읎것은 ì–žì  ê°€ 발생할 수밖에 없습니닀(팚닉은 윔드의 버귞 읎왞의 닀륞 것윌로 읞핎 발생할 수 있음).

BTW, errd 팚킀지륌 사용하멎 사용자가 읎에 대핮 생각할 필요가 없습니닀. 귞러나 팚닉읎 발생한 겜우 였류륌 알늬는 닀륞 메컀니슘은 ꎜ찮습니닀. 공황 상태에서 연Ʞ륌 혞출하지 않는 것도 횚곌가 있지만 자첎 묞제가 있습니닀.

ì„ ì–ž 시점에서 현재 "값곌 였류"와 "값 또는 였류"륌 구별할 수 있는 방법은 없습니닀.

@bcmills 아,

func Atoi(string) ?int

대신에

func Atoi(string) (int, error)

귞러나 WriteString은 변겜되지 않은 상태로 유지됩니닀.

func WriteString(Writer, String) (int, error)

비슷한 제안볎닀 @bcmills / @jba 의 =? / =! / :=? / :=! 제안읎 더 좋습니닀. 몇 가지 좋은 속성읎 있습니닀.

  • 작성 가능 (당신읎 사용할 수있는 =? 낎에서 =? 랔록)
  • 음반(였류 유형에 국한되지 않고 0 값에만 ꎀ심)
  • 향상된 범위
  • defer와 핚께 작동할 수 있습니닀(위의 한 변형에서).

귞것은 또한 ë‚Žê°€ 멋지닀고 생각하지 않는 몇 가지 속성을 가지고 있습니닀.

컎포지션 둥지. 반복 사용은 계속핎서 였륞쪜윌로 갈수록 듀여쓰Ʞ가 됩니닀. 귞것읎 반드시 ê·ž 자첎로 나쁜 것은 아니지만, 였류륌 음윌킀는 였류륌 처늬핎알 하는 맀우 복잡한 였류 처늬가 있는 상황에서는 처늬할 윔드가 현재 상태볎닀 훚씬 덜 명확핎질 것읎띌고 상상합니닀. 읎러한 상황 하나에서 사용할 수있는 =? 바깥 쪜 였류 및 if err != nil 낎부 였류에륌하지만 음반적윌로하거나 음반적읞 겜우에 췚꞉읎 정말 향상 였류가? 음반적읞 겜우륌 개선하는 것읎 필요한 전부음 수도 있지만 개읞적윌로는 귞닀지 맀력적읎지 않습니닀.

귞것은 볎펞성을 얻Ʞ 위핎 얞얎에 거짓을 도입합니닀. 거짓을 "0 값읎 아님"윌로 정의하는 것은 완전히 합늬적읎지만 if err != nil { 가 명시적읎Ʞ 때묞에 if err { 볎닀 낫닀고 생각합니닀. 나는 =? /etc륌 사용하렀고 하는 비틀늌을 알생에서 볌 것윌로 예상합니닀. 더 자연슀러욎 제얎 흐늄을 통핎 거짓에 액섞슀하렀고 시도합니닀. 귞것은 확싀히 음방적읎고 눈삎을 찌푞늬게 할 것읎지만 귞것은 음얎날 것입니닀. Ʞ능의 잠재적 낚용은 ê·ž 자첎로 Ʞ능에 대한 녌쟁읎 아니지만 고렀핎알 할 사항입니닀.

개선된 범위 지정(핎당 맀개변수륌 선얞하는 변형의 겜우)은 겜우에 따띌 좋지만 범위 지정을 수정핎알 하는 겜우 음반적윌로 범위 지정을 수정합니닀.

"가장 였륞쪜에 있는 유음한 결곌" 의믞 첎계는 읎핎가 되지만 나에게는 조ꞈ 읎상핎 볎입니닀. 귞것은 녌쟁볎닀 감정입니닀.

읎 제안은 얞얎에 간결핚을 더하지만 추가적읞 힘은 없습니닀. 맀크로 확장을 수행하는 전처늬Ʞ로 완전히 구현될 수 있습니닀. 귞것은 묌론 바람직하지 않습니닀. 빌드와 조각 개발을 복잡하게 만듀고 귞러한 전처늬Ʞ는 유형을 읞식하고 위생적읎얎알 하Ʞ 때묞에 극도로 복잡할 것입니닀. 나는 "귞냥 전처늬Ʞ륌 만드십시였"띌고 말핚윌로썚 묎시하렀는 것읎 아닙니닀. 나는 읎 제안읎 전적윌로 섀탕읎띌는 점을 지적하Ʞ 위핎 읎것을 제Ʞ합니닀. 지ꞈ 바둑에서 할 수 없었던 음을 할 수 없습니닀. 더 간결하게 작성할 수 있습니닀. 나는 섀탕에 독닚적윌로 반대하지 않습니닀. 신쀑하게 선택한 얞얎적 추상화에는 힘읎 있지만 귞것읎 섀탕읎띌는 사싀은 말하자멎 묎죄가 입슝될 때까지 👎 고렀되얎알 핚을 의믞합니닀.

연산자의 lhs는 명령묞읎지만 명령묞의 맀우 제한된 하위 집합입니닀. 핎당 하위 집합에 포핚할 요소는 상당히 자명하지만 닀륞 것읎 없닀멎 변겜 사항을 수용하Ʞ 위핎 ì–žì–Ž 사양의 묞법을 늬팩토링핎알 합니닀.

뭔가 좋아할까

func F() (S, T, error)

func MustF() (S, T) {
  return F() =? err { panic(err) }
}

허용되닀?

만앜에

defer f.Close() :=? err {
    return err
}

(얎느 정도) 와 동등핎알 하는 것읎 허용됩니닀.

func theOuterFunc() (err error) {
  //...
  defer func() {
    if err2 := f.Close(); err2 != nil {
      err = err2
    }
  }()
  //...
}

읎는 맀우 묞제가 있고 맀우 혌란슀러욎 상황을 유발할 가능성읎 있윌며, 맀우 비정상적윌로 큎로저륌 암시적윌로 할당하는 성능 영향을 숚ꞎ닀는 사싀을 묎시합니닀. 대안은 것입니닀 return 암시 적 폐쇄에서 수익을 한 닀음 유형의 값을 반환 할 수 없닀는 였류 메시지가 error A로부터 func() 있는 앜간입니닀 묎딘.

사싀, 앜간 개선된 범위 수정을 제왞하고는 Go에서 였류륌 처늬하는 데 직멎한 묞제륌 핎결하지 못합니닀. Ʞ껏핎알 if err != nil { return err } 륌 입력하는 것은 성가신 음읎며, #21182에서 표현한 앜간의 가독성 묞제륌 몚듈화합니닀. 두 가지 가장 큰 묞제는

  1. 였류륌 처늬하는 방법에 대핮 생각하고 있윌며 읎에 대핮 ì–žì–Žê°€ 할 수 있는 음은 없습니닀.
  2. ì–Žë–€ 상황에서 묎엇을 í•Žì•Œ 할지 결정하Ʞ 위핎 였류륌 검사하는 것 - errors 팚킀지의 지원곌 핚께 음부 추가 규칙은 여Ʞ에서 뚌 Ꞟ을 갈 수 있지만 몚든 묞제륌 í•Žê²°í•  수는 없습니닀.

나는 귞것읎 유음한 묞제가 아니며 많은 사람듀읎 닀륞 잡멎을 더 슉각적윌로 우렀한닀는 것을 알고 있지만, 귞것듀은 ë‚Žê°€ 가장 많은 시간을 볎낎고 닀륞 ì–Žë–€ 것볎닀 더 성가시고 곚칫거늬읞 것입니닀.

ë‚Žê°€ 묎얞가륌 망쳀을 때 감지하는 더 나은 정적 분석은 묌론 (귞늬고 음반적윌로 읎 시나늬였뿐만 아니띌) 항상 감사할 것입니닀. 소슀륌 더 쉜게 분석할 수 있도록 하는 ì–žì–Ž 변겜 및 규칙도 흥믞로욞 것입니닀.

방ꞈ 읎것에 대핮 많은 Ꞁ을 썌지만(정말 많읎! 죄송합니닀!) ê·ž 제안을 Ʞ각하지는 않습니닀. 나는 귞것읎 장점읎 있닀고 생각하지만 귞것읎 막대륌 제거하거나 묎게륌 끌얎당Ʞ는지 확신하지 못합니닀.

@jimmyfrasche

:=의 현재 동작읎 도입되었을 때륌 Ʞ억합니닀. 많은 슀레드가 암시적읞 "변수가 정확히 현재 범위에 있는 겜우에만 재사용" 대신 재사용할 읎늄에 명시적윌로 죌석을 달Ʞ 위한 방법을 요구했습니닀. " 낮 겜험상 볎Ʞ 힘든 몚든 믞묘한 묞제가 나타나는 곳입니닀.

† 링크가 있는 슀레드륌 찟을 수 없습니까?

Go가 출시되었을 때 Go에 찞여하지 않았닀멎 닀륞 슀레드륌 Ʞ억하고 계싀 것입니닀. 출시 직전읞 2009/11/9의 사양은 닀음곌 같습니닀.

음반 변수 선얞곌 달늬 짧은 변수 선얞은 변수가 원래 동음한 유형의 동음한 랔록에서 선얞되었고 공백읎 아닌 변수 쀑 하나 읎상읎 새로욎 겜우 변수륌 닀시 ì„ ì–ží•  수 있습니닀.

나는 처음윌로 사양을 읜었을 때 귞것읎 훌륭한 규칙읎띌고 생각했던 것을 Ʞ억합니닀. 읎전에 :=가 있는 얞얎륌 사용했지만 ê·ž 재사용 규칙 없읎 동음한 것에 대한 새 읎늄을 생각하는 것은 지룚했습니닀.

@mpvl
나는 당신의 원래 예의 까닀로움읎 더 많은 결곌띌고 생각합니닀.
Go의 였류 처늬 자첎볎닀 거Ʞ에서 사용하는 API.

특히 흥믞로욎 예입니닀.
팚닉읎 발생하멎 파음을 정상적윌로 닫고 싶지 않윌므로
정상적읞 "defer w.Close()" ꎀ용구가 작동하지 않습니닀.

닀음읎 있을 때 Close 혞출을 플할 필요가 없닀멎
공황 상태에서 닀음을 수행할 수 있습니닀.

func writeToGS(ctx context.Context, bucket, dst string, r io.Reader) (err error) {
    client, err := storage.NewClient(ctx)
    if err != nil {
        return err
    }
    defer client.Close()

    w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
    defer w.Close()
    _, err = io.Copy(w, r)
    if err != nil {
        w.CloseWithError(err)
    }
    return err
}

Close륌 혞출하도록 의믞가 변겜되었닀고 가정합니닀.
CloseWithError륌 혞출한 후에는 작동하지 않습니닀.

더 읎상 귞렇게 나쁘게 볎읎지 않는 것 같아요.

팚닉읎 있을 때 파음읎 였류 없읎 작성되지 않는닀는 요구 사항읎 있더띌도 수용하Ʞ에는 너묎 얎렵지 ì•Šì•„ì•Œ 합니닀. 예륌 듀얎 Close 전에 명시적윌로 혞출핎알 하는 Finalize 핚수륌 추가합니닀.

    w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
    defer w.Close()
    _, err = io.Copy(w, r)
    return w.Finalize(err)

하지만 팹닉 였류 메시지륌 첚부할 수는 없지만 적절한 로깅을 통핎 읎륌 더 명확하게 만듀 수 있습니닀.
(Close 메서드는 낎부에 복구 혞출읎 있을 수도 있지만 귞게 맞는지는 확싀하지 않습니닀.
사싀 정말 나쁜 생각입니닀...)

귞러나 였류 처늬의 99% 읎상의 겜우가 팹닉 복구륌 수행하지 ì•Šêž° 때묞에 읎 예의 팹닉 복구 잡멎은 읎 컚텍슀튞에서 닀소 적청읎띌고 생각합니닀.

@rogpeppe :

하지만 팹닉 였류 메시지륌 첚부할 수는 없지만 적절한 로깅을 통핎 읎륌 더 명확하게 만듀 수 있습니닀.

나는 귞것읎 묞제띌고 생각하지 않는닀.

제안된 API 변겜은 완화되지만 아직 묞제륌 완전히 핎결하지는 못합니닀. 필요한 의믞 첎계륌 사용하렀멎 닀륞 윔드도 제대로 작동핎알 합니닀. 아래 예륌 고렀하십시였.

r, w := io.Pipe()
go func() {
    var err error                // used to intercept downstream errors
    defer func() {
        w.CloseWithError(err)
    }()

    r, err := newReader()
    if err != nil {
        return
    }
    defer func() {
        if errC := r.Close(); errC != nil && err == nil {
            err = errC
        }
    }
    _, err = io.Copy(w, r)
}()
return r

ê·ž 자첎로 읎 윔드는 였류 처늬가 까닀롭거나 적얎도 지저분하닀는 것을 볎여쀍니닀(귞늬고 닀륞 제안윌로 읎것읎 얎떻게 개선될 수 있는지 궁ꞈ합니닀): 읎 윔드는 닀욎슀튞늌 였류륌 변수륌 통핎 은밀하게 전달하며 앜간의 였류가 있습니닀. clunky if 묞을 사용하여 올바륞 였류가 전달되었는지 확읞합니닀. 둘 ë‹€ "비슈니슀 녌늬"에서 너묎 많은 죌의륌 산만하게 합니닀. 였류 처늬가 윔드륌 지배합니닀. 귞늬고 읎 예제는 아직 팚닉을 처늬하지도 않습니닀.

완전성을 위핎 errd 읎것은 _공황을 올바륎게 처늬하고 닀음곌 같읎 볎음 것입니닀.

r, w := io.Pipe()
go errd.Run(func(e *errd.E) {
    e.Defer(w.CloseWithError)

    r, err := newReader()
    e.Must(err)
    e.Defer(r.Close)

    _, err = io.Copy(w, r)
    e.Must(err)
})
return r

위의 판독Ʞ( errd 사용하지 않음)가 판독Ʞ로 writeToGS에 전달되고 newReader에서 반환된 io.Reader 팚닉읎 발생하멎 제안된 API 수정곌 핚께 여전히 잘못된 의믞 첎계가 발생합니닀(성공적윌로 닫을 수 있습니닀. nil 였류와 핚께 팹닉 시 파읎프가 닫힌 후 GS 파음.)

읎것은 또한 요점을 슝명합니닀. Go에서 적절한 였류 처늬에 대핮 추론하는 것은 간닚하지 않습니닀. errd 하여 윔드륌 닀시 작성하는 방법을 삎펎볎니 버귞가 많은 윔드륌 발견했습니닀. 귞러나 errd 팚킀지에 대한 닚위 테슀튞륌 작성할 때 적절한 ꎀ용적 Go 였류 처늬륌 작성하는 것읎 얌마나 얎렵고 믞묘한 것읞지 배웠습니닀. :)

제안된 API 변겜에 대한 대안은 팹닉 시 지연을 전혀 처늬하지 않는 것입니닀. 읎것은 고유한 묞제가 있고 묞제륌 완전히 핎결하지 못하고 아마도 싀행 췚소할 수 있지만 몇 가지 좋은 특성읎 있습니닀.

얎느 쪜읎든, 간결핚에 쎈점을 맞추는 것볎닀 였류 처늬의 믞묘핚을 완화하는 ì–žì–Ž 변겜읎 가장 좋습니닀.

@mpvl
나는 종종 Go의 였류 처늬 윔드에서 닀륞 핚수륌 생성하멎 정늬할 수 있닀는 것을 알게 됩니닀. 위의 윔드륌 닀음곌 같읎 작성합니닀.

func something() {
    r, w := io.Pipe()
    go func() {
        err := copyFromNewReader(w)
        w.CloseWithError(err)
    }()
    ...
}

func copyFromNewReader(w io.Writer) error {
    r, err := newReader()
    if err != nil {
        return err
    }
    defer r.Close()
    _, err = io.Copy(w, r)
    return err
}()

r.Close가 유용한 였류륌 반환하지 않는닀고 가정합니닀. 독자륌 끝까지 읜었고 io.EOF만 발견했닀멎 닫힐 때 였류륌 반환하더띌도 거의 확싀하게 묞제가 되지 않습니닀.

나는 errd API에 ꎀ심읎 없습니닀. 시작되는 고룚틎에 너묎 믌감합니닀. 예: https://play.golang.org/p/iT441gO5us doSomething읎 고룚틎을 싀행하여 싀행하는지 여부
핚수 입력은 프로귞랚의 정확성에 영향을 믞치지 ì•Šì•„ì•Œ 하지만 errd륌 사용할 때는 영향을 믞칩니닀. 추상화 겜계륌 안전하게 가로지륎는 팚닉을 예상하고 있지만 Go에서는 귞렇지 않습니닀.

@mpvl

w.CloseWithError(err) ì—°êž°

BTW, 읎 쀄은 항상 nil 였류 값윌로 CloseWithError륌 혞출합니닀. 나는 당신읎 의도 한 것 같아요
ì“°ë‹€:

defer func() { 
   w.CloseWithError(err)
}()

@mpvl

io.Reader 에 대핮 Close 메서드에서 반환된 였류는 거의 유용하지 않습니닀(https://github.com/golang/go/issues/20803#issuecomment-312318808의 목록 ì°žì¡°). ).

귞것은 우늬가 였늘 당신의 예륌 닀음곌 같읎 작성핎알 핚을 시사합니닀.

r, w := io.Pipe()
go func() (err error) {
    defer func() { w.CloseWithError(err) }()

    r, err := newReader()
    if err != nil {
        return err
    }
    defer r.Close()

    _, err = io.Copy(w, r)
    return err
}()
return r

...조ꞈ 장황한 것을 제왞하고는 완벜하게 ꎜ찮아 볎입니닀.

팚닉의 겜우 w.CloseWithError 에 nil 였류륌 전달하는 것읎 사싀읎지만 얎욌든 전첎 프로귞랚은 ê·ž 지점에서 종료됩니닀. nil 였류로 닫지 않는 것읎 쀑요하닀멎 ê°„ë‹ší•œ 읎늄 바꟞Ʞ에 한 쀄을 추가하멎 됩니닀.

-go func() (err error) {
-   defer func() { w.CloseWithError(err) }()
+go func() (rerr error) {
+   rerr = errors.New("goroutine exited by panic")
+   defer func() { w.CloseWithError(rerr) }()

@rogpeppe : 정말 감사합니닀. :)

예, 고룚틎 묞제륌 알고 있습니닀. 귞것은 불쟌하지만 아마도 수의사 검사로 ìž¡êž°ê°€ 얎렵지 않은 것입니닀. 얎욌든 저는 errd륌 최종 솔룚션윌로 볎지 않고 였류 처늬륌 가장 잘 처늬하는 방법에 대한 겜험을 얻는 방법윌로 뎅니닀. 읎상적윌로는 동음한 묞제륌 핎결하지만 적절한 제한읎 부곌되는 ì–žì–Ž 변겜읎 있을 것입니닀.

추상화 겜계륌 안전하게 가로지륎는 팚닉을 예상하고 있지만 Go에서는 귞렇지 않습니닀.

귞것은 ë‚Žê°€ Ʞ대하는 것읎 아닙니닀. 읎 겜우 API가 성공을 볎고하지 않았을 때 볎고하지 않을 것윌로 예상합니닀. 마지막 윔드 조각은 작성자에 대핮 defer륌 사용하지 ì•Šêž° 때묞에 올바륎게 처늬합니닀. 귞러나 읎것은 맀우 믞묘합니닀. 많은 사용자는 ꎀ용적읞 것윌로 간죌되Ʞ 때묞에 읎 겜우 defer륌 사용합니닀.

음렚의 수의사 검사로 묞제가 있는 ì—°êž° 사용을 포착할 수 있습니닀. 귞래도 원래의 "ꎀ용적" 윔드와 마지막윌로 늬팩토링된 윔드에는 맀우 ê°„ë‹ší•œ 윔드 조각에 대한 였류 처늬의 믞묘핚을 핎결하Ʞ 위핎 많은 수정 작업읎 있습니닀. í•Žê²° 방법 윔드는 특정 였류 사례륌 처늬하는 방법을 알아낎Ʞ 위한 것읎 아니띌 생산적읞 용도로 사용할 수 있는 순전히 두뇌 순환의 낭비입니닀.

특히 errd 에서 배우렀고 하는 것은 직접 사용할 때 였류 처늬륌 더 간닚하게 만드는지 여부입니닀. ë‚Žê°€ 볌 수있는 것에서 많은 합병슝곌 믞묘핚읎 사띌집니닀. 의믞론의 잡멎을 새로욎 ì–žì–Ž Ʞ능윌로 첎계화할 수 있는지 확읞하는 것읎 좋습니닀.

@jimmyfrasche

귞것은 볎펞성을 얻Ʞ 위핎 얞얎에 거짓을 도입합니닀.

아죌 좋은 지적입니닀. 거짓곌 ꎀ렚된 음반적읞 묞제는 부욞 핚수륌 혞출하는 것을 잊거나 nil에 대한 포읞터륌 역찞조하는 것을 잊는 데서 발생합니닀.

(낙하 아마 우늬는 nillable로 유형 만 작업에 연산자륌 정의하여 후자륌 í•Žê²°í•  수 =! 가 대부분 쓞몚가있을 것읎Ʞ 때묞에, 결곌적윌로).

핚수 유형곌 핚께 작동하지 않거나 포읞터 또는 읞터페읎슀 유형에서만 작동하도록 전자륌 추가로 제한하여 전자륌 í•Žê²°í•  수 있습니닀. 귞러멎 변수가 부욞읎 아니띌는 것읎 분명하고 부욞 비교에 사용하렀는 시도가 더 많을 것입니닀. 분명히 잘못되었습니닀.

[ MustF ] 같은 것읎 허용됩니까?

예.

[ defer f.Close() :=? err { ]가 허용되멎 (얎느 정도) 닀음곌 같아알 합니닀.
[ defer func() { 
 }() ].

반드시 귞렇지는 않습니닀. 고유한 의믞륌 가질 수 있습니닀(익명 핚수볎닀 call/cc 와 비슷핚). ë‚Žê°€ 사용하Ʞ위한 사양 변겜을 제안하지 않은 =? 에서 defer 확싀 정확히 같은 정의가 될 복잡한 방법읎 아니에요, 귞래서 (읎것은 묞법 적얎도 변화륌 요구한닀) .

두 가지 가장 큰 묞제는 [
]

나는 귞것읎 싀제로 더 큰 묞제띌는 데 동의하지만 읎 묞제와 닀소 직교하는 것처럌 볎입니닀(읎는 상용구 및 ꎀ렚 였류 가능성을 쀄읎는 것에 ꎀ한 것입니닀).

( @rogpeppe , @davecheney , @dsnet , @crawshaw , 저, 귞늬고 제가 분명히 잊고 있는 몇몇 닀륞 사람듀은 GopherCon에서 였류 검사륌 위한 API에 대핮 좋은 토론을 했습니닀. 귞늬고 우늬도 ê·ž 잡멎에서 좋은 제안을 볌 수 있Ʞ륌 바랍니닀. , 귞러나 나는 정말로 닀륞 묞제에 대한 묞제띌고 생각합니닀.)

@bcmills : 읎 윔드에는 1) @rogpeppe가 얞꞉한 것곌 같은 두 가지 묞제가 있습니닀. CloseWithError에 전달된 err은 항상 nil읎고 2) 여전히 팚닉을 처늬하지 않윌므로 팚닉읎 있을 때 API가 명시적윌로 성공을 볎고합니닀. 반환된 r은 1읎 고정된 겜우에도 몚든 바읎튞가 Ʞ록되지 않은 겜우에도 io.EOF륌 방출할 수 있습니닀.

귞렇지 않윌멎 Close에서 반환된 였류가 종종 묎시될 수 있닀는 데 동의합니닀. 귞러나 항상 귞런 것은 아닙니닀(첫 번짞 예 ì°žì¡°).

제 닀소 ê°„ë‹ší•œ 예(나 자신의 것 포핚)에 4~5개의 잘못된 제안읎 있었닀는 것읎 닀소 놀랍고 여전히 Go의 였류 처늬가 사소하지 않닀고 죌장핎알 하는 것 같습니닀. :)

@bcmills :

팚닉의 겜우 w.CloseWithError에 nil 였류륌 전달하는 것읎 사싀읎지만 전첎 프로귞랚은 얎욌든 ê·ž 지점에서 종료됩니닀.

합니까? ê·ž 고룚틎의 연Ʞ는 여전히 혞출됩니닀. ë‚Žê°€ 읎핎하는 한 귞듀은 완료될 것입니닀. 읎 겜우 Close는 io.EOF에 신혞륌 볎냅니닀.

예륌 듀얎 https://play.golang.org/p/5CFbsAe8zF륌 찞조하십시였. 고룚틎 팹닉 후에 여전히 "foo"륌 닀륞 고룚틎에 행복하게 전달한 닀음 여전히 Stdout에 쓰도록 합니닀.

유사하게, 닀륞 윔드는 팹닉하는 고룚틎(귀하의 예와 같은)에서 잘못된 io.EOF륌 수신하고, 성공을 결론지윌며, 팹닉하는 고룚틎읎 팚닉을 재개하Ʞ 전에 행복하게 GS에 파음을 컀밋할 수 있습니닀.

닀음 죌장은 닀음곌 같습니닀. 버귞가 있는 윔드륌 작성하지 마십시였. 하지만:

  • 귞런 닀음 읎러한 버귞륌 더 쉜게 방지하고
  • 팚닉은 OOM곌 같은 왞부 요읞윌로 읞핎 발생할 수 있습니닀.

nil 였류로 닫지 않는 것읎 쀑요하닀멎 ê°„ë‹ší•œ 읎늄 바꟞Ʞ에 한 쀄을 추가하멎 됩니닀.

완료되멎 io.EOF에 신혞륌 볎낎Ʞ 위핎 여전히 nil로 ë‹«ì•„ì•Œ 하므로 작동하지 않습니닀.

nil 였류로 닫지 않는 것읎 쀑요하닀멎 ê°„ë‹ší•œ 읎늄 바꟞Ʞ에 한 쀄을 추가하멎 됩니닀.

완료되멎 io.EOF에 신혞륌 볎낎Ʞ 위핎 여전히 nil로 ë‹«ì•„ì•Œ 하므로 작동하지 않습니닀.

왜 안 돌? return err 끝에 rerr 가 nil 됩니닀.

@bcmills : 아 묎슚 말읞지 읎제 알겠얎요. 예, 작동핎알 합니닀. 하지만 저는 쀄 수가 아니띌 윔드의 믞묘핚에 대핮 걱정하고 있습니닀.

나는 읎것읎 변수 섀도잉곌 같은 묞제 범죌에 속한닀는 것을 알았습니닀. 닚지 덜 싀행될 가능성읎 더 낮았을 뿐읎었습니닀. 임의적읞 공황은 테슀튞하Ʞ가 더 얎렵습니닀.

대규몚로 욎영할 때 읎와 같은 버귞가 나타나는 것읎 거의 볎장됩니닀. 펞집슝읎 있을 수 있지만 데읎터 손싀 및 손상윌로 읎얎질 가능성읎 훚씬 적은 시나늬였륌 볎았습니닀. 음반적윌로 읎것은 ꎜ찮지만 튞랜잭션 처늬(예: gs 파음 작성)에는 적합하지 않습니닀.

나는 당신읎 당신의 제안을 대첎 구묞윌로 가로채는 것에 신겜쓰지 않Ʞ륌 바랍니닀. 사람듀은 닀음곌 같은 것에 대핮 얎떻게 생각할까요?

return err if f, err := os.Open("..."); err != nil

@SirCmpwn 귞것은 lede륌 묻습니닀. 핚수에서 읜Ʞ 가장 쉬욎 것은 였류 처늬가 아니띌 정상적읞 제얎 흐늄읎얎알 합니닀.

귞걎 공평하지만, 당신의 제안은 저륌 불펞하게 만듀Ʞ도 합니닀 - 귞것은 사용자가 예상하도록 훈령된 방식곌 닀륎게 동작하는 불투명한 구묞(||)을 도입합니닀 || 행동하는. 올바륞 솔룚션읎 묎엇읞지 확싀하지 않은 겜우 더 고믌할 것입니닀.

@SirCmpwn 예, 원래 게시묌에서 말했듯읎 "읎 제안은 죌로 Go 였류 처늬륌 닚순화하렀는 사람듀읎 수정되지 않은 였류륌 반환하는 것읎 아니띌 였류 죌위에 컚텍슀튞륌 쉜게 감쌀 수 있는 방법에 대핮 생각하도록 권장하Ʞ 위핎 작성합니닀. ." 나는 낮 제안을 가능한 한 잘 썌지만 귞것읎 채택될 것읎띌고 Ʞ대하지 않습니닀.

읎핎했닀.

읎것은 좀 더 ꞉진적읎지만 맀크로 êž°ë°˜ ì ‘ê·Œ 방식읎 더 잘 작동할 수 있습니닀.

f = try!(os.Open("..."))

try! 는 튜플의 마지막 값을 뚹고 nil읎 아니멎 반환하고, 귞렇지 않윌멎 나뚞지 튜플을 반환합니닀.

나는 우늬의 묞제 진술읎,

Go의 였류 처늬는 장황하고 반복적입니닀. Go의 였류 처늬의 ꎀ용적 형식은 였류가 아닌 제얎 흐늄을 볎는 것을 더 얎렵게 만듀고 장황한 낎용은 특히 신규 사용자에게 맀력적읎지 않습니닀. 현재까지 읎 묞제에 대핮 제안된 솔룚션은 음반적윌로 숙렚된 음회성 였류 처늬 Ʞ능을 필요로 하고 였류 처늬의 지역성을 쀄읎고 복잡성을 슝가시킵니닀. Go의 목표 쀑 하나는 작성자가 였류 처늬 및 복구륌 고렀하도록 하는 것읎Ʞ 때묞에 였류 처늬에 대한 개선도 ê·ž 목표륌 Ʞ반윌로 í•Žì•Œ 합니닀.

읎 묞제륌 핎결하Ʞ 위핎 Go 2.x의 였류 처늬 개선을 위한 닀음 목표륌 제안합니닀.

  1. 반복적읞 였류 처늬 상용구륌 쀄읎고 윔드 겜로의 죌요 의도에 최대한 집쀑합니닀.
  2. 였류륌 전파할 때 였류륌 래핑하는 것을 포핚하여 적절한 였류 처늬륌 권장합니닀.
  3. 명확성곌 닚순성의 Go 디자읞 원칙을 쀀수합니닀.
  4. 가능한 가장 ꎑ범위한 였류 처늬 상황에 적용할 수 있습니닀.

읎 제안 평가:

f.Close() =? err { return fmt.Errorf(
, err) }

ê·ž 목표듀에 따륎멎, 나는 귞것읎 목표 #1에서 잘 성공했닀고 결론지을 것입니닀. 읎것읎 #2에 얎떻게 도움읎 되는지 잘 몚륎겠지만 컚텍슀튞륌 추가할 가능성도 쀄얎듀지 않습니닀(낮 제안은 #2에서 읎 앜점을 공유했습니닀). 하지만 3번곌 4번에서는 성공하지 못합니닀.
1) 닀륞 사람듀읎 말했듯읎 였류 값 확읞 및 할당은 불투명하고 비정상적입니닀. 귞늬고
2) =? 구묞도 특읎합니닀. 비슷하지만 닀륞 =! 구묞곌 결합하멎 특히 혌란슀럜습니닀. 사람듀읎 ê·ž 의믞에 익숙핎지는 데 시간읎 걞늎 것입니닀. 귞늬고
3) 였류와 핚께 유횚한 값을 반환하는 것은 몚든 새 솔룚션에서도 핎당 겜우륌 처늬핎알 할 만큌 음반적입니닀.

였류 처늬륌 랔록윌로 만드는 것은 좋은 생각음 수 있지만 닀륞 사람듀읎 제안한 대로 gofmt 에 대한 변겜 사항곌 결합된 겜우입니닀. 낮 제안에 비핎 음반성읎 향상되얎 목표 #4에 도움읎 되고 친숙도가 향상되얎 목표 #3에 도움읎 되지만 컚텍슀튞가 추가되얎 닚순히 였류륌 반환하는 음반적읞 겜우에 대핮 간결핚을 희생합니닀.

쎈록에서 저에게 질묞했닀멎 위의 였류 처늬 개선 목표륌 충족하는 한 였류 처늬 특정 솔룚션볎닀 더 음반적읞 솔룚션읎 더 낫닀는 데 동의했을 것입니닀. 귞러나 읎제 읎 토론을 읜고 더 많읎 생각한 결곌 였류 처늬 특정 솔룚션읎 더 명확하고 닚순하게 결곌륌 가젞올 것읎띌고 믿는 겜향읎 있습니닀. Go의 였류는 값음 뿐읎지만 였류 처늬는 였류 처늬 윔드륌 명확하고 간결하게 만드는 특정 구묞읎 있는 프로귞래밍의 쀑요한 부분을 구성합니닀. 범위 지정 및 구성 가능성곌 같은 닀륞 목표와 병합하멎 읎믞 얎렀욎 묞제(였류 처늬륌 위한 깚끗한 솔룚션을 제공하는 것)륌 훚씬 더 얎렵고 복잡하게 만듀 것입니닀.

귞럌에도 불구하고 @rsc 가 자신의 Ʞ사 Toward Go 2 에서 지적했듯읎 묞제 섀명, 목표 또는 구묞 제안은 묞제가 쀑요하닀는 것을 볎여죌는 겜험 볎고서 없읎는 진전되지 않을 것입니닀. 닀양한 구묞 제안에 대핮 토론하는 대신 지원 데읎터륌 ì°Ÿêž° 시작핎알 할까요?

귞럌에도 불구하고 @rsc 가 자신의 Ʞ사 Toward Go 2에서 지적했듯읎 묞제 섀명, 목표 또는 구묞 제안은 묞제가 쀑요핚을 볎여죌는 겜험 볎고서 없읎는 진전되지 않을 것입니닀. 닀양한 구묞 제안에 대핮 토론하는 대신 지원 데읎터륌 파헀쳐알 할까요?

읞첎 공학읎 쀑요하닀고 가정하멎 읎것은 자명하닀고 생각합니닀. Go 윔드베읎슀륌 ì—Žê³  ì–žì–Žê°€ 처늬할 수 있는 작업을 걎조하거나 읞첎 공학을 개선할 Ʞ회가 있는 곳을 찟윌십시였. 현재 였류 처늬는 명백한 읎상값입니닀. 나는 Toward Go 2 ì ‘ê·Œ 방식읎 í•Žê²° 방법읎 있는 묞제륌 묎시하도록 잘못 옹혞할 수 있닀고 생각합니닀. 읎 겜우 사람듀은 ê·žì € 웃윌멎서 찞습니닀.

if $val, err := $operation($args); err != nil {
  return err
}

윔드볎닀 상용구가 많을 때 묞제는 자명합니닀.

@billyh

f.Close() =? err { return fmt.Errorf(
, err) } 형식읎 너묎 장황하고 혌란슀럜닀고 생각합니닀. 나는 개읞적윌로 였류 부분읎 랔록에 있얎알 한닀고 생각하지 않습니닀. 필연적윌로 1쀄읎 아닌 3쀄로 나누얎지게 됩니닀. 또한 였류륌 반환하Ʞ 전에 였류륌 수정하는 것 읎상을 수행핎알 하는 였프 변겜에서 현재 if err != nil { ... } 사용할 수 있습니닀

=? 연산자도 앜간 혌란슀럜습니닀. 귞곳에서 묎슚 음읎 음얎나고 있는지 슉시 알 수 없습니닀.

닀음곌 같읎:
file := os.Open("/some/file") or raise(err) errors.Wrap(err, "extra context")
또는 앜얎:
file := os.Open("/some/file") or raise
귞늬고 연Ʞ된:
defer f.Close() or raise(err2) errors.ReplaceIfNil(err, err2)
좀 더 장황하고 닚얎륌 선택하멎 쎈Ʞ 혌란을 쀄음 수 있습니닀(슉, 사람듀은 raise 을 Python곌 같은 닀륞 얞얎의 유사한 킀워드와 슉시 연ꎀ시킀거나, 닚지 제Ʞ가 였류/마지막 비-비륌 발생시킀는 것윌로 추론할 수 있습니닀. 혞출자에게 슀택을 Ʞ볞값윌로 섀정).

또한 태양 아래에서 가능한 몚든 몚혞한 였류 처늬륌 핎결하렀고 시도하지 않는 좋은 명령형 솔룚션입니닀. 지ꞈ까지 알생에서 가장 큰 였류 처늬 덩얎늬는 위에서 얞꞉한 특성입니닀. 나쀑을 위핎 현재 구묞도 도움읎 됩니닀.

펞집하닀:
"마법"을 조ꞈ 쀄읎렀멎 읎전 예제도 닀음곌 같을 수 있습니닀.
file, err := os.Open("/some/file") or raise errors.Wrap(err, "extra context")
file, err := os.Open("/some/file") or raise err
defer err2 := f.Close() or errors.ReplaceIfNil(err, err2)
저는 개읞적윌로 읎전 예제가 여Ʞ에서처럌 분할하는 대신 전첎 였류 처늬륌 였륞쪜윌로 읎동하Ʞ 때묞에 더 낫닀고 생각합니닀. 귞러나 읎것은 더 명확할 수 있습니닀.

나는 우늬의 묞제 진술읎, ...

묞제 진술에 동의하지 않습니닀. 대안을 제안하고 싶습니닀.


얞얎적 ꎀ점에서 였류 처늬는 졎재하지 않습니닀. Go가 제공하는 유음한 것은 믞늬 선얞된 였류 유형읎며 싀제로 새로욎 것을 가능하게 하지 ì•Šêž° 때묞에 펞의륌 위한 것입니닀. 였류는 값음 뿐입니닀 . 였류 처늬는 음반적읞 사용자 윔드입니닀. ì–žì–Ž POV에서 귞것에 대핮 특별한 것은 없윌며 귞것에 대핮 특별한 것읎 없얎알합니닀. 였류 처늬의 유음한 묞제는 음부 사람듀읎 읎 가치 있고 아늄닀욎 닚순성을 ì–Žë–€ 희생을 치륎더띌도 제거핎알 한닀고 생각한닀는 것입니닀.

Cznic읎 말한 대로 였류 처늬 읎상에 유용한 솔룚션읎 있윌멎 좋을 것입니닀.

였류 처늬륌 볎닀 음반적윌로 만드는 한 가지 방법은 통합 유형/합 유형 및 래핑 í•Žì œ 잡멎에서 생각하는 것입니닀. Swift와 Rust는 둘 ë‹€ ? ! 비록 Rust가 앜간 불안정하닀고 생각하지만.

합계 유형을 높은 수쀀의 개념윌로 만듀고 싶지 않닀멎 튜플읎 싀제로 Go의 음부가 아닌 방식윌로 닀쀑 반환의 음부로 만듀 수 있지만 여전히 닀쀑 반환을 수행할 수 있습니닀.

Swift에서 영감을 받은 구묞 분석:

func Failable() (*Thingie | error) {
    ...
}

guard thingie, err := Failable() else { 
    return wrap(err, "Could not make thingie)
}
// err is not in scope here

닀음곌 같은 닀륞 용도로도 사용할 수 있습니닀.

guard val := myMap[key] else { val = "default" }

@bcmills 와 @jba 가 제안한 =? 솔룚션은 였류륌 위한 것읎 아니띌 0읎 아닌 개념을 위한 것입니닀. 읎 예는 정상적윌로 작동합니닀.

func Foo()(Bar, Recover){}
bar := Foo() =? recover { log.Println("[Info] Recovered:", recover)}

읎 제안의 죌요 아읎디얎는 읜Ʞ 쉜도록 사읎드 녾튾, 윔드의 죌요 목적을 분늬하고 부찚적읞 겜우는 따로 두는 것입니닀.
나에게 Go 윔드륌 읜는 것은 ì–Žë–€ 겜우에는 연속적읎지 않습니닀. 여러 번 if err!= nil {return err} 하여 쀑지 아읎디얎륌 @jba 토크 )
맀우 드묞 상황에서 였류는 Ʞ능의 죌요 목적읎며 아마도 복구에 있을 수 있습니닀. 음반적윌로 였류가 발생하멎 컚텍슀튞, 로귞 및 반환을 추가합니닀. 읎러한 겜우 볎조 메몚륌 통핎 윔드륌 더 읜Ʞ 쉜게 만듀 수 있습니닀.
가장 좋은 구묞읞지는 몚륎겠지만 특히 두 번짞 부분의 랔록읎 마음에 듀지 않습니닀. 볎조 메몚는 ìž‘ì•„ì•Œ 하고 한 쀄읎멎 충분핎알 합니닀.

bar := Foo() =? recover: log.Println("[Info] Recovered:", recover)

@billyh

  1. 닀륞 사람듀읎 말했듯읎 였류 값 확읞 및 할당은 불투명하고 읎례적입니닀. 귞늬고

좀 더 구첎적윌로 말씀핎 죌십시였. "불투명하고 특읎한" 것은 지극히 죌ꎀ적입니닀. 제안읎 혌동될 수 있닀고 생각되는 윔드의 몇 가지 예륌 제시할 수 있습니까?

  1. =? 구묞도 비정상적입니닀. [
]

IMO ê·ž Ʞ능입니닀. 누군가 비정상적읞 연산자륌 볞닀멎 정확할 수도 있고 정확하지 않을 수도 있는 묎얞가륌 가정하는 대신 ê·ž 연산자가 수행하는 작업을 찟는 겜향읎 더 크닀고 생각합니닀.

  1. 였류와 핚께 유횚한 값을 반환하는 것은 몚든 새 솔룚션에서도 핎당 사례륌 처늬핎알 할 만큌 음반적입니닀.

귞렇습니닀?

제안을 죌의 깊게 읜윌십시였. =? 는 Block 륌 평가하Ʞ 전에 할당을 수행하므로 읎 겜우에도 사용할 수 있습니닀.

n := r.Read(buf) =? err {
  if err == io.EOF {
    [
]
  }
  return err
}

귞늬고 @nigeltao가 얞꞉했듯읎 항상 êž°ì¡Ž 'n, err := r.Read(buf)' 팚턎을 사용할 수 있습니닀. 음반적읞 겜우에 대한 범위 지정 및 상용구에 도움읎 되는 Ʞ능을 추가한닀고 í•Žì„œ 음반적읎지 않은 겜우에도 읎 Ʞ능을 사용핎알 한닀는 의믞는 아닙니닀.

닀양한 구묞 제안에 대핮 토론하는 대신 지원 데읎터륌 파헀쳐알 할까요?

Ian읎 원볞 게시묌에 링크한 수많은 묞제(및 핎당 예)륌 찞조하섞요.
https://github.com/golang/go/wiki/ExperienceReports#error -handling도

핎당 볎고서에서 구첎적읞 통찰력을 얻었닀멎 공유핎 죌십시였.

@urandom

나는 개읞적윌로 였류 부분읎 랔록에 있얎알 한닀고 생각하지 않습니닀. 부득읎하게 1쀄읎 아닌 3쀄로 늘얎납니닀.

랔록의 목적은 두 가지입니닀.

  1. 였류륌 생성하는 표현곌 핎당 처늬Ʞ 사읎에 명확한 시각적 및 묞법적 구분을 제공하고,
  2. 더 넓은 범위의 였류 처늬륌 허용합니닀(원래 게시묌에서 @ianlancetaylor 의 명시된 목표에 따띌).

3쀄 대 1은 ì–žì–Ž 변겜도 아닙니닀. 쀄 수가 가장 큰 묞제읞 겜우 gofmt 로 간닚히 변겜하여 í•Žê²°í•  수 있습니닀.

file, err := os.Open("/some/file") or raise errors.Wrap(err, "extra context")
file, err := os.Open("/some/file") or raise err

우늬는 읎믞 return 및 panic ; ê·ž 위에 raise 륌 추가하멎 너묎 적은 읎득을 위핎 핚수륌 종료하는 방법읎 너묎 많은 것처럌 볎입니닀.

defer err2 := f.Close() or errors.ReplaceIfNil(err, err2)

errors.ReplaceIfNil(err, err2) 에는 맀우 특읎한 ì°žì¡° 통곌 의믞 첎계가 필요합니닀.
대신 포읞터로 err 륌 전달할 수 있습니닀.

defer err2 := f.Close() or errors.ReplaceIfNil(&err, err2)

귞러나 귞것은 여전히 ​​나에게 맀우 읎상하게 볎입니닀. or 토큰읎 표현식, 명령묞 또는 닀륞 것을 구성합니까? (볎닀 구첎적읞 제안읎 도움읎 될 것입니닀.)

@carlmjohnson

guard 
 else 묞의 구첎적읞 구묞곌 의믞는 묎엇입니까? 제 생각에는 토큰곌 변수 위치가 교환된 =? 또는 :: 처럌 볎입니닀. (닀시 말하지만, 볎닀 구첎적읞 제안읎 도움읎 될 것입니닀. 엌두에 두고 있는 싀제 구묞곌 의믞는 묎엇입니까?)

@bcmills
가상의 ReplaceIfNil은 닀음곌 같읎 간닚합니닀.

func ReplaceIfNil(original, replacement error) error {
   if original == nil {
       return replacement
   }
   return original
}

귞것에 대핮 읎상한 것은 없습니닀. 아마도 읎늄은 ...

or 는 읎진 연산자읎고 왌쪜 플연산자는 IdentifierList 또는 PrimaryExpr입니닀. 전자의 겜우 가장 였륞쪜 식별자로 축소됩니닀. 귞런 닀음 왌쪜 플연산자가 Ʞ볞값읎 아닌 겜우 였륞쪜 플연산자가 싀행되도록 허용합니닀.

읎것읎 나쀑에 표현식의 값을 췚하는 Result 핚수의 마지막 맀개변수륌 제왞한 몚든 것에 대핮 Ʞ볞값을 반환하는 마법을 수행하Ʞ 위핎 나쀑에 닀륞 토큰읎 필요한 읎유입니닀.
IIRC, 너묎 였래 전에 얞얎에 지룚한 Ʞ볞값 쎈Ʞ화륌 대신할 '...' 또는 묎얞가륌 추가하는 또 닀륞 제안읎 있었습니닀. ê·ž 원읞에서 전첎가 닀음곌 같읎 볎음 수 있습니닀.

f, err := os.Open("/some/file") or return ..., errors.Wrap(err, "more context")

랔록에 ꎀ핎서는 더 넓은 처늬가 가능하닀는 것을 읎핎합니닀. 나는 개읞적윌로 읎 제안의 범위가 가상의 80%륌 컀버하는 것곌는 대조적윌로 가능한 몚든 시나늬였륌 시도하고 수용핎알 하는지 확신하지 못합니닀. 귞늬고 저는 개읞적윌로 결곌가 얌마나 많은 쀄을 사용하는지가 쀑요하닀고 믿습니닀(나는 귞것읎 가장 큰 ꎀ심사띌고 말한 적읎 없지만 =?와 같은 몚혞한 토큰을 사용할 때 사싀 가독성 또는 가독성 부족입니닀). 읎 새로욎 제안읎 음반적읞 겜우 여러 쀄에 걞쳐 있는 겜우 개읞적윌로 닀음곌 같은 읎점읎 없습니닀.

if f, err := os.Open("/some/file"); err != nil {
     return errors.Wrap(err, "more context")
}
  • 위에 정의된 변수가 if 범위 왞부에서 사용 가능하게 된 겜우.
    귞늬고 여전히 읎러한 였류 처늬 랔록의 시각적 녞읎슈로 읞핎 읎러한 명령묞읎 몇 개 있는 핚수륌 읜Ʞ가 더 얎렵게 만듭니닀. 귞늬고 귞것은 사람듀읎 읎동 쀑에 였류 처늬륌 녌의할 때 가지고 있는 불만 쀑 하나입니닀.

@urandom

or 는 읎진 연산자읎고 왌쪜 플연산자는 IdentifierList 또는 PrimaryExpr입니닀. [...] 귞런 닀음 왌쪜 플연산자가 Ʞ볞값읎 아닌 겜우 였륞쪜 플연산자가 싀행되도록 합니닀.

Go의 읎진 연산자는 묞읎 아니띌 표현식읎므로 or 륌 읎진 연산자로 만드는 것은 많은 질묞을 제Ʞ합니닀. (더 큰 표현의 음부읞 or 의 의믞는 묎엇읎며 := 와 핚께 게시한 예제와 얎떻게 연ꎀ됩니까?)

싀제로 묞장읎띌고 가정하멎 였륞쪜 플연산자는 묎엇입니까? 표현식읎띌멎 ê·ž 유형은 묎엇읎며 raise 륌 닀륞 컚텍슀튞에서 표현식윌로 사용할 수 있습니까? 명령묞읞 겜우 raise 읎왞의 닀륞 의믞는 묎엇입니까? 아니멎 or raise 가 볞질적윌로 닚음 명령묞(예: :: 또는 =? 대한 구묞 대안윌로 :: or raise 되도록 제안하시겠습니까?

ë‚Žê°€ ì“ž 수 있을까

defer f.Close() or raise(err2) errors.ReplaceIfNil(err, err2) or raise(err3) Transform(err3)

?

ë‚Žê°€ ì“ž 수 있을까

f(r.Read(buf) or raise err)

?

defer f.Close() or raise(err2) errors.ReplaceIfNil(err, err2) or raise(err3) Transform(err3)

아니요, 두 번짞 raise 때묞에 유횚하지 않습니닀. 귞렇지 않은 겜우 전첎 변환 첎읞을 거쳐알 하고 최종 결곌가 혞출자에게 반환되얎알 합니닀. 전첎로서의 의믞론은 필요하지 않을 수 있지만 닀음곌 같읎 작성할 수 있습니닀.

defer f.Close() or raise(err2) Transform(errors.ReplaceIfNil(err, err2)


f(r.Read(buf) or raise err)

낮 원래 의견을 가정하멎 - 여Ʞ서 또는 왌쪜의 마지막 값을 췚하여 Ʞ볞값읞 겜우 최종 표현식은 나뚞지 결곌 목록윌로 평가됩니닀. ë„€, 읎것은 유횚핎알 합니닀. 읎 겜우 r.Read 가 였류륌 반환하멎 핎당 였류가 혞출자에게 반환됩니닀. 귞렇지 않윌멎 n 가 f 로 전달됩니닀.

펞집하닀:

ìš©ì–Žê°€ 혌동되지 않는 한 or 륌 읎항 연산자로 생각합니닀. 읎 연산자의 플연산자는 동음한 유형읎얎알 합니닀(귞러나 왌쪜 플연산자가 사묌의 목록읎고 읎 겜우 핎당 목록의 마지막 요소륌 사용합니닀). raise 는 플연산자륌 사용하고 핎당 플연산자의 값을 마지막 반환 읞수의 값윌로 사용하여 핚수에서 반환하는 당항 연산자읎며 읎전 값은 Ʞ볞값을 갖습니닀. 귞런 닀음 return ..., err 띌고도 하는 핚수에서 반환할 목적윌로 독늜 싀행형 묞에서 Ʞ술적윌로 raise 륌 사용할 수 있습니닀.

읎것은 읎상적읞 겜우읎지만 랔록 대신 ê°„ë‹ší•œ 명령묞을 허용하는 한 or raise 가 =? 대한 구묞 대안음 뿐읎므로 ꎜ찮습니닀. 덜 장황한 방식윌로 대부분의 사용 사례륌 닀룹니닀. 또는 표현식을 허용하는 지연곌 같은 묞법도 사용할 수 있습니닀. 읎것은 닀음곌 같은 대부분의 겜우륌 닀룰 것입니닀:

f := os.Open("/some/file") or raise(err) errors.Wrap(err, "with context")

복잡한 겜우:

f := os.Open or raise(err) func() {
     if err == io.EOF {
         [
]
     }
  return err
}()

낮 제안에 대핮 조ꞈ 더 생각하멎서, 나는 union/sum-types에 대핮 조ꞈ 떚얎뜚늜니닀. ë‚Žê°€ 제안하는 구묞은

guard [ ASSIGNMENT || EXPRESSION ] else { [ BLOCK ] }

표현식의 겜우 표현식을 평가하고 결곌가 boolean 표현식의 겜우 true 또는 닀륞 표현식의 겜우 공백 값곌 같지 않윌멎 BLOCK읎 싀행됩니닀. 할당에서 마지막윌로 할당된 값은 != true / != nil 됩니닀. 가드 묞 닀음에는 몚든 할당읎 범위 낎에 있게 됩니닀(마지막 변수륌 제왞하고는 새 랔록 범위륌 생성하지 않습니닀).

Swift에서 BLOCK for guard 묞은 return , break , continue 또는 throw 쀑 하나륌 포핚핎알 합니닀. 나는 귞것을 좋아하는지 아닌지 결정하지 않았습니닀. 독자가 guard 닚얎에서 닀음에 묎엇을 할지 알Ʞ 때묞에 앜간의 가치륌 더하는 것 같습니닀.

guard 읎 컀뮀니티에서 좋은 평가륌 받고 있닀고 말할 만큌 Swift륌 잘 따륎는 사람읎 있습니까?

예:

guard f, err := os.Open("/some/file") else { return errors.Wrap(err, "could not open:") }

guard data, err := ioutil.ReadAll(f) else { return errors.Wrap(err, "could not read:") }

var obj interface{}

guard err = json.Unmarshal(data, &obj) else { return errors.Wrap(err, "could not unmarshal:") }

guard m, _ := obj.(map[string]interface{}) else { return errors.New("unexpected data format") }

guard val, _ := m["key"] else { return errors.New("missing key") }

임혞 여Ʞ저Ʞ서 한꺌번에 너묎 ꎑ범위한 묞제륌 녌하는데 현싀에서 가장 흔한 팚턎은 '였류륌 있는 귞대로 돌렀볎낎는 것'읎닀. 따띌서 닀음곌 같은 smth의 가장 큰 묞제에 접귌하지 않는 읎유는 묎엇입니까?

code, err ?= fn()

읎는 핚수가 err != nil에서 반환되얎알 핚을 의믞합니까?

:= 연산자륌 위핎 ?:=륌 도입할 수 있습니닀.

code, err ?:= fn()

컎파음러가 "err" 변수륌 동음한 읎늄의 err 반환 값에 전달핎알 하Ʞ 때묞에 ?:= 의 상황은 섀도잉윌로 읞핎 더 나쁜 것 같습니닀.

음부 사람듀읎 닚순히 잘못된 윔드륌 쀄읎는 대신 올바륞 윔드륌 더 쉜게 작성할 수 있도록 하는 데 집쀑하고 있닀는 사싀에 맀우 Ʞ쁩니닀.

몇 가지 ì°žê³  사항:

였류 몚덞에 대한 Microsoft의 Midori 디자읎너 쀑 한 명읎 작성한 흥믞로욎

읎 묞서와 Swift의 몇 가지 아읎디얎가 Go2에 아늄답게 적용될 수 있닀고 생각합니닀.

새로 수정된 throws 킀워드륌 도입하멎 닀음곌 같읎 핚수륌 정의할 수 있습니닀.

func Get() []byte throws {
  if (...) {
    raise errors.New("oops")
  }

  return []byte{...}
}

던지지 않는 닀륞 핚수에서 읎 핚수륌 혞출하렀고 하멎 처늬되지 않은 throw 가능한 였류로 읞핎 컎파음 였류가 발생합니닀.
대신 우늬는 몚두가 동의하는 였류륌 전파하거나 처늬할 수 있얎알 합니닀.

func ScrapeDate() time.Time throws {
  body := Get() // compilation error, unhandled throwable
  body := try Get() // we've been explicit about potential throwable

  // ...
}

메소드가 싀팚하지 않는닀는 것을 알고 있는 겜우 또는 테슀튞에서 swift와 유사한 try! 도입할 수 있습니닀.

func GetWillNotFail() time.Time {
  body := Get() // compilation error, throwable not handled
  body := try Get() // compilation error, throwable can not be propagated, because `GetWillNotFail` is not annotated with throws
  body := try! Get() // works, but will panic on throws != nil

  // ...
}

확싀하지 않지만(swift와 유사):

func main() {
  // 1:
  do {
    fmt.Printf("%v", try ScrapeDate())
  } catch err { // err contains caught throwable
    // ...
  }

  // 2:
  do {
    fmt.Printf("%v", try ScrapeDate())
  } catch err.(type) { // similar to a switch statement
    case error:
      // ...
    case io.EOF
      // ...
  }
}

PS1. 여러 반환 값 func ReadRune() (ch Rune, size int) throws { ... }
PS2. return try Get() 또는 return try! Get() 반환할 수 있습니닀.
PS3. 읎제 buffer.NewBuffer(try Get()) 또는 buffer.NewBuffer(try! Get()) 와 같은 혞출을 연결할 수 있습니닀.
PS4. 죌석읎 확싀하지 않음( errors.Wrap(err, "context") 작성하Ʞ 쉬욎 방법)
PS5. 읎것은 싀제로 예왞입니닀
PS6. 가장 큰 승늬는 묎시된 예왞에 대한 컎파음 시간 였류입니닀.

당신읎 쓰는 제안은 몚든 나쁜 것듀곌 핚께 믞도늬 링크에 정확히 섀명되얎 있습니닀
귞것의 ìž¡ë©Ž... 귞늬고 "던짐"의 명백한 결곌 쀑 하나는 "사람
ì‹«ì–Ž". 왜 대부분의 겜우 맀번 "throws"륌 썚알 합니까?
Ʞ능?

BTW, 였류륌 확읞하고 묎시하지 않윌렀는 의도는
였류가 아닌 유형에도 적용되며 더 많읎 사용하는 것읎 좋습니닀.
음반화된 형식(예: gcc __attribute__((warn_unused_result))).

연산자의 형식에 ꎀ핎서는 짧은 형식읎나
닀음곌 같은 킀워드 형식:

?= fn() OR check fn() -- 혞출자에게 였류 전파
!= fn() 또는 nofail fn() -- 였류 발생 시 팹닉

2017년 8월 26음 토요음 였후 12:15, nvartolomei [email protected]
썌닀:

몇 가지 ì°žê³  사항:

흥믞로욎 겜험 볎고서
http://joeduffyblog.com/2016/02/07/the-error-model/ 쀑 하나에서
였류 몚덞에 대한 Microsoft의 Midori 디자읎너.

읎 묞서와 Swift에서 몇 가지 아읎디얎가 있닀고 생각합니닀.
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html
Go2에 아늄답게 적용할 수 있습니닀.

새로욎 reseved throws 킀워드륌 도입하멎 닀음곌 같읎 핚수륌 정의할 수 있습니닀.

func Get() []byte는 {
만앜 (...) {
였류 발생.New("oops")
}

반환 []바읎튞{...}
}

던지지 않는 닀륞 핚수에서 읎 핚수륌 혞출하렀고 하멎
처늬되지 않은 throw 가능한 였류로 읞핎 컎파음 였류가 발생합니닀.
대신 우늬는 몚두가 동의하는 였류륌 전파할 수 있얎알 합니닀.
음반적읞 겜우 또는 처늬하십시였.

func ScrapeDate() time.Time은 {
body := Get() // 컎파음 였류, 처늬되지 않은 throw 가능
body := try Get() // 우늬는 잠재적읞 throwable에 대핮 명시했습니닀.

// ...
}

방법읎 싀팚하지 않을 것읎띌는 것을 알고 있는 겜우 또는 테슀튞에서 닀음을 수행할 수 있습니닀.
시도륌 소개합니닀! 슀위프튞와 비슷하닀.

func GetWillNotFail() time.Time {
body := Get() // 컎파음 였류, throwable읎 처늬되지 않음
body := try Get() // 컎파음 였류, throwable을 전파할 수 없습니닀. GetWillNotFail 에 throw 죌석읎 없Ʞ 때묞입니닀.
몞 := 시도! Get() // 작동하지만 throw 시 팚닉읎 발생합니닀 != nil

// ...
}

확싀하지 않지만(swift와 유사):

핚수 메읞() {
// 1:
하닀 {
fmt.Printf("%v", ScrapEDate()륌 시도하십시였)
} catch err { // err에는 catch된 throwable읎 포핚되얎 있습니닀.
// ...
}

// 2:
하닀 {
fmt.Printf("%v", ScrapEDate()륌 시도하십시였)
} catch err.(type) { // switch 묞곌 유사
쌀읎슀 였류:
// ...
쌀읎슀 io.EOF
// ...
}
}

PS1. 여러 반환 값 func ReadRune() (ch Rune, 크Ʞ int) throw {
... }
PS2. return try Get() 또는 return try로 돌아갈 수 있습니닀! 얻닀()
PS3. 읎제 buffer.NewBuffer(try Get()) 또는 buffer.NewBuffer(try!
얻닀())
PS4. 죌석읎 확싀하지 않음

—
당신읎 댓Ꞁ을 달았Ʞ 때묞에 읎것을 받는 것입니닀.
읎 읎메음에 직접 답장하고 GitHub에서 확읞하섞요.
https://github.com/golang/go/issues/21161#issuecomment-325106225 또는 음소거
슀레드
https://github.com/notifications/unsubscribe-auth/AICzv9CLN77RmPceCqvjXVE_UZ6o7JGvks5sb-IYgaJpZM4Oi1c-
.

@jba 와 @bcmills 가 제안한 연산자는 "??"로 더 잘

읎 예륌 볎멎:

func doStuff() (int,error) {
    x, err := f() 
    if err != nil {
        return 0, wrapError("f failed", err)
    }

    y, err := g(x)
    if err != nil {
        return 0, wrapError("g failed", err)
    }

    return y, nil
}

func doStuff2() (int,error) {
    x := f()  ?? (err error) { return 0, wrapError("f failed", err) }
    y := g(x) ?? (err error) { return 0, wrapError("g failed", err) }
    return y, nil
}

doStuff2는 닀음곌 같은 읎유로 읜Ʞ가 훚씬 쉜고 빠늅니닀.

  1. 수직 공간을 덜 낭비
  2. 왌쪜의 행복한 Ꞟ을 빚늬 읜Ʞ 쉜습니닀.
  3. 였륞쪜의 였류 조걎을 빠륎게 읜Ʞ 쉜습니닀.
  4. 핚수의 로컬 넀임슀페읎슀륌 였엌시킀는 였류 변수가 없습니닀.

나에게 읎 제안은 불완전핎 볎읎고 너묎 많은 마법을 가지고 있습니닀. ?? 연산자는 얎떻게 정의됩니까? "nil읎 아닌 겜우 마지막 반환 값을 캡처합니닀"? "메소드 유형곌 음치하는 겜우 마지막 였류 값을 캡처합니까?"

위치와 유형에 따띌 반환 값을 처늬하Ʞ 위핎 새 연산자륌 추가하는 것은 핎킹처럌 볎입니닀.

2017년 8월 29음 13:03 +0300, Mikael Gustavsson [email protected] 은 닀음곌 같읎 썌습니닀.

@jba 와 @bcmills 가 제안한 연산자는 "??"로 더 잘
읎 예륌 볎멎:
func doStuff() (int, error) {
x, 였류 := f()
였류 != nil {
반환 0, wrapError("f 싀팚", 였류)
}

   y, err := g(x)
   if err != nil {
           return 0, wrapError("g failed", err)
   }

   return y, nil

}

func doStuff2() (int, error) {
x := f() ?? (였류 였류) { 0 반환, wrapError("f 싀팚", 였류) }
y := g(x) ?? (였류 였류) { 0 반환, wrapError("g 싀팚", 였류) }
늬턎 y, nil
}
doStuff2는 닀음곌 같은 읎유로 읜Ʞ가 훚씬 쉜고 빠늅니닀.

  1. 수직 공간을 덜 낭비
  2. 왌쪜의 행복한 Ꞟ을 빚늬 읜Ʞ 쉜습니닀.
  3. 였륞쪜의 였류 조걎을 빠륎게 읜Ʞ 쉜습니닀.
  4. 핚수의 로컬 넀임슀페읎슀륌 였엌시킀는 였류 변수가 없습니닀.

—
당신읎 댓Ꞁ을 달았Ʞ 때묞에 읎것을 받는 것입니닀.
읎 읎메음에 직접 답장하거나 GitHub에서 볎거나 슀레드륌 음소거하섞요.

@nvartolomei

?? 연산자는 얎떻게 정의됩니까?

https://github.com/golang/go/issues/21161#issuecomment -319434101 및 https://github.com/golang/go/issues/21161#issuecomment -320758279륌 ì°žì¡° 하섞요 .

@bcmills 는 정지된 슀레드륌 부활 @slvmnd 의 예륌

func doStuff() (int, err) {
        x, err := f()
        return 0, wrapError("f failed", err)     if err != nil

    y, err := g(x)
        return 0, wrapError("g failed", err)     if err != nil

        return y, nil
}

한 쀄에 명령묞곌 였류 검사륌 포핚하는 것만큌 간결하지는 않지만 합늬적윌로 잘 읜힙니닀. (if 표현식에서 := 형식의 할당을 허용하지 않는 것읎 좋습니닀. 귞렇지 않윌멎 묞법읎 명확하더띌도 범위 지정 묞제가 사람듀을 혌란슀럜게 할 수 있습니닀.) "if"의 부정 버전윌로 "unless"륌 허용하는 것은 앜간의 구묞상의 섀탕읎지만 읜Ʞ에 잘 작동하며 고렀할 가치가 있습니닀.

하지만 여Ʞ에서는 Perl에서 크늬빙(cribbing)하는 것을 권장하지 않습니닀. (Basic Plus 2는 ꎜ찮습니닀.) 귞런 식윌로 반복묞 수정자가 있는데, 읎는 때때로 유용하지만 또 닀륞 상당히 복잡한 묞제 섞튞륌 가젞옵니닀.

더 짧은 버전:
였류 != nil읎멎 반환
귞때도 지원핎알 합니닀.

읎러한 구묞을 사용하멎 질묞읎 발생합니닀.
닀음곌 같은 "if" 묞윌로 지원됩니닀.
func(args) if 조걎

애프터 액션을 발명하는 대신 싱Ꞁ을 도입할 가치가 있닀멎
띌읞읎띌멎?

err!=nil 반환읎멎
err!=nil읎 0을 반환하멎 wrapError("싀팚", err)
만앜 err!=nil do_smth()

특별한 형태의 구묞볎닀 훚씬 더 자연슀러워 볎읎지 않습니까? ë‚Žê°€ 추잡하지만
귞것은 구묞 분석에 많은 고통을 쎈래합니닀 :/

하지만... 몚두 작은 조정음 뿐읎며 였류에 대한 특별한 ì–žì–Ž 지원읎 아닙니닀.
췚꞉/전파.

2017년 9월 18음 월요음 였후 4시 14분에 dsugalski [email protected]에서 닀음곌 같읎 썌습니닀.

@bcmills https://github.com/bcmills 가
조용한 슀레드, 닀륞 얞얎에서 크늬빙을 고렀하렀는 겜우
묞 수정자가 몚든 사람에게 합늬적읞 솔룚션을 제공하는 것처럌 볎입니닀.
읎것. @slvmnd https://github.com/slvmnd 의 예륌
명령묞 수정자:

func doStuff() (int, err) {
x, 였류 := f()
0 반환, wrapError("f 싀팚", err) err != nil읞 겜우

  y, err := g(x)
    return 0, wrapError("g failed", err)     if err != nil

    return y, nil

}

명령묞곌 였류륌 한 번에 확읞하는 것만큌 간결하지는 않습니닀.
쀄읎지만 ꜀ 잘 읜힙니닀. (:= 형식을 허용하지 않는 것읎 좋습니닀.
if 표현식에 할당하지 않윌멎 범위 지정 묞제가 발생할 수 있습니닀.
묞법읎 명확하더띌도 사람듀을 혌란슀럜게 합니닀.
"if"의 부정 버전은 앜간의 구묞 섀탕읎지만 닀음곌 같읎 잘 작동합니닀.
읜고 고렀할 가치가 있습니닀.

하지만 여Ʞ에서는 Perl에서 크늬빙(cribbing)하는 것을 권장하지 않습니닀. (베읎직 플러슀 2는
fine) 귞런 식윌로 반복되는 묞 수정자가 있지만 때로는
유용하고 상당히 복잡한 묞제의 또 닀륞 집합을 가젞옵니닀.

—
당신읎 댓Ꞁ을 달았Ʞ 때묞에 읎것을 받는 것입니닀.
읎 읎메음에 직접 답장하고 GitHub에서 확읞하섞요.
https://github.com/golang/go/issues/21161#issuecomment-330215402 또는 음소거
슀레드
https://github.com/notifications/unsubscribe-auth/AICzv1rfnXeGVRRwaigCyyVK_STj-i83ks5sjmylgaJpZM4Oi1c-
.

@dsugalski 의 제안에 대핮 좀 더 생각핎볎멎 @jba 및 닀륞 사람듀읎 요청한 속성, 슉 였류가 아닌 윔드가 였류 윔드와 시각적윌로 구별되는 속성읎 없습니닀. 였류가 없는 윔드 겜로에도 상당한 읎점읎 있닀멎 여전히 흥믞로욎 아읎디얎음 수 있지만, 제안된 대안에 비핎 귞것에 대핮 생각하멎 할수록 덜 맀력적윌로 볎입니닀.

순수한 텍슀튞에서 Ʞ대하는 것읎 얌마나 시각적읞 찚읎가 있는지 잘 몚륎겠습니닀. ì–Žë–€ 시점에서는 읎륌 IDE 또는 텍슀튞 펞집Ʞ의 윔드 색칠 레읎얎에 펀튾하는 것읎 더 적절핎 볎입니닀.

귞러나 텍슀튞 Ʞ반의 가시적 구분을 위핎 찜플할 정도로 였래 전에 읎것을 처음 사용하Ʞ 시작했을 때 우늬가 가지고 있던 서식 표쀀은 IF/UNLESS 묞 수정자륌 였륞쪜윌로 정렬핎알 했Ʞ 때묞에 충분히 눈에 띄게 만듀었습니닀. (당, 볎닀 유연한 ì°œ 크Ʞ륌 가진 펞집Ʞ볎닀 VT-220 터믞널에서 적용하Ʞ 쉜고 시각적윌로 더 구별되는 표쀀읎 부여되었지만)

적얎도 나에게는 명령묞 수정자 case가 쉜게 구별되고 현재 if-block 첎계볎닀 더 잘 읜힌닀는 것을 알았습니닀. 묌론 닀륞 사람듀에게는 귞렇지 않을 수도 있습니닀. 저는 영얎 텍슀튞륌 읜는 것곌 같은 방식윌로 소슀 윔드륌 읜고 Ʞ졎의 펞안한 팚턎에 맀핑되지만 몚든 사람읎 읎렇게 하는 것은 아닙니닀.

return 0, wrapError("f failed", err) if err != nil 는 if err != nil { return 0, wrapError("f failed", err) } 로 ì“ž 수 있습니닀.

if err != nil return 0, wrapError("f failed", err) 동음하게 ì“ž 수 있습니닀.

여Ʞ서 필요한 것은 gofmt가 if 륌 ì„ž 쀄로 확장하는 대신 한 쀄에 한 쀄로 작성하는 것뿐음까요?

나륌 공격하는 또 닀륞 가능성읎 있습니닀. 음회용 Go 윔드륌 빠륎게 작성하렀고 할 때 겜험하는 많은 마찰은 몚든 닚음 혞출에서 였류 검사륌 수행핎알 하므로 혞출을 멋지게 쀑첩할 수 없Ʞ 때묞입니닀.

예륌 듀얎, 뚌저 http.NewRequest 결곌륌 임시 변수에 할당한 닀음 Do륌 혞출하지 않고는 새 요청 객첎에 대핮 http.Client.Do륌 혞출할 수 없습니닀.

닀음을 허용할 수 있는지 궁ꞈ합니닀.

f(y())

y 가 (T, error) 튜플을 반환하더띌도 작동합니닀. y가 였류륌 반환하멎 컎파음러는 식 평가륌 쀑닚하고 핎당 였류가 f에서 반환되도록 할 수 있습니닀. f가 였류륌 반환하지 않윌멎 였류가 발생할 수 있습니닀.

귞러멎 나는 할 수 있닀:

n, err := http.DefaultClient.Do(http.NewRequest("DELETE", "/foo", nil))

NewRequest 또는 Do가 싀팚하멎 였류 결곌는 nil읎 아닙니닀.

귞러나 여Ʞ에는 한 가지 쀑요한 묞제가 있습니닀. f가 두 개의 읞수 또는 가변 읞수륌 허용하는 겜우 위의 식은 읎믞 유횚합니닀. 또한 읎륌 수행하Ʞ 위한 정확한 규칙읎 상당히 복잡할 수 있습니닀.

귞래서 음반적윌로 나는 귞것을 좋아하지 않는닀고 생각하지만(나도 읎 슀레드의 닀륞 제안에 ꎀ심읎 없습니닀), 얎욌든 고렀륌 위핎 아읎디얎륌 버늎 것읎띌고 생각했습니닀.

@rogpeppe 아니멎 귞냥 사용할 수 있습니닀 json.NewEncoder을

@gbbr 하 예, 나쁜 예입니닀.

더 나은 예는 http.Request음 수 있습니닀. 귞것을 사용하Ʞ 위핎 죌석을 변겜했습니닀.

와. 많은 아읎디얎가 윔드 가독성을 더욱 악화시킀고 있습니닀.
나는 접귌읎 좋닀

if val, err := DoMethod(); err != nil {
   // val is accessible only here
   // some code
}

한 가지 정말 짜슝나는 것은 반환된 변수의 범위륌 지정하는 것입니닀.
읎 겜우 val 륌 사용핎알 하지만 if 범위에 있습니닀.
따띌서 else 륌 사용핎알 하지만 linter는 읎에 반대할 것읎며(저도 마찬가지입니닀) 유음한 방법은

val, err := DoMethod()
if err != nil {
   // some code
}
// some code with val

if 랔록 왞부의 변수에 액섞슀할 수 있윌멎 좋을 것입니닀.

if val, err := DoMethod(); err != nil {
   // some code
}
// some code with val

@dmbreaker 읎것읎 볞질적윌로 Swift의 가드 절의 목적입니닀. ì–Žë–€ 조걎을 통곌하멎 현재 범위 낎에서 변수륌 할당합니닀. 낮 읎전 의견을 찞조하십시였.

저는 Go에서 였류 처늬륌 닚순화하Ʞ 위핎 최선을 닀하고 있지만(개읞적윌로 귞닀지 신겜 쓰지는 않지만) 읎것읎 간닚하고 맀우 읜Ʞ 쉬욎 얞얎에 앜간의 마법을 추가한닀고 생각합니닀.

@gbbr
여Ʞ서 말하는 '읎것'은 묎엇입니까? 음을 처늬하는 방법에 대한 몇 가지 닀륞 제안읎 있습니닀.

아마도 두 부분윌로 구성된 솔룚션입니까?

try 륌 "반환 튜플에서 가장 였륞쪜 값을 벗겚낎십시였. 핎당 유형에 대한 0 값읎 아닌 겜우 닀륞 값읎 0윌로 섀정된 읎 핚수의 가장 였륞쪜 값윌로 반환"윌로 정의합니닀. 읎것은 음반적읞 겜우륌 만듭니닀

 a := try ErrorableFunction(b)

연결을 가능하게 합니닀.

 a := try ErrorableFunction(try SomeOther(b, c))

(선택적윌로 횚윚성을 위핎 0읎 아닌 nil읎 아닌 것윌로 만듭니닀.) 였류 핚수가 nil/0읎 아닌 값을 반환하멎 핚수는 "값곌 핚께 쀑닚"됩니닀. try 'ed 핚수의 가장 였륞쪜 값은 혞출 핚수의 가장 였륞쪜 값에 할당할 수 있얎알 합니닀. 귞렇지 않윌멎 컎파음 타임 유형 검사 였류입니닀. (따띌서 읎것은 error 만 처늬하도록 하드 윔딩되지 않았지만 컀뮀니티에서는 닀륞 "영늬한" 윔드에 대한 사용을 권장하지 않을 수 있습니닀.)

귞런 닀음, 닀음 쀑 하나와 같은 지연 킀워드로 try 반환을 포착하도록 허용합니닀.

catch func(e error) {
    // whatever this function returns will be returned instead
}

또는 더 장황하지만 Go가 읎믞 작동하는 방식곌 더 ꎀ렚읎 있습니닀.

defer func() {
    if err := catch(); err != nil {
        set_catch(ErrorWrapper{a, "while posting request to server"})
    }
}()

catch 겜우 핚수의 맀개변수는 반환되는 값곌 정확히 음치핎알 합니닀. 여러 Ʞ능읎 제공되는 겜우 값은 몚든 Ʞ능을 역순윌로 전달합니닀. 묌론 올바륞 유형의 핚수로 핎석되는 값을 넣을 수 있습니닀. defer êž°ë°˜ 예제의 겜우 하나의 defer func가 set_catch 혞출하멎 닀음 defer func는 catch() 값을 가젞옵니닀. (만앜 당신읎 프로섞슀에서 귞것을 닀시 nil로 섀정할 만큌 얎늬석닀멎, 혌란슀러욎 반환 값을 얻을 것입니닀. 귞렇게 하지 마십시였.) set_catch에 전달된 값은 반환된 유형에 할당할 수 있얎알 합니닀. 두 겜우 몚두 선얞읎 아니띌 명령묞읎띌는 점에서 읎것읎 defer 처럌 작동할 것윌로 예상하고 명령묞읎 싀행된 후에만 윔드에 적용됩니닀.

나는 닚순성 ꎀ점에서 ì—°êž° êž°ë°˜ 솔룚션을 선혞하는 겜향읎 있지만(Ʞ볞적윌로 거Ʞ에 새로욎 개념읎 도입되지 않고 새로욎 것읎 아니띌 recover() 의 두 번짞 유형임) 성능 묞제가 있을 수 있음을 읞정합니닀. 별도의 catch 킀워드륌 사용하멎 정상적읞 반환읎 발생할 때 완전히 걎너뛰Ʞ가 더 쉬워젞 횚윚성을 높음 수 있습니닀. 최대 횚윚성을 원할 겜우 범위 또는 Ʞ능당 하나만 활성화되도록 범위에 묶을 수 있습니닀. , 제 생각에는 거의 제로 비용읎 될 것입니닀. (아마도 소슀 윔드 파음 읎늄곌 쀄 번혞는 catch 핚수에서 반환되얎알 합니까? 귞렇게 하는 것은 컎파음 시간에 저렎하고 사람듀읎 지ꞈ 전첎 슀택 추적을 요구하는 몇 가지 읎유륌 플할 수 있습니닀.)

얎느 쪜읎든 반복적읞 였류 처늬가 핚수 낎의 한 곳에서 횚곌적윌로 처늬되도록 허용하고 위의 rsc의 섀명에 따띌 현재 사례의 최악의 ìž¡ë©Ž 쀑 하나읞 IMHO읞 였류 처늬륌 띌읎람러늬 Ʞ능윌로 쉜게 제공할 수 있습니닀. 였류 처늬의 번거로움은 올바륞 처늬볎닀 "였류 반환"을 조장하는 겜향읎 있습니닀. 나 자신도 ê·ž 묞제로 많읎 고생한닀는 것을 알고 있습니닀.

@thejerf 읎 제안에 대한 Ian의 요점 쀑 음부는 핚수가 컚텍슀튞륌 추가하거나 반환하는 였류륌 조작하는 것을 방핎하지 않고 였류 상용구륌 핎결하는 방법을 탐색하는 것입니닀.

였류 처늬륌 try 및 catch 것은 ê·ž 목표에 반하는 것처럌 볎읎지만 음반적윌로 추가하렀는 섞부 정볎 종류에 따띌 닀늅니닀.

최소한, 좀 더 현싀적읞 예시로 얎떻게 작동하는지 볎고 싶습니닀.

낮 제안의 요점은 컚텍슀튞륌 추가하거나 였류륌 조작할 수 있도록 하는 것입니닀. 여Ʞ서 컚텍슀튞륌 계속핎서 반복하는 것곌 ꎀ렚된 대부분의 제안볎닀 프로귞래밍 방식윌로 더 정확하닀고 생각하는 방식윌로 추가 컚텍슀튞륌 추가하렀는 욕구륌 억제합니닀. .

원래 예제륌 닀시 작성하렀멎

func Chdir(dir string) error {
    if e := syscall.Chdir(dir); e != nil {
        return &PathError{"chdir", dir, e}
    }
    return nil
}

로 나옚닀

func Chdir(dir string) error {
    catch func(e error) {
        return &PathError{"chdir", dir, e}
    }

    try syscall.Chdir(dir)
    return nil
}

읎 예제가 싀제로 읎러한 제안 쀑 하나에 대핮 너묎 사소하닀는 점을 제왞하고는 읎 겜우 원래 Ʞ능을 귞대로 둡니닀.

개읞적윌로 나는 원래의 Chdir Ʞ능읎 애쎈에 묞제띌고 생각하지 않습니닀. 나는 하나의 였류 Ʞ능읎 아닌 장Ʞ간 반복되는 였류 처늬로 읞핎 Ʞ능에 잡음읎 있는 겜우륌 핎결하Ʞ 위핎 특별히 조정하고 있습니닀. 또한 가능한 몚든 사용 사례에 대핮 묞자 귞대로 닀륞 작업을 수행하는 Ʞ능읎 있는 겜우 읎믞 얻은 것을 계속 작성하는 것읎 정답음 수 있습니닀. 귞러나 나는 귞것읎 음반적읞 겜우띌멎 애쎈에 불만읎 제Ʞ되지 않았을 것읎띌는 귌거에서 읎것읎 대부분의 사람듀에게 닚연윔 드묞 겜우띌고 생각합니닀. 였류륌 확읞하는 소음은 사람듀읎 핚수에서 "대부분 동음한 작업"을 계속핎서 수행하Ʞ륌 원하Ʞ 때묞에 정확히 쀑요합니닀.

나는 또한 사람듀읎 원하는 대부분읎 충족될 것읎띌고 생각합니닀.

func SomethingBigger(dir string) (interface{}, error) {
     catch func (e error, filename string, lineno int) {
         return PackageSpecificError{e, filename, lineno, dir}
     }

     x := try Something()

     if x == true {
         try SomethingElse()
     } else {
         a, b = try AThirdThing()
     }

     return whatever, nil
}

하나의 if 묞을 신겜쓰Ʞ에는 너묎 작아서 볎Ʞ 좋게 만듀렀고 하는 묞제륌 없애고 A가 : 귞것은 싀제로 맀우 드묞 겜우읎고 B: 읎 겜우에 상용구 였버헀드는 고유 처늬 윔드의 복잡성에 비핎 싀제로 귞렇게 쀑요하지 않습니닀. 아마도 묞제는 핎결책읎 있는 것윌로 축소될 수 있습니닀.

나도 진짜 볎고싶닀

func packageSpecificHandler(f string) func (err error, filename string, lineno int) {
    return func (err error, filename string, lineno int) {
        return &PackageSpecificError{"In function " + f, err, filename, lineno}
    }
}

 func SomethingBigger(dir string) (interface{}, error) {
     catch packageSpecificHandler("SomethingBigger")

     ...
 }

또는 귞와 동등한 것읎 가능합니닀.

귞늬고, 페읎지에 있는 몚든 제안 쀑... 읎것은 여전히 ​​Go처럌 볎읎지 않습니까? 현재의 바둑볎닀 바둑곌 더 비슷핎 볎입니닀.

솔직히 말핎서, 낮 전묞적읞 엔지니얎링 겜험의 대부분은 PHP에 대한 것읎지만(나는 알고 있습니닀) Go의 죌요 맀력은 항상 가독성읎었습니닀. 나는 PHP의 음부 잡멎을 슐Ʞ지만 가장 겜멞하는 부분은 "최종" "추상" "정적" 넌섌슀읎며 한 가지 작업을 수행하는 윔드 조각에 지나치게 복잡한 개념을 적용하는 것입니닀.

읎 제안을 볎고 나는 한 조각을 볎고 ê·ž 윔드 조각읎 말하고/하고 있는 것에 대핮 두 번 읎핎하고 정말로 "생각"í•Žì•Œ 하는 느낌에 대한 슉각적읞 플래시백을 죌었습니닀. 나는 읎 윔드륌 읜을 수 있고 얞얎에 싀제로 추가되지 않는닀고 생각합니닀. 낮 첫 번짞 볞능은 왌쪜을 볎는 것읎며 읎것은 항상 nil 반환한닀고 생각합니닀. 귞러나 읎 변겜윌로 읞핎 윔드의 동작을 결정하Ʞ 위핎 왌쪜곌 였륞쪜을 삎펎뎐알 합니닀. 읎는 더 많은 시간을 읜고 더 많은 정신적 몚덞을 의믞합니닀.

귞러나 읎것읎 Go에서 였류 처늬륌 개선할 여지가 없닀는 것을 의믞하지는 않습니닀.

읎 전첎 슀레드륌 (아직) 읜지 않아서 죄송합니닀(맀우 깁니닀). 하지만 사람듀읎 대첎 구묞을 버늬는 것을 볎았윌므로 제 아읎디얎륌 공유하고 싶습니닀.

a, err := helloWorld(); err? {
  return fmt.Errorf("helloWorld failed with %s", err)
}

읎것을 묎횚화하는 위의 것을 놓치지 않Ʞ륌 바랍니닀. 얞젠가는 몚든 댓Ꞁ을 ë‹€ 처늬할 것을 앜속합니닀. :)

연산자는 error 유형에서만 허용되얎알 유형 변환 시맚틱 혌란을 플할 수 있습니닀.

흥믞 롭습니닀 , 죌나요 ?

if a, err := helloWorld(); err != nil {
  return fmt.Errorf("helloWorld failed with %s", err)
}

a 가 읎슀쌀읎프되도록 허용하는 반멎 현재 상태에서는 then 및 else 랔록윌로 범위가 지정됩니닀.

@object88 맞습니닀 . 변화는 믞묘하고 믞학적읎며 죌ꎀ적입니닀. 개읞적윌로 읎 죌제에 대핮 Go 2에서 원하는 것은 믞묘한 가독성 변화입니닀.

개읞적윌로 띌읞읎 if 로 시작하지 않고 !=nil 필요하지 ì•Šêž° 때묞에 더 읜Ʞ 쉜습니닀. 변수는 (대부분?) 닀륞 쀄에 있는 왌쪜 가장자늬에 있습니닀.

a 의 범위에 대한 좋은 점, 나는 귞것을 고렀하지 않았습니닀.

읎 묞법의 닀륞 가능성을 고렀하멎 읎것읎 가능한 것 같습니닀.

err := helloWorld(); err? {
  return fmt.Errorf("error: %s", err)
}

귞늬고 아마도

helloWorld()? {
  return fmt.Errorf("hello world failed")
}

귞것은 아마도 귞것읎 묎너지는 곳음 것입니닀.

였류륌 반환하는 것은 Go의 몚든 핚수 혞출의 음부여알 하므로 닀음곌 같읎 상상할 수 있습니닀.
```
a := helloWorld(); 잘못? {
return fmt.Errorf("helloWorld 싀팚: %s", 였류)
}

싀제 예왞 처늬는 얎떻습니까? 제 말은 시도하고, ìž¡ë‹€, 마칚낎 많은 현대 얞얎처럌 하시겠습니까?

아니요, 윔드륌 암시적읎고 불분명하게 만듭니닀(싀제로는 조ꞈ 더 짧음).

2017년 11월 23음 목요음 07:27 Kamyar Miremadi [email protected]
썌닀:

싀제 예왞 처늬는 얎떻습니까? 낮 말은, 시도하고, 잡고, 마칚낎
대신 많은 현대 얞얎처럌?

—
당신읎 댓Ꞁ을 달았Ʞ 때묞에 읎것을 받는 것입니닀.
읎 읎메음에 직접 답장하고 GitHub에서 확읞하섞요.
https://github.com/golang/go/issues/21161#issuecomment-346529787 또는 음소거
슀레드
https://github.com/notifications/unsubscribe-auth/AICzvyy_kGAlcs6RmL8AKKS5deNRU4_5ks5s5PQVgaJpZM4Oi1c-
.

@mpvl 의 WriteToGCS 예제 up-thread 로 돌아가서 컀밋/례백 팚턎읎 Go의 였류 처늬에서 죌요 변겜 사항을 볎슝할 만큌 충분히 음반적읎지 않닀는 것을 (닀시) 제안하고 싶습니닀. 핚수에서 팚턎을 캡처하는 것은 얎렵지 않습니닀( 놀읎터 링크 ):

func runWithCommit(f, commit func() error, rollback func(error)) (err error) {
    defer func() {
        if r := recover(); r != nil {
            rollback(fmt.Errorf("panic: %v", r))
            panic(r)
        }
    }()
    if err := f(); err != nil {
        rollback(err)
        return err
    }
    return commit()
}

귞런 닀음 예제륌 닀음곌 같읎 작성할 수 있습니닀.

func writeToGCS(ctx context.Context, bucket, dst string, r io.Reader) error {
    client, err := storage.NewClient(ctx)
    if err != nil {
        return err
    }
    defer client.Close()

    w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
    return runWithCommit(
        func() error { _, err := io.Copy(w, r); return err },
        func() error { return w.Close() },
        func(err error) { _ = w.CloseWithError(err) })
}

더 ê°„ë‹ší•œ 솔룚션을 제안합니닀.

func someFunc() error {
    ^err := someAction()
    ....
}

닀쀑 닀쀑 핚수 반환의 겜우:

func someFunc() error {
    result, ^err := someAction()
    ....
}

귞늬고 여러 반환 읞수의 겜우:

func someFunc() (result Result, err error) {
    var result Result
    params, ^err := someAction()
    ....
}

^ Ʞ혞는 맀개변수가 nil읎 아닌 겜우 반환을 의믞합니닀.
Ʞ볞적윌로 "였류가 발생하멎 슀택 위로 읎동"

읎 방법의 닚점읎 있습니까?

@gladkikhartem
였류가 반환되Ʞ 전에 얎떻게 수정합니까?

@urandom
였류륌 래핑하는 것은 낮 생각에 명시적윌로 수행되얎알 하는 쀑요한 작업입니닀.
Go 윔드는 마법읎 아니띌 가독성에 ꎀ한 것입니닀.
였류 래핑을 더 명확하게 유지하고 싶습니닀.

하지만 동시에 많은 정볎륌 ë‹Žê³  있지 않고 공간만 찚지하는 윔드륌 없애고 싶습니닀.

if err != nil {
    return err
}

바둑의 진부한 표현곌 같습니닀. 읜고 싶지 않고 귞냥 걎너뛰고 싶을 뿐입니닀.

지ꞈ까지 읎 토론에서 볞 것은 닀음곌 같은 조합입니닀.

  1. 구묞 장황핚 쀄읎Ʞ
  2. 컚텍슀튞륌 추가하여 였류 개선

읎것은 두 가지 잡멎을 몚두 얞꞉한 @ianlancetaylor 의 원래 묞제 섀명곌

1. 구묞의 장황핚 감소

펞집/확장된 읎후로 여Ʞ에 볎고하는 원래 형식에서도 @gladkikhartem 의 아읎디얎가 듭니닀 .

 result, ^ := someAction()

func의 맥띜에서:

func getOddResult() (int, error) {
    result, ^ := someResult()
    if result % 2 == 0 {
          return result + 1, nil
    }
    return result, nil
}

읎 짧은 구묞 또는 @gladkikhartem 읎 err^ 로 제안한 형식은 묞제(1)의 구묞 상섞도 부분을 처늬합니닀.

2. 였류 컚텍슀튞

두 번짞 부분의 겜우 컚텍슀튞륌 더 추가하멎 지ꞈ은 완전히 잊얎버늎 수도 있고 나쀑에 특별한 contextError 유형읎 사용되는 겜우 각 였류에 슀택 추적을 자동윌로 추가하도록 제안할 수도 있습니닀. 읎러한 새로욎 Ʞ볞 였류 유형은 전첎 또는 짧은 슀택 추적( GO_CONTEXT_ERROR=full 상상)을 제공할 수 있윌며 error 읞터페읎슀와 혾환되는 동시에 최상위 혞출 슀택에서 최소한 핚수 및 파음 읎늄을 추출할 수 있는 가능성을 제공합니닀. êž°ìž….

contextError 사용할 때 Go는 얎떻게든 였류가 생성된 정확한 지점에 혞출 슀택 추적을 첚부핎알 합니닀.

닀시 func 예륌 듀멎 닀음곌 같습니닀.

func getOddResult() (int, contextError) {
    result, ^ := someResult() // here a 'contextError' is created; if the error received from 'someResult()' is also a `contextError`, the two are nested
    if result % 2 == 0 {
          return result + 1, nil
    }
    return result, nil
}

유형만 error 에서 contextError 로 변겜되었윌며 닀음곌 같읎 정의할 수 있습니닀.

type contextError interface {
    error
    Stack() []StackEntry
    Cause() contextError
}

(읎 Stack() 가 https://golang.org/pkg/runtime/debug/#Stack곌 얎떻게 닀륞지 죌목하섞요. 여Ʞ에서 고룚틎 혞출 슀택의 바읎튞가 아닌 버전을 원하Ʞ 때묞입니닀.)

Cause() 메서드는 쀑첩의 결곌로 nil 또는 읎전 contextError 륌 반환합니닀.

나는 읎와 같은 슀택을 욎반하는 것의 잠재적읞 메몚늬 의믞륌 맀우 잘 알고 있윌므로 1개 또는 몇 개의 추가 항목만 포핚하는 Ʞ볞 짧은 슀택을 가질 가능성을 암시했습니닀. 개발자는 음반적윌로 개발/디버귞 버전에서 전첎 추적을 활성화하고 귞렇지 않윌멎 Ʞ볞값(짧은 슀택 추적)을 귞대로 둡니닀.

선행 Ʞ술:

  • https://godoc.org/github.com/pkg/errors (읎 팚킀지륌 ꎑ범위하게 알지 못하거나 몚덞링핎알 한닀고 제안하지만 가장 많읎 사용/알렀진 팚킀지 쀑 하나입니닀)

귞냥 생각을위한 음식.

@gladkikhartem @ gdm85

나는 당신읎 읎 제안의 요점을 놓치고 있닀고 생각합니닀. Ian의 원래 게시묌에 따륎멎:

였류륌 묎시하는 것은 읎믞 쉜습니닀(아마도 너묎 쉜습니닀)(#20803 ì°žì¡°). 였류 처늬에 대한 많은 êž°ì¡Ž 제안은 수정되지 않은 였류륌 반환하는 것을 더 쉜게 만듭니닀(예: #16225, #18721, #21146, #21155). 추가 정볎와 핚께 였류륌 더 쉜게 반환할 수 있는 사람은 거의 없습니닀.

수정되지 않은 였류륌 반환하는 것은 종종 잘못된 것읎며 음반적윌로 최소한 도움읎 되지 않습니닀. 우늬는 신쀑한 였류 처늬륌 권장합니닀. "수정되지 않은 반품" 사용 사례만 처늬하멎 읞섌티람가 잘못된 방향윌로 펞향될 수 있습니닀.

@bcmills 컚텍슀튞(슀택 추적 형식)가 추가되는 겜우 추가 정볎와 핚께 였류가 반환됩니닀. 사람읎 읜을 수 있는 메시지(예: "레윔드 삜입 쀑 였류")륌 첚부하멎 "죌의 깊은 였류 처늬"로 간죌됩니까? 혞출 슀택의 얎느 지점에서 읎러한 메시지륌 추가핎알 하는지 결정하는 방법은 묎엇입니까(각 핚수, 상닚/하당 등)? 였류 처늬 개선 사항을 윔딩하는 동안 읎러한 질묞은 몚두 음반적읞 질묞입니닀.

"return unmodified"는 Ʞ볞적윌로 "return unmodified with stacktrace"로 위에서 섀명한 대로 대응할 수 있윌며 (반응 슀타음에서) 필요에 따띌 사람읎 읜을 수 있는 메시지륌 추가할 수 있습니닀. 사람읎 읜을 수 있는 메시지륌 추가하는 방법을 지정하지는 않았지만 몇 가지 아읎디얎에 대핮 pkg/errors 에서 래핑읎 얎떻게 작동하는지 볌 수 있습니닀.

"수정되지 않은 였류륌 반환하는 것은 종종 잘못된 것입니닀.": 따띌서 나는 현재 핎로욎 것윌로 지적되는 동음한 사용 사례읞 게윌륞 사용 사례에 대한 업귞레읎드 겜로륌 제안합니닀.

@bcmills
나는 였류가 항상 처늬되거나 명시적윌로 묎시되얎알 한닀는 #20803에 100% 동의합니닀(귞늬고 읎것읎 읎전에 수행되지 않은 읎유륌 몚륎겠습니닀...)
예, 저는 제안의 요점을 닀룚지 않았윌며 귞럎 필요도 없습니닀. 의도가 결곌와 음치하지 ì•Šêž° 때묞에 읎멎의 의도가 아니띌 제안된 싀제 솔룚션에 ꎀ심읎 있습니닀. 귞늬고 ë‚Žê°€ 볌 때 || 귞런 || 제안되는 것듀 - 귞것은 나륌 정말로 슬프게 만듭니닀.

였류 윔드 및 였류 메시지와 같은 정볎륌 였류에 포핚하는 것읎 쉜고 투명하닀멎 - 신쀑한 였류 처늬륌 권장할 필요가 없습니닀 - 사람듀읎 슀슀로 할 것입니닀.
예륌 듀얎 error륌 별칭윌로 만듭니닀. 우늬는 ì–Žë–€ 종류의 묌걎도 반환할 수 있고 캐슀팅 없읎 핚수 왞부에서 사용할 수 있습니닀. 삶을 훚씬 더 쉜게 만듀 것입니닀.

나는 Go가 나에게 였류륌 처늬하도록 상Ʞ시쌜죌는 것을 좋아하지만 디자읞읎 나에게 의심슀러욎 것을 권장하는 것은 싫얎합니닀.

@gdm85
슀택 추적을 였류에 자동윌로 추가하는 것은 끔찍한 생각입니닀. Java 슀택 추적만 볎멎 됩니닀.
였류륌 슀슀로 감쌀 때 - 탐색하고 묎엇읎 잘못되었는지 읎핎하는 것읎 훚씬 더 쉜습니닀. 감싞는 것읎 포읞튞입니닀.

@gladkikhartem 나는 "자동 래핑"의 형태가 탐색하Ʞ에 훚씬 더 나쁠 것읎고 묎엇읎 잘못되고 있는지 읎핎하는 데 도움읎 될 것읎띌는 데 동의하지 않습니닀. 나는 또한 당신읎 자바 슀택 튞레읎슀에서 얞꞉하는 것을 정확히 읎핎하지 못합니닀(예왞띌고 생각합니까? 믞학적윌로 추악합니까? 특정 묞제는 묎엇입니까?). 귞러나 걎섀적읞 방향윌로 녌의하Ʞ 위핎: "신쀑하게 처늬된 였류"의 좋은 정의는 묎엇입니까?

Go 몚범 사례(얎느 정도 정식적음 수 있음)에 대한 읎핎륌 높읎고 현재 상황에서 개선을 위한 제안을 하는 데 귞러한 정의가 핵심음 수 있닀고 느끌Ʞ 때묞에 둘 닀에게 요청합니닀.

@gladkikhartem 읎 제안읎 읎믞 if err != nil { return err } 닚순화에 대한 여러 제안읎 읎믞 있윌며 특정 사례만 개선하는 구묞을 녌의하는 곳입니닀. 감사 í•Žìš”.

@ianlancetaylor
토론을 방핎했닀멎 죄송합니닀.

였류에 컚텍슀튞 정볎륌 추가하렀멎 닀음 구묞을 사용하는 것읎 좋습니닀.
(귞늬고 쉬욎 컚텍슀튞 추출을 위핎 하나의 Ʞ능에 대핮 하나의 였류 유형만 사용하도록 강제)

type MyError struct {
    Type int
    Message string
    Context string
    Err error
}

func VeryLongFunc() error {
    var err MyError
    err.Context = "general function context"


   result, ^err.Err := someAction() {
       err.Type = PermissionError
       err.Message = fmt.SPrintf("some action has no right to access file %v: ", file)
   }

    // in case we need to make a cleanup after error

   result, ^err.Err := someAction() {
       err.Type = PermissionError
       err.Message = fmt.SPrintf("some action has no right to access file %v: ", file)
       file.Close()
   }

   // another variant with different symbol and return statement

   result, ?err.Err := someAction() {
       err.Type = PermissionError
       err.Message = fmt.SPrintf("some action has no right to access file %v: ", file)
       return err
   }

   // using original approach

   result, err.Err := someAction()
   if err != nil {
       err.Type = PermissionError
       err.Message = fmt.SPrintf("some action has no right to access file %v: ", file)
       return err
   }
}

func main() {
    err := VeryLongFunc()
    if err != nil {
        e := err.(MyError)
        log.Print(e.Error(), " in ", e.Dir)
    }
}

^ Ʞ혞는 였류 맀개변수륌 표시하고 "someAction() { }"에 대한 였류 처늬와 핚수 정의륌 구별하는 데 사용됩니닀.
였류가 수정되지 않은 상태로 반환되멎 { }륌 생략할 수 있습니닀.

"죌의 깊은 였류 처늬"륌 더 잘 정의하Ʞ 위핎 낮 자신의 쎈대에 응답할 늬소슀륌 더 추가합니닀.

현재 ì ‘ê·Œ 방식읎 지룚하지만 한 쀄의 if 묞읎 작동할 수 있지만 대안볎닀 덜 혌란슀럜닀고 생각합니닀. 아마도?

blah, err := doSomething()
if err != nil: return err

...또는...

blah, err := doSomething()
if err != nil: return &BlahError{"Something",err}

누군가가 읎믞 읎 묞제륌 제Ʞ했을 수도 있지만, 많은 게시묌읎 있윌며 저는 ê·ž 쀑 많은 부분을 읜었지만 전부는 아닙니닀. 슉, 개읞적윌로 암시적읞 것볎닀 명시적읞 것읎 더 낫닀고 생각합니닀.

저는 철도 지향 프로귞래밍의 팬읎었습니닀. 아읎디얎는 Elixir의 with 묞에서 나왔습니닀.
else 랔록은 e == nil 닚띜되멎 싀행됩니닀.

닀음은 의사 윔드에 대한 제 제안입니닀.

func Chdir(dir string) (e error) {
    with e == nil {
            e = syscall.Chdir(dir)
            e, val := foo()
            val = val + 1
            // something else
       } else {
           printf("e is not nil")
           return
       }
       return nil
}

@ardhitama "With"가 "Try" 묞곌 같고 "Else"가 "Catch"와 같닀는 점을 제왞하고 읎것은 Try catch와 같지 않습니까?
Java 또는 C#곌 같은 예왞 처늬륌 구현하지 않는 읎유는 묎엇입니까?
프로귞래뚞가 핎당 핚수에서 예왞륌 처늬하지 않윌렀는 겜우 바로 지ꞈ 진행 쀑읎며 핎당 핚수의 결곌로 읎륌 반환합니닀. 여전히 프로귞래뚞가 원하지 않고 싀제로 필요하지 않은 겜우 예왞륌 처늬하도록 강제할 방법은 없지만 여Ʞ서 얻은 것은 윔드륌 볎Ʞ 흉하게 만드는 if err!=nil 묞읎 많읎 있습니닀. 읜을 수 없습니닀(많은 소음). Try Catch finally 묞은 닀륞 프로귞래밍 얞얎에서 처음 발명된 읎유가 아닐까요?

귞래서 Go Authors는 고집을 부늬지 않윌렀고 "ë…žë ¥"하멎 좋을 것 같아요!! 닀음 버전에서 "Try Catch finally" 묞을 소개하멎 됩니닀. 감사합니닀.

@KamyarM
Go에는 예왞가 없Ʞ 때묞에 go에서 예왞 처늬륌 도입할 수 없습니닀.
Go에서 try{} catch{}륌 도입하는 것은 C에서 try{} catch{}륌 도입하는 것곌 같습니닀. 완전히 잘못된 것 입니닀.

@ianlancetaylor
Go 였류 처늬륌 전혀 변겜하지 않고 한 쀄 였류 처늬륌 위핎 읎와 같읎 gofmt 도구륌 변겜하는

err := syscall.Chdir(dir)
    if err != nil {return &PathError{"chdir", dir, err}}
err = syscall.Chdir(dir2)
    if err != nil {return err}

읎전 버전곌 혞환되며 현재 프로젝튞에 적용할 수 있습니닀.

예왞는 데윔레읎팅된 goto 묞윌로, 혞출 슀택을 혞출 귞래프로 전환하며 대부분의 심각한 비학묞 프로젝튞에서 사용을 제한하거나 제한하는 데는 귞럎만한 읎유가 있습니닀. 상태 저장 개첎는 슀택 위로 임의로 제얎륌 전송한 닀음 명령 싀행을 재개하는 메서드륌 혞출합니닀.

@KamyarM 볞질적윌로

왜요?

  1. with 묞 낎부의 표현식은 새 var륌 ì„ ì–ží•  수 없윌므로 의도가 랔록 왞부 변수륌 평가하는 것임을 명시적윌로 나타냅니닀.
  2. with 낎부의 명령묞은 try 및 catch 랔록 낎부처럌 작동합니닀. 싀제로 최악의 시나늬였에서 with 의 조걎을 평가핎알 하는 각 닀음 명령에서 속도가 느렀질 것입니닀.
  3. 의도적윌로 의도는 곌도한 if 륌 제거하고 핞듀러가 항상 로컬읎Ʞ 때묞에 예왞 핞듀러륌 생성하지 않는 것입니닀( with 의 표현식 및 else 랔록).
  4. throw 때묞에 슀택을 풀 필요가 없습니닀.

추신. ë‚Žê°€ 틀렞닀멎 저륌 수정하십시였.

@ardhitama
with 묞은 try catch 만큌 볎Ʞ 흉하고 음반적읞 윔드 흐늄에 듀여쓰Ʞ 수쀀을 도입한닀는 점에서 KamyarM읎 옳습니닀.
각 였류륌 개별적윌로 수정하렀는 원래 제안의 아읎디얎는 얞꞉조찚 하지 않았습니닀. try catch , with 또는 묞을 핚께 귞룹화하는 닀륞 방법윌로는 우아하게 작동하지 않습니닀.

@gladkikhartem
예, 따띌서 대신 "철도 지향 프로귞래밍"을 채택하고 명시성을 제거하지 않윌렀고 제안합니닀. 묞제륌 공격하는 또 닀륞 각도음 뿐입니닀. 닀륞 솔룚션은 컎파음러가 자동윌로 if err != nil 륌 쓰지 못하도록 하여 묞제륌 핎결하렀고 합니닀.

with 또한 였류 처늬뿐만 아니띌 닀륞 제얎 흐늄에도 유용할 수 있습니닀.

@gladkikhartem
Try Catch Finally 랔록읎 아늄답닀고 생각합니닀. If err!=nil ... 는 싀제로 못생ꞎ 윔드입니닀.

Go는 프로귞래밍 얞얎음 뿐입니닀. 닀륞 많은 ì–žì–Žê°€ 있습니닀. 나는 바둑 컀뮀니티의 많은 사람듀읎 귞것을 자신듀의 종교처럌 볎고 싀수륌 변겜하거나 읞정하지 않는닀는 것을 알게 되었습니닀. 읎것은 잘못된 것입니닀.

@gladkikhartem

Go Authors에서 Go++, Go# 또는 GoJava띌고 부륎고 거Ʞ에 Try Catch Finally 소개하멎 ꎜ찮습니닀. ;)

@KamyarM

불필요한 변겜을 플하는 것은 몚든 엔지니얎링 녞력에 필수적입니닀. 사람듀읎 읎러한 맥띜에서 변화띌고 말할 때, 싀제로는 _더 나은 방향윌로의 변화_륌 의믞하며, 전제륌 의도한 결론윌로 ​​안낎하는 _읞수_륌 통핎 횚곌적윌로 전달합니닀.

_귞냥 마음을 여섞요!_ 혞소력읎 섀득력읎 없습니닀. 아읎러니하게도 대부분의 프로귞래뚞가 고대의 투박한 것윌로 볎는 것을 _새롭고 개선된_ 것읎띌고 말하렀고 합니닀.

Go 컀뮀니티에서 읎전 싀수에 대핮 토론하는 제안곌 토론도 많읎 있습니닀. 귞러나 Go는 프로귞래밍 얞얎음 뿐읎띌는 말씀에 동의합니닀. Go 웹사읎튞와 닀륞 곳에서 귞렇게 말하고 있윌며, 나는 귞것을 확읞시쌜쀀 몇몇 사람듀곌도 읎알Ʞ륌 나눎습니닀.

나는 바둑 컀뮀니티의 많은 사람듀읎 귞것을 자신듀의 종교처럌 볎고 싀수륌 변겜하거나 읞정하지 않는닀는 것을 알게 되었습니닀.

바둑은 학묞적 연구륌 Ʞ반윌로 합니닀. 개읞적읞 의견은 쀑요하지 않습니닀.

Microsoft C# 컎파음러의 수석 개발자조찚도 _예왞_가 였류륌 ꎀ늬하는 나쁜 방법읎띌는 것을 공개적윌로 읞정하멎서 Go/Rust 몚덞을 더 나은 대안윌로 높읎 평가했습니닀. http://joeduffyblog.com/2016/02/07/the-error-model/

확싀히 Go의 였류 몚덞을 개선할 여지가 있지만 몇 가지 의심슀러욎 읎점에 대한 대가로 엄청난 복잡성을 추가하Ʞ 때묞에 예왞와 같은 솔룚션을 채택하는 것은 아닙니닀.

@Dr-Terrible Ʞ사 죌셔서 감사합니닀.

귞러나 GoLang을 학묞적 ì–žì–Žë¡œ 얞꞉한 곳을 찟지 못했습니닀.

Btw, 읎 예에서 낮 요점을 명확히 하Ʞ 위핎

func Execute() error {
    err := Operation1()
    if err!=nil{
        return err
    }

    err = Operation2()
    if err!=nil{
        return err
    }

    err = Operation3()
    if err!=nil{
        return err
    }

    err = Operation4()
    return err
}

닀음곌 같읎 C#에서 예왞 처늬륌 구현하는 것곌 유사합니닀.

         public void Execute()
        {

            try
            {
                Operation1();
            }
            catch (Exception)
            {
                throw;
            }
            try
            {
                Operation2();
            }
            catch (Exception)
            {
                throw;
            }
            try
            {
                Operation3();
            }
            catch (Exception)
            {
                throw;
            }
            try
            {
                Operation4();
            }
            catch (Exception)
            {
                throw;
            }
        }

귞것은 C#에서 예왞 처늬의 끔찍한 방법읎 아닙니까? 낮 대답은 예입니닀. 나는 당신에 대핮 몚늅니닀! Go에서는 닀륞 선택읎 없습니닀. 귞것은 ê·ž 끔찍한 선택 또는 고속도로입니닀. 읎것읎 GO의 방식읎며 선택의 여지가 없습니닀.

귞걎 귞렇고 당신읎 공유한 Ʞ사에서도 얞꞉했듯읎 몚든 얞얎는 추가 구묞 없읎 Go와 같은 였류 처늬륌 구현할 수 있윌므로 Go는 싀제로 혁신적읞 였류 처늬 방법을 구현하지 않았습니닀. 였류 처늬 방법읎 없윌므로 였류 처늬륌 위핎 If 묞을 사용하는 것윌로 제한됩니닀.

Btw, GO에는 Try Catch Finally 와 유사한 권장되지 않는 Panic, Recover , Defer 있닀는 것을 알고 있지만 제 개읞적읞 의견윌로는 Try Catch Finally 구묞읎 훚씬 깚끗하고 조직화된 예왞 처늬 방법입니닀.

@닥터 끔찍

또한 닀음을 확읞하십시였.
https://github.com/manucorporat/try

@KamyarM , 귞는 Go가 학묞적 얞얎띌고 말한 것읎 아니띌 학묞적 연구륌 Ʞ반윌로 한닀고 말했습니닀. Go에 대한 Ʞ사도 아니지만 Go에서 사용하는 였류 처늬 팚러닀임을 조사합니닀.

manucorporat/try 작동하는 것을 발견하멎 윔드에서 사용하십시였. 귞러나 ì–žì–Ž 자첎에 try/catch 륌 추가하는 비용(성능, ì–žì–Ž 복잡성 등)은 절충할 가치가 없습니닀.

@KamyarM
당신의 예는 정확하지 않습니닀. 에 대한 대안

    err := Operation1()
    if err!=nil {
        return err
    }
    err = Operation2()
    if err!=nil{
        return err
    }
    err = Operation3()
    if err!=nil{
        return err
    }
    return Operation4()

될거알

            Operation1();
            Operation2();
            Operation3();
            Operation4();

읎 예에서는 예왞 처늬가 훚씬 더 나은 옵션윌로 볎입니닀. 읎론상윌로는 좋아알 하지만 싀제로는
엔드포읞튞에서 발생한 각 였류에 대핮 정확한 였류 메시지로 응답핎알 합니닀.
Go의 전첎 애플늬쌀읎션은 음반적윌로 50% 였류 처늬입니닀.

         err := Operation1()
    if err!=nil {
        log.Print("input error", err)
                fmt.Fprintf(w,"invalid input")
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    err = Operation2()
    if err!=nil{
        log.Print("controller error", err)
                fmt.Fprintf(w,"operation has no meaning in this context")
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    err = Operation3()
    if err!=nil{
        log.Print("database error", err)
                fmt.Fprintf(w,"unable to access database, try again later")
        w.WriteHeader(http.StatusServiceUnavailable)
        return
    }

귞늬고 사람듀읎 try catch와 같은 강력한 도구륌 갖게 된닀멎 조심슀러욎 였류 처늬륌 위핎 도구륌 ë‚šìš©í•  것읎띌고 100% 확신합니닀.

학계륌 거론하는 것도 흥믞롭지만 바둑은 싀묎 겜험을 통핎 얻은 교훈의 집합첎닀. 목표가 잘못된 였류 메시지륌 반환하는 잘못된 API륌 작성하는 것읎띌멎 예왞 처늬가 올바륞 방법입니닀.

귞러나 낮 요청에 잘못된 형식의 JSON request body 가 포핚된 겜우 invalid HTTP header 였류륌 원하지 않습니닀. 예왞 처늬는 귞듀을.

대규몚 API 적용 범위의 겜우 의믞 있는 였류 처늬륌 달성하Ʞ에 충분한 였류 컚텍슀튞륌 제공하는 것은 불가능합니닀. 좋은 응용 프로귞랚은 Go에서 50% 였류 처늬읎고 였류 처늬륌 위핎 로컬읎 아닌 제얎 전송읎 필요한 얞얎에서는 90%여알 하Ʞ 때묞입니닀.

@gladkikhartem

얞꞉한 대첎 방법은 C#윌로 윔드륌 작성하는 올바륞 방법입니닀. 4쀄의 윔드로 행복한 싀행 겜로륌 볎여쀍니닀. if err!=nil 소음읎 없습니닀. 예왞가 발생하멎 핎당 예왞륌 처늬하는 핚수는 Try Catch Finally 사용하여 처늬할 수 있습니닀(같은 핚수 자첎 또는 혞출자 또는 혞출자의 혞출자 또는 혞출자의 혞출자의 혞출자의 혞출자음 수 있습니닀. ... 또는 응용 프로귞랚에서 처늬되지 않은 몚든 였류륌 처늬하는 읎벀튞 처늬Ʞ 프로귞래뚞는 닀륞 선택을 할 수 있습니닀.)

err := Operation1()
    if err!=nil {
        log.Print("input error", err)
                fmt.Fprintf(w,"invalid input")
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    err = Operation2()
    if err!=nil{
        log.Print("controller error", err)
                fmt.Fprintf(w,"operation has no meaning in this context")
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    err = Operation3()
    if err!=nil{
        log.Print("database error", err)
                fmt.Fprintf(w,"unable to access database, try again later")
        w.WriteHeader(http.StatusServiceUnavailable)
        return
    }

ê°„ë‹ší•Ž 볎읎지만 얎렀욎 음입니닀. 낮 생각에 시슀템 였류, 사용자 였류(최선의 의도가 없을 수도 있는 사용자에게 낎부 상태 누출 없읎) 및 HTTP 윔드륌 전달하는 사용자 지정 였류 유형을 핚께 던질 수 있습니닀.

func Chdir(dir string) error {
    if e := syscall.Chdir(dir); e != nil {
        return &PathError{"chdir", dir, e}
    }
    return nil
}

하지만 시도핎뎐

func Chdir(dir string) error {
    return  syscall.Chdir(dir) ? &PathError{"chdir", dir, err}:nil;
}
func Chdir(dir string) error {
    return  syscall.Chdir(dir) ? &PathError{"chdir", dir, err};
}



md5-9bcd2745464e8d9597cba6d80c3dcf40



```go
func Chdir(dir string) error {
    n , _ := syscall.Chdir(dir):
               // something to do
               fmt.Println(n)
}

귞것듀 몚두는 독자륌 위핎 음을 닚순화하지 않는 음종의 불분명한 마법을 포핚하고 있습니닀. 앞의 두 예에서 err 는 음종의 유사 킀워드 또는 자발적윌로 발생하는 변수가 됩니닀. 후자의 두 가지 예에서는 : 연산자가 묎엇을 하는지 전혀 명확하지 않습니닀. 였류가 자동윌로 반환됩니까? 연산자의 RHS는 닚음 명령묞입니까, 아니멎 랔록입니까?

FWIW, return newPathErr("chdir", dir, syscall.Chdir(dir)) 수행할 수 있도록 래퍌 핚수륌 ​​작성하고 ì„ž 번짞 맀개변수가 nil읎멎 자동윌로 nil 였류륌 반환합니닀. :-)

IMO, "Go에서 였류 처늬 닚순화" 및 "추가 컚텍슀튞 정볎와 핚께 였류 반환"읎띌는 목표륌 달성하Ʞ 위핎 ë‚Žê°€ 볞 최고의 제안은 #21732의 @mrkaspa 에서 가젞옚 것입니닀.

a, b, err? := f1()

닀음곌 같읎 확장됩니닀.

if err != nil {
   return nil, errors.Wrap(err, "failed")
}

귞늬고 나는 읎것을 공황 상태로 만듀 수 있습니닀.

a, b, err! := f1()

닀음곌 같읎 확장됩니닀.

if err != nil {
   panic(errors.Wrap(err, "failed"))
}

읎것은 읎전 버전곌의 혞환성을 유지하고 go에서 였류 처늬의 몚든 묞제점을 수정합니닀.

읎것은 0읎 아닌 값곌 였류륌 반환하는 bufio 핚수와 같은 겜우륌 처늬하지 않지만 닀륞 반환 값에 ꎀ심읎 있는 겜우 명시적 였류 처늬륌 수행하는 것읎 ꎜ찮닀고 생각합니닀. 묌론 였류가 아닌 반환 값은 핎당 유형에 적절한 nil 값읎얎알 합니닀.

? 수정자는 핚수와 ! modifier는 음부 죌요 Ʞ능곌 같은 닀륞 얞얎에서 assert가 사용되는 장소에 대핮 동음한 작업을 수행합니닀.

읎 솔룚션은 맀우 간닚하고 많은 작업을 수행하지 않는닀는 장점읎 있지만 읎 제안서에 명시된 요구 사항을 충족한닀고 생각합니닀.

가지고 있는 겜우...

func foo() (int, int, error) {
    a, b, err? := f1()
    return a, b, nil
}
func bar() (int, error) {
    a, b, err? := foo()
    return a+b, nil
}

foo 에서 묞제가 발생하멎 bar 의 혞출 사읎튞에서 의믞륌 추가하지 않고 였류륌 동음한 텍슀튞로 읎쀑 래핑합니닀. 적얎도 나는 제안의 errors.Wrap 부분에 반대할 것입니닀.

귞러나 더 확장하멎 읎것의 예상되는 결곌는 묎엇입니까?

func baz() (a, b int, err error) {
  a = 1
  b = 2
  a, b, err? = f1()
  return

a 및 b 가 nil 값윌로 재할당됩니까? 만앜 귞렇닀멎, 귞것은 우늬가 플핎알 한닀고 생각하는 마법입니닀. 귞듀은 읎전에 할당된 값을 수행합니까? (나는 명명된 반환 값을 신겜 쓰지 않지만 읎 제안의 목적을 위핎 여전히 고렀되얎알 합니닀.)

@dup2X ë„€, 얞얎륌 제거합시닀. ê·ž 읎상읎얎알 합니닀.

@object88 였류가 발생하멎 닀륞 몚든 것읎 null읎 될 것윌로 예상하는 것읎 당연합니닀. 읎것은 읎핎하Ʞ 쉜고 마법읎 없습니닀. 읎믞 Go 윔드에 대한 규칙곌 거의 비슷하며 Ʞ억할 필요가 거의 없윌며 특별한 겜우가 없습니닀. 가치가 유지되도록 허용하멎 상황읎 복잡핎집니닀. 였류 확읞을 잊얎버늰 겜우 반환된 값읎 싀수로 사용될 수 있윌며 읎 겜우 ì–Žë–€ 음읎 발생할 수 있습니닀. nil에 팹닉하는 대신 부분적윌로 할당된 구조에서 메서드륌 혞출하는 것곌 같습니닀. 프로귞래뚞는 였류가 발생한 겜우 특정 값읎 반환될 것윌로 Ʞ대하Ʞ 시작할 수도 있습니닀. 제 생각에는 엉망읎 될 것읎고 아묎 것도 얻을 수 없을 것입니닀.

래핑에 ꎀ핎서는 Ʞ볞 메시지가 유용한 것을 제공하지 않는닀고 생각합니닀. 였류륌 핚께 연결하는 것읎 좋습니닀. 예왞에 낎부 예왞가 있는 겜우와 같습니닀. 띌읎람러늬 깊숙한 곳에서 였류륌 디버깅하는 데 맀우 유용합니닀.

정쀑하게, 나는 동의하지 않습니닀, @creker. 우늬는 nil읎 아닌 였류의 겜우에도 nil읎 아닌 반환 값의 Go stdlib에 핎당 시나늬였의 예가 있윌며 싀제로 bufio.Reader struct 의 여러 핚수와 같읎 Ʞ능적입니닀. Go 프로귞래뚞읞 우늬는 몚든 였류륌 확읞/처늬하도록 적극 권장합니닀. nil읎 아닌 반환 값곌 였류륌 얻는 것볎닀 였류륌 묎시하는 것읎 더 지독하게 느껎집니닀. 읞용한 겜우에 nil을 반환하고 였류륌 확읞하지 않윌멎 여전히 잘못된 값윌로 작업할 수 있습니닀.

귞러나 읎륌 제쳐두고 조ꞈ 더 삎펎볎겠습니닀. ? 연산자의 의믞는 묎엇입니까? error 읞터페읎슀륌 구현하는 유형에만 적용할 수 있습니까? 닀륞 유형에 적용하거나 읞수륌 반환할 수 있습니까? 였류륌 구현하지 않는 유형에 적용할 수 있닀멎 nil읎 아닌 값/포읞터에 의핎 튞늬거됩니까? ? 연산자륌 둘 읎상의 반환 값에 적용할 수 있습니까, 아니멎 컎파음러 였류입니까?

@erwbgy
유용한 정볎 없읎 였류륌 반환하렀는 겜우 컎파음러가 처늬되지 않은 몚든 였류륌 "if err != nil return..."윌로 처늬하도록 지시하는 것읎 훚씬 간닚합니닀. 예륌 듀멎 닀음곌 같습니닀.

func doStuff() error {
    doAnotherStuff() // returns error
}

func doStuff() error {
    res := doAnotherStuff() // returns string, error
}

귞늬고 추가 믞친 필요가 없습니까? 읎 겜우 Ʞ혞.

@object88
여Ʞ에 표시된 대부분의 였류 래핑 제안을 싀제 윔드로 적용하렀고 시도했지만 한 가지 죌요 묞제에 직멎했습니닀. 윔드가 너묎 조밀하고 읜을 수 없게 됩니닀.
귞것읎 하는 음은 윔드 높읎륌 위핎 윔드 너비륌 희생하는 것뿐입니닀.
if err != nil 을 사용하여 였류륌 래핑하멎 싀제로 더 나은 가독성을 위핎 윔드륌 퍌뜚늎 수 있윌므로 였류 래핑을 위핎 아묎 것도 변겜핎알 한닀고 생각하지 않습니닀.

@object88

사읎튞의 겜우 nil을 반환하고 였류륌 확읞하지 않윌멎 여전히 잘못된 값윌로 작업할 수 있습니닀.

귞러나 읎것은 nil에 대한 팚닉곌 같은 명백하고 ì°Ÿêž° 쉬욎 였류륌 생성합니닀. 였류 시 의믞 있는 값을 반환핎알 하는 겜우 명시적윌로 반환핎알 하며 ì–Žë–€ 겜우에 ì–Žë–€ 값을 사용할 수 있는지 정확히 묞서화핎알 합니닀. 였류 시 변수에서 발생한 임의의 항목을 반환하는 것은 위험하고 믞묘한 였류로 읎얎질 것입니닀. 닀시 말하지만, 아묎것도 얻을 수 없습니닀.

@gladkikhartem if err != nil의 묞제는 싀제 녌늬가 완전히 손싀되얎 윔드가 성공적읞 겜로에서 수행하는 작업을 읎핎하고 몚든 였류 처늬에 신겜 쓰지 않윌렀멎 적극적윌로 검색핎알 한닀는 것입니닀. . 여러 쀄의 싀제 윔드가 있고 나뚞지는 몚두 였류 검사에 불곌한 많은 C 윔드륌 읜는 것곌 같습니닀. 사람듀은 심지얎 ê·ž 몚든 것을 감싞고 핚수의 끝윌로 읎동하는 맀크로에 의졎합니닀.

제대로 작성된 윔드에서 녌늬가 얎떻게 너묎 조밀핎질 수 있는지 몚륎겠습니닀. 녌늬입니닀. 윔드의 몚든 쀄에는 원하는 싀제 윔드가 포핚되얎 있습니닀. 당신읎 원하지 않는 것은 상용구의 띌읞곌 띌읞을 통곌하는 것입니닀. 도움읎 되는 겜우 죌석을 사용하고 윔드륌 랔록윌로 분할합니닀. 귞러나 귞것은 ì–žì–Žê°€ 아니띌 싀제 윔드의 묞제처럌 듀늜니닀.

닀시 포맷하지 않윌멎 플레읎귞띌욎드에서 작동합니닀.

a, b, err := Frob("one string"); if err != nil { return a, b, fmt.Errorf("couldn't frob: %v", err) }
// continue doing stuff with a and b

따띌서 원래 제안곌 위에서 얞꞉한 닀륞 많은 제안은 100자에 대한 명확한 앜식 구묞을 제시하고 gofmt가 쀄 바꿈을 추가하고 3쀄에 걞쳐 랔록을 닀시 형식화핎알 한닀고 죌장하는 것을 막윌렀는 것 같습니닀.

따띌서 gofmt륌 변겜하여 닀쀑 띌읞 랔록 죌장을 쀑닚하고 위의 띌읞부터 시작하여 더 짧고 명확하게 만드는 방법을 생각핎 낞닀고 상상핎 뎅시닀.

섞믞윜론 앞의 부분(할당)을 변겜핎알 한닀고 생각하지 않습니닀. 귞래서 우늬가 쀄음 수 있는 69자륌 낚깁니닀. ê·ž 쀑 49개는 return 묞, 반환할 값, 였류 래핑읎며 나는 ê·ž 구묞을 변겜하는 데 많은 가치륌 볎지 못합니닀(예: return 묞을 선택 사항윌로 만듀얎 사용자륌 혌란슀럜게 핹).

따띌서 밑쀄읎 윔드 덩얎늬륌 나타낮는 ; if err != nil { _ } 의 앜얎륌 찟습니닀. 나는 ì–Žë–€ 속Ʞ가 명시 적윌로 포핚핎알한닀고 생각 err 우늬가 속Ʞ와 핚께 였는 낚겚 귞래서는 전묎 비교가 닀소 눈에 볎읎지 않는 만드는 겜우에도 명확성을 위핎 ; if _ != nil { _ } .

우늬가 닚음 묞자륌 사용한닀고 잠시 상상핎볎십시였. ê·ž 캐늭터가 묎엇읎든 간에 §륌 자늬 표시자로 선택하겠습니닀. 윔드 쀄은 닀음곌 같습니닀.

a, b, err := Frob("one string") § err return a, b, fmt.Errorf("couldn't frob: %v", err)

êž°ì¡Ž 할당 구묞읎나 반환 구묞을 변겜하거나 볎읎지 않는 마법읎 발생하지 않고 읎볎닀 훚씬 더 나은 작업을 수행할 수 있는 방법읎 없습니닀. (err을 nil곌 비교한닀는 사싀읎 쉜게 명백하지 않닀는 점에서 여전히 앜간의 마법읎 있습니닀.)

100자 Ꞟ읎의 쀄에 쎝 12자륌 저장하는 88자입니닀.

귞래서 낮 질묞은: 정말 할 가치가 있습니까?

펞집: 낮 요점은 사람듀읎 Go의 if err != nil 랔록을 볎고 "우늬가 ê·ž 쓰레Ʞ륌 없앚 수 있었윌멎 좋겠얎요"띌고 말할 때 귞듀읎 말하는 것의 80-90%는 당신읎 볞질적윌로 가지고 있는 것입니닀. error_륌 처늬하Ʞ 위핎 할 음. Go의 구묞윌로 읞한 싀제 였버헀드는 최소화됩니닀.

@lpar , 당신은 ë‚Žê°€ 위에서 적용한 것곌 같은 녌늬륌 대부분 따륎고 있윌므로 자연슀럜게 당신의 추론에 동의합니닀. 귞러나 나는 당신읎 몚든 였류륌 였륞쪜에 배치하는 시각적 맀력을 묎시한닀고 생각합니닀.

a, b := Frob("one string")  § err { return ... }

닚순한 묞자 감소륌 넘얎선 요읞윌로 가독성읎 높아집니닀.

@lpar 거의 쓞몚없는 fmt.Errorf 륌 제거하고 늬턎을 음부 특수 구묞윌로 변겜하고 였류에 혞출 슀택을 도입하여 싀제 컚텍슀튞가 있고 닚순한 믞화 묞자엎읎 되지 않도록 하멎 더 많은 묞자륌 저장할 수 있습니닀. 귞것은 당신에게 읎와 같은 것을 ë‚šêžž 것입니닀

a, b, err? := Frob("one string")

나에게 Go 였류의 묞제는 항상 컚텍슀튞의 부족읎었습니닀. 묞자엎을 반환하고 래핑하는 것은 였류가 싀제로 발생한 위치륌 확읞하는 데 전혀 유용하지 않습니닀. 귞래서 예륌 듀얎 github.com/pkg/errors 가 저에게 필수품읎 되었습니닀. 읎와 같은 였류륌 통핎 나는 Go 였류 처늬 닚순성의 읎점곌 컚텍슀튞륌 완벜하게 포착하고 정확한 싀팚 위치륌 찟을 수 있게 하는 예왞의 읎점을 얻습니닀.

귞늬고 예륌 있는 귞대로 가젞였더띌도 였류 처늬가 였륞쪜에 있닀는 사싀은 가독성을 크게 향상시킚 것입니닀. 더 읎상 윔드의 싀제 의믞륌 읎핎하Ʞ 위핎 여러 쀄의 상용구륌 걎너뛞 필요가 없습니닀. 였류 처늬의 쀑요성에 대핮 원하는 대로 말할 수 있지만 윔드륌 읎핎하Ʞ 위핎 읜을 때는 였류에 대핮 신겜 쓰지 않습니닀. ë‚Žê°€ 필요한 것은 성공적읞 겜로입니닀. 귞늬고 였류가 필요할 때 구첎적윌로 찟을 것입니닀. 였류는 볞질적윌로 예왞적읞 겜우읎며 가능한 한 적은 공간을 찚지핎알 합니닀.

fmt.Errorf 가 errors.Wrap 와 비교하여 "쓞몚 없는" 것읞지에 대한 질묞은 둘 ë‹€ 동등하게 장황하Ʞ 때묞에 읎 묞제와 직교한닀고 생각합니닀. (싀제 응용 프로귞랚에서는 사용하지 않고 였류와 였류가 발생한 윔드 쀄도 Ʞ록하는 닀륞 것을 사용합니닀.)

따띌서 였류 처늬가 였륞쪜에 있는 것을 정말 좋아하는 사람듀읎 있닀고 생각합니닀. Perl곌 Ruby륌 배겜윌로 핎서띌도 귞렇게 확신하지 못합니닀.

@lpar 혞출 슀택을 자동윌로 캡처하Ʞ 때묞에 errors.Wrap 합니닀. 읎러한 였류 메시지가 몚두 필요하지 않습니닀. 나는 귞것읎 발생한 장소와 아마도 ì–Žë–€ 읞수가 였류륌 생성한 핚수에 전달되었는지에 대핮 더 ꎀ심읎 있습니닀. 당신은 비슷한 음을 하고 있닀고 말하Ʞ도 합니닀. 였류 메시지에 대한 컚텍슀튞륌 제공하Ʞ 위핎 윔드 행을 Ʞ록합니닀. 였류에 더 많은 컚텍슀튞륌 제공하멎서 상용구륌 쀄읎는 방법을 생각할 수 있닀는 점을 감안할 때(여Ʞ서 거의 제안된 낎용입니닀).

였륞쪜에 있는 였류에 ꎀ핎서. 나에게 귞것은 닚순히 장소에 ꎀ한 것읎 아니띌 였류 처늬로 흩얎젞 있는 윔드륌 읜는 데 걞늬는 읞지 부하륌 쀄읎는 것입니닀. 나는 였류가 너묎 쀑요핎서 였류가 발생하는 만큌 많은 공간을 찚지하Ʞ륌 원한닀는 죌장을 믿지 않습니닀. 나는 귞듀읎 가능한 한 멀늬 떠나는 것을 싀제로 선혞합니닀. 귞듀은 죌요 읎알Ʞ가 아닙니닀.

@크레컀

읎것은 잘못된 사용자 입력윌로 읞핎 였류륌 생성하는 프로덕션 시슀템의 였류볎닀 사소한 개발자 였류륌 섀명할 가능성읎 더 큜니닀. 였류륌 확읞하는 데 필요한 몚든 것읎 쀄 번혞와 파음 겜로띌멎, 방ꞈ 윔드륌 작성했고 묎엇읎 잘못되었는지 읎믞 알고 있을 가능성읎 있습니닀.

@ 예왞와 유사하Ʞ 때묞입니닀. 대부분의 겜우 혞출 슀택곌 예왞 메시지는 였류가 발생한 위치와 원읞을 파악하Ʞ에 충분합니닀. 더 복잡한 겜우에는 적얎도 였류가 발생한 위치륌 알고 있습니닀. 예왞는 Ʞ볞적윌로 읎 읎점을 제공합니닀. Go륌 사용하멎 Ʞ볞적윌로 혞출 슀택을 에뮬레읎튞하는 였류륌 핚께 연결하거나 싀제 혞출 슀택을 포핚핎알 합니닀.

올바륎게 작성된 윔드에서는 대부분의 겜우 였류가 예상되Ʞ 때묞에 행 번혞와 파음 겜로에서 정확한 원읞을 알 수 있습니닀. 싀제로 발생할 수 있는 쀀비로 음부 윔드륌 작성했습니닀. 예상하지 못한 음읎 발생하멎 예, 혞출 슀택읎 원읞을 제공하지 않지만 검색 공간을 크게 쀄음 수 있습니닀.

@처럌

낮 겜험상 사용자 입력 였류는 거의 슉시 처늬됩니닀. 싀제 묞제가 되는 프로덕션 였류는 윔드 깊숙한 곳에서 발생하며(예: 서비슀가 닀욎되얎 닀륞 서비슀에서 였류가 발생핚) 적절한 슀택 추적을 얻는 데 맀우 유용합니닀. 귞만한 가치가 있Ʞ 때묞에 Java 슀택 추적은 메시지가 아니띌 프로덕션 묞제륌 디버깅할 때 맀우 유용합니닀.

@크레컀
였류는 값음 뿐읎며 핚수 입력 및 출력의 음부입니닀. 귞듀은 "예상치 못한" 수 없습니닀.
핚수에서 였류가 발생한 읎유륌 찟윌렀멎 테슀튞, 로깅 등을 사용하십시였.

@gladkikhartem 현싀 섞계에서는 귞렇게 간닚하지 않습니닀. 예, 핚수 서명읎 반환 값윌로 였류륌 포핚한닀는 점에서 였류륌 예상합니닀. 귞러나 ë‚Žê°€ 예상하여 얞꞉한 것은 묞제가 발생한 읎유와 원읞을 정확히 알고 있Ʞ 때묞에 싀제로 묞제륌 핎결하Ʞ 위핎 묎엇을 í•Žì•Œ 하는지 또는 전혀 핎결하지 ì•Šêž° 위핎 í•Žì•Œ 하는지 알 수 있닀는 것입니닀. 잘못된 사용자 입력은 음반적윌로 였류 메시지륌 볎는 것만윌로도 ê³ ì¹  수 있습니닀. 프로포윜 버퍌륌 사용하고 음부 필수 필드가 섀정되지 않은 겜우, 유선윌로 수신하는 몚든 항목을 적절하게 검슝하멎 읎는 예상되는 것읎며 수정하Ʞ가 정말 간닚합니닀.

읎 시점에서 나는 우늬가 묎엇에 대핮 녌쟁하는지 더 읎상 읎핎하지 못합니닀. 슀택 추적 또는 였류 메시지 첎읞은 올바륎게 구현되는 겜우 맀우 유사합니닀. 검색 공간을 쀄읎고 였류륌 재현하고 수정하는 데 유용한 컚텍슀튞륌 제공합니닀. 우늬에게 필요한 것은 충분한 컚텍슀튞륌 제공하멎서 였류 처늬륌 닚순화하는 방법에 대핮 생각하는 것입니닀. 나는 닚순핚읎 적절한 묞맥볎닀 더 쀑요하닀고 옹혞하는 것읎 아닙니닀.

읎것읎 Java 읞수입니닀. 몚든 였류 윔드륌 닀륞 곳윌로 읎동하여 볌 필요가 없도록 하십시였. 잘못된 것 같아요. 귞렇게 하는 Java의 메컀니슘읎 크게 싀팚했Ʞ 때묞읎 아니띌 ë‚Žê°€ 윔드륌 볌 때 였류가 있을 때 얎떻게 동작할지가 몚든 것읎 작동할 때 얎떻게 동작할지만큌읎나 쀑요하Ʞ 때묞입니닀.

아묎도 귞런 죌장을 하지 않습니닀. 몚든 였류 처늬가 한 곳에서 읎룚얎지는 예왞 처늬와 여Ʞ에서 녌의되는 낎용을 혌동하지 맙시닀. 귞것을 "대부분 싀팚"띌고 부륎는 것은 닚지 하나의 의견음 뿐읎지만, 나는 Go가 ì–Žë–€ 겜우에도 귞런 식윌로 돌아갈 것읎띌고 생각하지 않습니닀. Go 였류 처늬는 닚지 닀륎며 개선할 수 있습니닀.

@creker 나는 같은 점을 지적 하렀고 시도했고 의믞 있고 유용한 였류 메시지로 간죌되는 것읎 묎엇읞지 명확히 핎달띌고 요청했습니닀.

사싀, 나는 혞출 슀택곌 핚수 읞수에 대한 대가로 가변 품질 였류 메시지 텍슀튞(개발자가 ê·ž 순간에 ê·ž 지식을 가지고 작성하는 펞향읎 있음)륌 제공할 것입니닀. 였류 메시지 텍슀튞( fmt.Errorf 또는 errors.New )륌 사용하멎 혞출 슀택/백튞레읎슀륌 읜는 동안 소슀 윔드에서 텍슀튞륌 검색하게 됩니닀. 파음/띌읞 번혞( errors.Wrap 등)로 직접 조회하는 것에 핎당합니닀.

두 가지 닀륞 슀타음읎지만 목적은 동음합니닀. 슉, 핎당 조걎에서 런타임에 발생한 음을 뚞늿속윌로 재현하렀는 것입니닀.

읎 죌제에서 묞제 #19991은 의믞 있는 였류륌 정의하는 두 번짞 슀타음에 대한 ì ‘ê·Œ 방식에 대한 유횚한 요앜을 작성하고 있습니닀.

볌 필요가 없도록 몚든 였류 윔드륌 닀륞 곳윌로 읎동하십시였.

@lpar , 였류 처늬륌 였륞쪜윌로 읎동하는 것에 대한 낮 요점에 응답하는 겜우: 각죌/믞죌(자바)와 부죌(낮 제안) 간에는 큰 찚읎가 있습니닀. 사읎드 녾튾는 맥띜을 잃지 않고 앜간의 시선 읎동만 필요합니닀.

@gdm85

소슀 윔드에서 텍슀튞륌 검색하게 됩니닀.

슀택 추적곌 연결된 였류 메시지가 유사하닀는 것읎 정확히 의믞했습니닀. 둘 ë‹€ 였류가 발생한 겜로륌 Ʞ록합니닀. 메시지의 겜우에만 죌의 깊게 작성하지 않윌멎 프로귞랚의 얎느 곳에서나 있을 수 있는 완전히 쓞몚없는 메시지로 끝날 수 있습니닀. 연쇄 였류의 유음한 읎점은 변수 값을 Ʞ록하는 Ʞ능입니닀. 귞늬고 귞마저도 핚수 읞수 또는 음반적읞 변수의 겜우 자동화될 수 있윌며 적얎도 저에게는 였류에서 필요한 거의 몚든 것을 닀룰 것입니닀. 귞듀은 여전히 ​​값읎 될 것입니닀. 필요한 겜우 여전히 switch륌 입력할 수 있습니닀. 귞러나 얎느 시점에서 당신은 아마 귞것듀을 Ʞ록할 것읎고 슀택 추적을 볌 수 있는 것은 맀우 유용합니닀.

Go가 공황 상태에서 묎엇을 하는지 볎섞요. 몚든 고룚틎의 전첎 슀택 추적을 얻습니닀. 였류의 원읞을 파악하고 슉시 수정하는 데 몇 번읎나 도움읎 되었는지 Ʞ억나지 않습니닀. 귞것읎 얌마나 쉬욎지 나는 종종 놀랐닀. 디버거가 필요하지 않을 정도로 전첎 ì–žì–Žê°€ 맀우 예잡 가능하므로 완벜하게 흐늅니닀.

Java와 ꎀ렚된 몚든 것에 낙읞읎 있는 것 같윌며 사람듀은 종종 ì–Žë–€ 죌장도 하지 않습니닀. 닚지 때묞에 나쁘닀. 나는 Java의 팬은 아니지만 귞런 종류의 추론은 누구에게도 도움읎 되지 않습니닀.

닀시 말하지만, 였류는 개발자가 버귞륌 수정하는 것읎 아닙니닀. 읎것읎 였류 처늬의 읎점 쀑 하나입니닀. Java 방식은 개발자듀에게 읎것읎 였류 처늬띌는 것을 가륎쳀습니닀. 였류는 응용 프로귞랚 계잵곌 흐멄 계잵 너뚞에 있을 수 있습니닀. Go의 였류는 컎파음 시간읎 아니띌 런타임에 시슀템읎 췚하는 복구 전략을 제얎하는 ​​데 음상적윌로 사용됩니닀.

ì–žì–Žê°€ 슀택을 풀고 였류가 발생하Ʞ 전에 수행한 몚든 작업에 대한 메몚늬륌 잃음윌로썚 였류의 결곌로 흐멄 제얎륌 손상시킬 때 읎것은 읎핎하Ʞ 얎렀욞 수 있습니닀. 였류는 싀제로 Go에서 런타임에 유용합니닀. 왜 귞듀읎 쀄 번혞와 같은 것을 전달핎알 하는지 몚륎겠습니닀. 싀행 쀑읞 윔드는 귞것에 대핮 거의 신겜 쓰지 않습니닀.

@처럌

닀시 말하지만, 였류는 개발자가 버귞륌 수정하는 것읎 아닙니닀.

귞것은 완전히 귞늬고 완전히 잘못된 것입니닀. 였류는 바로 ê·ž 읎유 때묞입니닀. 귞것듀에 국한되지는 않지만 죌요 용도 쀑 하나입니닀. 였류는 시슀템에 묞제가 있음을 나타낎며 읎에 대핮 조치륌 ì·ší•Žì•Œ 합니닀. 예상되고 쉬욎 였류의 겜우 예륌 듀얎 TCP 시간 쎈곌와 같은 복구륌 시도할 수 있습니닀. 더 심각한 묞제의 겜우 로귞에 덀프하고 나쀑에 묞제륌 디버귞합니닀.

읎것읎 였류 처늬의 읎점 쀑 하나입니닀. Java 방식은 개발자듀에게 읎것읎 였류 처늬띌는 것을 가륎쳀습니닀.

Java가 당신에게 묎엇을 가륎쳀는지 몚륎지만 나는 같은 읎유로 예왞륌 사용합니닀 - 런타임에 복구 전략 시슀템읎 췚하는 것을 제얎하Ʞ 위핎서입니닀. Go는 였류 처늬 잡멎에서 특별한 것읎 없습니닀.

ì–žì–Žê°€ 슀택을 풀고 였류가 발생하Ʞ 전에 수행한 몚든 작업에 대한 메몚늬륌 잃음윌로썚 였류의 결곌로 흐멄 제얎륌 손상시킀는 겜우 읎는 읎핎하Ʞ 얎렀욞 수 있습니닀.

나륌 위한 것읎 아니띌 누군가륌 위한 것음 수도 있닀.

였류는 싀제로 Go에서 런타임에 유용합니닀. 왜 귞듀읎 쀄 번혞와 같은 것을 전달핎알 하는지 몚륎겠습니닀. 싀행 쀑읞 윔드는 귞것에 대핮 거의 신겜 쓰지 않습니닀.

윔드에서 버귞륌 수정하는 데 ꎀ심읎 있닀멎 쀄 번혞륌 사용하는 것읎 좋습니닀. 우늬에게 읎것에 대핮 가륎쳐 쀀 것은 Java가 아닙니닀. C는 바로 ê·ž 읎유 때묞에 __LINE__ 와 __FUNCTION__ 륌 가지고 있습니닀. 당신은 당신의 였류륌 Ʞ록하고 귞것읎 발생한 정확한 장소륌 Ʞ록하Ʞ륌 원합니닀. 귞늬고 묞제가 발생하멎 최소한 시작핎알 할 것읎 있습니닀. 복구할 수 없는 였류로 읞핎 발생한 임의의 였류 메시지가 아닙니닀. 귞런 종류의 정볎가 필요하지 않닀멎 묎시하십시였. 귞것은 당신을 닀치게하지 않습니닀. 귞러나 최소한 거Ʞ에 있고 필요할 때 사용할 수 있습니닀.

왜 여Ʞ 사람듀읎 대화륌 예왞 대 였류 값윌로 계속 옮Ʞ는지 읎핎가 되지 않습니닀. 아묎도 귞런 비교륌 하지 않았습니닀. 녌의된 것은 슀택 추적읎 맀우 유용하고 많은 컚텍슀튞 정볎륌 전달한닀는 것입니닀. 귞것읎 읎핎할 수 없닀멎 아마도 당신은 추적읎 졎재하지 않는 완전히 닀륞 섞계에 ì‚Žê³  있을 것입니닀.

귞것은 완전히 귞늬고 완전히 잘못된 것입니닀.

귞러나 ë‚Žê°€ 얞꞉하는 프로덕션 시슀템은 여전히 ​​싀행 쀑읎며 흐멄 제얎륌 위핎 였류륌 사용하고 Go로 작성되었윌며 였류 전파륌 위핎 슀택 추적을 사용하는 얞얎의 느며 구현을 대첎했습니닀.

귞것읎 읎핎할 수 없닀멎 아마도 당신은 추적읎 졎재하지 않는 완전히 닀륞 섞계에 ì‚Žê³  있을 것입니닀.

였류 유형을 반환하는 몚든 핚수에 대한 혞출 슀택 정볎륌 연결하렀멎 재량에 따띌 수행하십시였. 슀택 추적은 더 느늬고 볎안상의 읎유로 장난감 프로젝튞 왞부에서 사용하Ʞ에 적합하지 않습니닀. 묎분별한 였류 전파 전략을 돕Ʞ 위핎 귞듀을 Go의 음등 시믌윌로 만드는 것은 Ʞ술적읞 파욞입니닀.

귞런 종류의 정볎가 필요하지 않닀멎 묎시하십시였. 귞것은 당신을 닀치게하지 않습니닀.

소프튞웚얎 팜찜은 서버가 Go에서 닀시 작성되는 읎유입니닀. 볎읎지 않는 것은 여전히 ​​파읎프띌읞의 처늬량을 저하시킬 수 있습니닀.

TCP 시간 쎈곌 및 로귞 덀핑 처늬에 대한 앜간 ꎀ렚 없는 강의 대신 읎 Ʞ능을 사용하여 읎점을 얻을 수 있는 싀제 소프튞웚얎의 예륌 선혞합니닀.

슀택 추적읎 더 느늌

슀택 추적읎 였류 겜로에서 생성된닀는 점을 감안할 때 속도가 얌마나 느늰지는 아묎도 신겜 쓰지 않습니닀. 소프튞웚얎의 정상적읞 작동읎 읎믞 쀑닚되었습니닀.

볎안상의 읎유로 장난감 프로젝튞 왞부에서 사용하Ʞ에 부적합

지ꞈ까지 닚음 프로덕션 시슀템읎 "볎안상의 읎유" 또는 ê·ž 묞제로 읞핎 슀택 추적을 끄는 것을 아직 볎지 못했습니닀. 반멎에 윔드가 였류륌 생성하는 데 걞늰 겜로륌 빠륎게 식별할 수 있닀는 것은 맀우 유용했습니닀. 귞늬고 읎것은 윔드 Ʞ반에서 작업하는 여러 팀곌 전첎 시슀템에 대한 완전한 지식읎 없는 대규몚 프로젝튞륌 위한 것입니닀.

볎읎지 않는 것은 여전히 ​​파읎프띌읞의 처늬량을 저하시킬 수 있습니닀.

아니, 정말 귞렇지 않습니닀. 앞서 말했듯읎 슀택 추적은 였류에 대핮 생성됩니닀. 소프튞웚얎에서 지속적윌로 읎러한 묞제가 발생하지 않는 한 처늬량은 조ꞈ도 영향을 받지 않습니닀.

슀택 추적읎 였류 겜로에서 생성된닀는 점을 감안할 때 속도가 얌마나 느늰지는 아묎도 신겜 쓰지 않습니닀. 소프튞웚얎의 정상적읞 작동읎 읎믞 쀑닚되었습니닀.

올바륎지 않은.

  • 정상 작동의 음부로 였류가 발생할 수 있습니닀.
  • 였류륌 복구할 수 있고 프로귞랚을 계속할 수 있윌므로 성능읎 여전히 묞제입니닀.
  • 하나의 룚틎을 느늬게 하멎 행복한 겜로에서 작동하는 _are_ 닀륞 룚틎의 늬소슀가 쀄얎듭니닀.

@object88 싀제 프로덕션 윔드륌 상상핎볎섞요. 얌마나 많은 였류가 생성될 것윌로 예상합니까? 나는 별로 생각하지 않을 것읎닀. 적얎도 제대로 작성된 신청서에서는. 고룚틎읎 사용 쀑읞 룚프에 있고 반복할 때마닀 였류가 계속 발생한닀멎 윔드에 묞제가 있는 것입니닀. 하지만 귞렇닀고 핮도 대부분의 Go 응용 프로귞랚읎 IO 바읞딩되얎 있닀는 점을 감안할 때 심각한 묞제는 아닐 것입니닀.

@처럌

귞러나 ë‚Žê°€ 얞꞉하는 프로덕션 시슀템은 여전히 ​​싀행 쀑읎며 흐멄 제얎륌 위핎 였류륌 사용하고 Go로 작성되었윌며 였류 전파륌 위핎 슀택 추적을 사용하는 얞얎의 느며 구현을 대첎했습니닀.

죄송하지만 제 말곌 전혀 상ꎀ없는 말도 안되는 묞장입니닀. 대답하지 않을 것입니닀.

슀택 추적읎 더 느늌

더 느늬지만 얌마나? 상ꎀ읎 있나? 나는 귞렇게 생각하지 않는닀. Go 애플늬쌀읎션은 음반적윌로 IO 바읞딩됩니닀. 읎 겜우 CPU 죌Ʞ륌 추적하는 것은 얎늬석은 음입니닀. CPU륌 잡아뚹는 Go 런타임에는 훚씬 더 큰 묞제가 있습니닀. 버귞 수정에 도움읎 되는 유용한 Ʞ능을 버늬띌는 죌장읎 아닙니닀.

볎안상의 읎유로 장난감 프로젝튞 왞부에서 사용하Ʞ에 부적합합니닀.

졎재하지 않는 "볎안상의 읎유"는 닀룚지 않겠습니닀. 귞러나 음반적윌로 낎부에 저장되는 애플늬쌀읎션 추적 및 개발자만 액섞슀할 수 있음을 상Ʞ시쌜 드늬고 싶습니닀. 귞늬고 핚수 읎늄을 숚Ʞ는 것은 얎욌든 시간 낭비입니닀. 볎안읎 아닙니닀. 귞것에 대핮 자섞히 섀명할 필요가 없Ʞ륌 바랍니닀.

볎안상의 읎유륌 고집한닀멎 예륌 듀얎 macOS/iOS륌 생각핎 죌셚윌멎 합니닀. 몚든 슀레드의 슀택곌 몚든 CPU 레지슀터의 값을 포핚하는 팹닉 및 크래시 덀프륌 발생시킀는 데 묞제가 없습니닀. 읎러한 "볎안상의 읎유"에 의핎 영향을 받는 것을 볎지 마십시였.

묎분별한 였류 전파 전략을 돕Ʞ 위핎 귞듀을 Go의 음등 시믌윌로 만드는 것은 Ʞ술적읞 파욞입니닀.

더 죌ꎀ적음 수 있습니까? "생각 없는 였류 전파 전략" 얎디서 뎀얎?

소프튞웚얎 팜찜은 서버가 Go에서 닀시 작성되는 읎유입니닀. 볎읎지 않는 것은 여전히 ​​파읎프띌읞의 처늬량을 저하시킬 수 있습니닀.

또 얌마나?

TCP 시간 쎈곌 및 로귞 덀핑 처늬에 대한 앜간 ꎀ렚 없는 강의 대신 읎 Ʞ능을 사용하여 읎점을 얻을 수 있는 싀제 소프튞웚얎의 예륌 선혞합니닀.

읎 시점에서 나는 프로귞래뚞가 아닌 누구와도 읎알Ʞ하고 있는 것 같습니닀. 추적은 몚든 소프튞웚얎에 읎점읎 있습니닀. 버귞륌 수정하는 데 도움읎 되는 몚든 얞얎와 몚든 유형의 소프튞웚얎에서 공통적읞 Ʞ술입니닀. 더 자섞한 정볎륌 원하시멎 위킀플디아륌 읜얎볎섞요.

합의 없읎 너묎 많은 비생산적읞 토론을 한닀는 것은 읎 묞제륌 í•Žê²°í•  우아한 방법읎 없닀는 것을 의믞합니닀.

@object88
Go는 닀륞 고룚틎읎 ì°šë‹š 핎제될 때까지 Ʞ닀렀알 하Ʞ 때묞에 몚든 고룚틎을 추적하렀는 겜우 슀택 추적읎 느멮 수 있습니닀.
현재 싀행 쀑읞 고룚틎을 추적하멎 귞렇게 느늬지 않습니닀.

@크레컀
혜택 몚든 소프튞웚얎륌 추적, 귞러나 당신읎 추적하고있는 묎슚에 따띌 달띌집니닀. 대부분의 Go 프로젝튞에서 슀택 추적은 동시성읎 ꎀ렚되얎 있Ʞ 때묞에 좋은 아읎디얎가 아니었습니닀. 데읎터는 앞윌로 읎동하고 많은 것듀읎 서로 통신하며 음부 고룚틎은 몇 쀄의 윔드에 불곌합니닀. 읎러한 겜우 슀택 추적을 갖는 것은 도움읎 되지 않습니닀.
귞렇Ʞ 때묞에 동음한 슀택 추적을 재생성하Ʞ 위핎 로귞에 Ʞ록된 컚텍슀튞 정볎로 래핑된 였류륌 사용하지만 읎는 싀제 고룚틎 슀택읎 아니띌 애플늬쌀읎션 로직 자첎에 바읞딩됩니닀.
ë‚Žê°€ 할 수 있도록 cat *.log | grep "orderID=xxx"륌 입력하고 였류륌 음윌킚 싀제 작업 시퀀슀의 슀택 추적을 가젞옵니닀.
Go 컚텍슀튞가 풍부한 였류의 동시성윌로 읞핎 슀택 추적볎닀 더 가치가 있습니닀.

@gladkikhartem 시간을 ë‚Žì–Ž 적절한 녌거륌 작성

나는 당신의 죌장을 읎핎하고 부분적윌로 동의합니닀. 귞럌에도 불구하고 적얎도 5개 읎상의 핚수 슀택을 처늬핎알 한닀는 사싀을 알게 되었습니닀. 읎것은 묎슚 음읎 음얎나고 있고 얎디서부터 삎펎뎐알 하는지 읎핎할 수 있을 만큌 읎믞 충분히 큜니닀. 귞러나 맀우 작은 고룚틎 슀택 추적읎 많읎 포핚된 고도로 동시 싀행되는 응용 프로귞랚에서는 읎점읎 손싀됩니닀. 동의합니닀.

@크레컀

싀제 프로덕션 윔드륌 상상핎볎섞요. 얌마나 많은 였류가 생성될 것윌로 예상합니까? [...], Go 애플늬쌀읎션의 대부분읎 IO 바읞딩되얎 있닀는 점을 감안할 때 심각한 묞제는 아닐 것입니닀.

IO 바읞딩 작업을 얞꞉하는 것읎 좋습니닀. io.Reader Read 메서드는 EOF에서 정상적읞 였류륌 반환합니닀. 귞래서 행복한 Ꞟ에서 많은 음읎 음얎날 것입니닀.

@urandom

슀택 추적은 시슀템 프로파음링에 쀑요한 정볎륌 묎의식적윌로 녞출합니닀.

  • 사용자 읎늄
  • 파음 시슀템 겜로
  • 백엔드 데읎터베읎슀 유형/버전
  • 거래 흐멄
  • 객첎 구조
  • 암혞화 알고늬슘

평균적읞 애플늬쌀읎션읎 였류 유형에서 슀택 프레임을 수집하는 였버헀드륌 알아찚늎지는 몚륎겠지만, 성능읎 쀑요한 애플늬쌀읎션의 겜우 현재 핚수 혞출 였버헀드로 읞핎 많은 작은 Go 핚수가 수동윌로 읞띌읞된닀는 것을 말할 수 있습니닀. 추적하멎 악화됩니닀.

Go의 목표는 간닚하고 빠륞 소프튞웚얎륌 만드는 것읎며 추적은 뒀로 묌러날 것입니닀. 우늬는 비 전통적읞 였류 유형곌 수동 읞띌읞을 조장하는 성능 저하 없읎 작은 핚수륌 작성하고 핎당 핚수에서 였류륌 반환할 수 있얎알 합니닀.

@크레컀

더 읎상의 불협화음을 알Ʞ하는 예륌 제시하지 않겠습니닀. 싀망을 드렀 죄송합니닀.

나는 ê·ž 읎늄읎 ê·ž Ʞ능을 슉시 드러낎는 새로욎 킀워드 "returnif"륌 사용하는 것을 제안할 것입니닀. 또한 였류 처늬볎닀 더 많은 사용 사례에서 사용할 수 있을 만큌 충분히 유연합니닀.

예 1(명명된 반환 사용):

a, err = 묎얞가(b)
였류 != nil {
반품
}

닀음읎 될 것입니닀:

a, err = 묎얞가(b)
returnif 였류 != nil

예 2(명명된 반환을 사용하지 않음):

a, err := 뭔가(b)
였류 != nil {
반환, 였류
}

닀음읎 될 것입니닀:

a, err := 뭔가(b)
returnif err != nil { a, err }

명명 된 반환 예제와 ꎀ렚하여 의믞하는 것은 ...

a, err = something(b)
returnif err != nil

@ambernardino
대신 fmt 도구륌 업데읎튞하고 ì–žì–Ž 구묞을 업데읎튞하고 쓞몚없는 새 킀워드륌 추가할 필요가 없습니닀.

a, err := something(b)
if err != nil { return a, err }

또는

a, err := something(b)
    if err != nil { return a, err }

@gladkikhartem 아읎디얎는 였류륌 전파할 때마닀 입력하지 않는 것입니닀.

a, err? := something(b)

@mrkaspa
아읎디얎는 윔드륌 더 읜Ʞ 쉜게 만드는 것입니닀. 윔드륌 입력하는 것읎 묞제가 아니띌 읜는 것읎 묞제입니닀.

@gladkikhartem 녹은 ê·ž ì ‘ê·Œ 방식을 사용하며

@gladkikhartem ? 가 가독성을 떚얎뜚늬지 않는닀고 생각합니닀. 녞읎슈륌 완전히 제거한닀고 합니닀. 나에게 묞제는 소음윌로 읞핎 유용한 컚텍슀튞륌 제공할 가능성도 제거된닀는 것입니닀. 음반적읞 였류 메시지륌 삜입하거나 였류륌 래핑할 수 있는 위치가 표시되지 않습니닀. 혞출 슀택은 명백한 솔룚션읎지만 읎믞 얞꞉했듯읎 몚든 사람에게 작동하지는 않습니닀.

@mrkaspa
가독성읎 떚얎진닀고 생각합니닀. 닀음은 묎엇읞가요? 우늬는 최선의 핎결책을 ì°Ÿê³  있습니까, 아니멎 의견을 공유하고 있습니까?

@크레컀
'?' 묞자는 묎엇을 반환할지 명확하지 않고 묌론 사람읎 읎 작업읎 묎엇을 하는지 알아알 하Ʞ 때묞에 독자에게 읞지 부하륌 추가합니닀. 귞늬고 묌론? Ʞ혞는 독자의 마음에 질묞을 제Ʞ합니닀.

읎전에 말했듯읎 err != nil을 제거하렀멎 컎파음러가 사용하지 않는 였류 맀개변수륌 감지하여 직접 전달할 수 있습니닀.
귞늬고

a, err? := doStuff(a,b)
err? := doAnotherStuff(b,z,d,g)
a, b, err? := doVeryComplexStuff(b)

더 읜Ʞ 쉬워질 것입니닀

a := doStuff(a,b)
doAnotherStuff(b,z,d,g)
a, b := doVeryComplexStuff(b)

같은 마법, 입력할 항목곌 생각할 항목읎 쀄얎듭니닀.

@gladkikhartem Ꞁ쎄요, 독자듀읎 새로욎 것을 ë°°ìšž 필요가 없는 솔룚션은 없닀고 생각합니닀. 얞얎륌 바Ꟍ 결곌입니닀. 우늬는 절충안을 만듀얎알 합니닀. 원시 ìš©ì–Žë¡œ 수행되는 작업을 정확히 볎여죌는 얌굎 구묞에 장황하게 입력하거나 장황핚을 숚Ʞ거나 구묞 섀탕 등을 추가할 수 있는 새로욎 구묞을 도입하거나 닀륞 방법읎 없습니닀. 독자가 ë°°ìšž 낎용을 추가하는 것을 거부하는 것은 역횚곌입니닀. 몚든 Go2 묞제륌 닫고 하룚띌고 부륌 수도 있습니닀.

귀하의 예에서는 더 많은 마법을 도입하고 개발자가 였류에 대한 컚텍슀튞륌 제공할 수 있도록 하는 구묞을 도입하Ʞ 위핎 몚든 죌입 지점을 숚깁니닀. 귞늬고 가장 쀑요한 것은 ì–Žë–€ 핚수 혞출읎 였류륌 발생시킬 수 있는지에 대한 정볎륌 완전히 숚깁니닀. 귞것은 점점 예왞의 냄새가 납니닀. 귞늬고 만앜 우늬가 였류륌 닀시 던지는 것에 대핮 진지하닀멎 슀택 추적은 ê·ž 겜우에 컚텍슀튞륌 유지할 수 있는 유음한 방법읎Ʞ 때묞에 필수가 됩니닀.

원래 제안은 싀제로 읎믞 몚든 것을 ꜀ 잘 닀룚고 있습니닀. 충분히 장황하고 였류륌 래핑하고 유용한 컚텍슀튞륌 제공하Ʞ에 좋은 위치륌 제공합니닀. 귞러나 죌요 묞제 쀑 하나는 읎 마법의 '였류'입니닀. 나는 귞것읎 충분히 마술적읎지 않고 충분히 장황하지 ì•Šêž° 때묞에 추하닀고 생각합니닀. 귞것은 음종의 쀑간입니닀. 더 나은 것은 더 많은 마법을 도입하는 것입니닀.

|| 가 원래 였류륌 자동윌로 래핑하는 새 였류륌 생성하멎 얎떻게 될까요? 귞래서 예제는 닀음곌 같읎 됩니닀

func Chdir(dir string) error {
    syscall.Chdir(dir) || &PathError{"chdir", dir}
    return nil
}

err 가 사띌지고 몚든 래핑읎 암시적윌로 처늬됩니닀. 읎제 읎러한 낎부 였류에 액섞슀할 수 있는 방법읎 필요합니닀. Inner() error 와 같은 닀륞 메소드륌 error 읞터페읎슀에 추가하멎 작동하지 않을 것 같습니닀. 한 가지 방법은 unwrap(error) []error 와 같은 낎장 핚수륌 도입하는 것입니닀. 귞것읎 하는 음은 몚든 낎부 였류의 조각을 포장된 순서대로 반환하는 것입니닀. 귞런 식윌로 낎부 였류 또는 범위에 액섞슀할 수 있습니닀.

error 가 읞터페읎슀음 뿐읎고 사용자 정의 error 유형에 대핮 래핑된 였류륌 둘 위치가 필요하닀는 점을 감안할 때 읎것의 구현은 의심슀럜습니닀.

나륌 위핎 읎것은 몚든 상자륌 첎크하지만 닀소 너묎 마술적음 수 있습니닀. 귞러나 였류 읞터페읎슀가 정의상 맀우 특별하닀는 점을 감안할 때 읎륌 1꞉ 시믌에 더 가깝게 가젞였는 것은 나쁜 생각읎 아닐 수 있습니닀. 였류 처늬는 음반 Go 윔드읎Ʞ 때묞에 장황합니닀. 특별한 것은 없습니닀. 귞것은 서류상윌로나 화렀한 헀드띌읞을 만듀Ʞ에 좋을지 몚륎지만 였류는 너묎 특별핎서 귞러한 췚꞉을 정당화할 수 없습니닀. 귞듀은 특별한 쌀읎슀가 필요합니닀.

원래 제안은 였류 검사의 수륌 쀄읎는 것입니까 아니멎 각 개별 검사의 Ꞟ읎륌 쀄읎는 것입니까?

후자띌멎 조걎묞곌 반복묞읎 하나만 있닀는 읎유로 제안의 필요성을 녌박하는 것읎 간닚합니닀. ì–Žë–€ 사람듀은 for 룚프륌 싫얎합니닀. 암시적 룚프 구성도 제공핎알 하나요?

지ꞈ까지 제안된 구묞 변겜은 흥믞로욎 사고 싀험윌로 작용했지만 ê·ž 쀑 얎느 것도 원볞만큌 명확하고 발음하Ʞ 쉜고 간닚하지 않습니닀. Go는 bash가 아니며 였류에 대핮 "마술"읎 되얎서는 안 됩니닀.

점점 더 많은 사람듀읎 읎러한 제안을 읜고 "새로욎 것을 추가하므로 나쁘고 읜을 수 없윌며 몚든 것을 귞대로 둡니닀"띌고 죌장하는 사람듀을 점점 더 많읎 뎅니닀.

@as 제안은 달성하렀는 것에 대한 요앜을 제공합니닀. 수행되는 작업은 맀우 잘 정의되얎 있습니닀.

원볞처럌 명확하고 발음하Ʞ 쉬우며 닚순합니닀.

몚든 제안은 새로욎 구묞을 도입하고 음부 사람듀에게 새로욎 것은 "읜을 수 없거나 복잡한 등"윌로 듀늜니닀. 새롭닀고 í•Žì„œ 명확하지 않고 발음하Ʞ 쉬우며 닚순하지 않습니닀. "||" 귞늬고 "?" 예제는 Ʞ능을 알고 나멎 êž°ì¡Ž 구묞만큌 명확하고 간닚합니닀. 아니멎 "->"와 "<-"가 너묎 마술적읎얎서 독자가 ê·ž 의믞륌 알아알 한닀고 불평하Ʞ 시작핎알 합니까? 메서드 혞출로 교첎핎 볎겠습니닀.

Go는 bash가 아니며 였류에 대핮 "마술"읎 되얎서는 안 됩니닀.

귞것은 완전히 귌거가 없윌며 ì–Žë–€ 것에 대한 죌장윌로 간죌되지 않습니닀. Bash와 묎슚 상ꎀ읎 있는지는 알 수 없습니닀.

@크레컀
예, 읎벀튞에 더 많은 마법을 도입했닀는 귀하의 의견에 전적윌로 동의합니닀. 낮 예는 ? 더 적은 항목을 입력하는 욎영자의 아읎디얎.

나는 우늬가 묎얞가륌 희생하고 앜간의 변화와 마법을 도입핎알 한닀는 데 동의합니닀. 귞것은 유용성의 장점곌 귞러한 마법의 닚점의 균형음 뿐입니닀.

원볞 || 제안은 ꜀ 훌륭하고 싀제로 테슀튞되었지만 낮 생각에는 형식읎 추악합니닀. 형식을 닀음윌로 변겜하는 것읎 좋습니닀.

syscal.Chdir(dir)
    || return &PathError{"chdir", dir}

추신 마술 구묞의 귞러한 변형에 대핮 얎떻게 생각하십니까?

syscal.Chdir(dir) {
    return &PathError{"chdir", dir}
}

@gladkikhartem 둘 ë‹€ 가독성 잡멎에서 ꜀ 좋아 볎읎지만 후자에서 나쁜 느낌을 받습니닀. 귞것은 ë‚Žê°€ 확신하지 못하는 읎 읎상한 랔록 범위륌 소개합니닀.

구묞을 따로따로 볎지 말고 핚수의 맥띜에서 볎는 것읎 좋습니닀. 읎 메서드에는 몇 가지 닀륞 였류 처늬 랔록읎 있습니닀.

func (l *Loader) processDirectory(p *Package) (*build.Package, error) {
        absPath, err := p.preparePath()
        if err != nil {
                return nil, err
        }
    fis, err := l.context.ReadDir(absPath)
    if err != nil {
        return nil, err
    } else if len(fis) == 0 {
        return nil, nil
    }

    buildPkg, err := l.context.Import(".", absPath, 0)
    if err != nil {
        if _, ok := err.(*build.NoGoError); ok {
            // There isn't any Go code here.
            return nil, nil
        }
        return nil, err
    }

    return buildPkg, nil
}

제안된 변겜 사항은 읎 Ʞ능을 얎떻게 정늬합니까?

func (l *Loader) processDirectory(p *Package) (*build.Package, error) {
    absPath, err? := p.preparePath()
    fis, err? := l.context.ReadDir(absPath)
    if len(fis) == 0 {
        return nil, nil
    }

    buildPkg, err := l.context.Import(".", absPath, 0)
    if err != nil {
         if _, ok := err.(*build.NoGoError); ok {
             // There isn't any Go code here.
             return nil, nil
         }
         return nil, err
    }

    return buildPkg, nil
}

@bcmills 제안읎 더 적합합니닀.

func (l *Loader) processDirectory(p *Package) (*build.Package, error) {
    absPath := p.preparePath()        =? err { return nil, err }
    fis := l.context.ReadDir(absPath) =? err { return nil, err }
    if len(fis) == 0 {
        return nil, nil
    }
    buildPkg := l.context.Import(".", absPath, 0) =? err {
        if _, ok := err.(*build.NoGoError); ok {
            // There isn't any Go code here.
            return nil, nil
        }
        return nil, err
    }
    return buildPkg, nil
}

@object88

func (l *Loader) processDirectory(p *Package) (p *build.Package, err error) {
        absPath, err := p.preparePath() {
        return nil, fmt.Errorf("prepare path: %v", err)
    }
    fis, err := l.context.ReadDir(absPath) {
        return nil, fmt.Errorf("read dir: %v", err)
    }
    if len(fis) == 0 {
        return nil, nil
    }

    buildPkg, err := l.context.Import(".", absPath, 0) {
        err, ok := err.(*build.NoGoError)
                if !ok {
            return nil, fmt.Errorf("buildpkg: %v",err)
        }
        return nil, nil
    }
    return buildPkg, nil
}

계속 읎것저것 찔러뎅니닀. 얎쩌멎 우늬는 더 완전한 사용 예륌 생각핎 ë‚Œ 수 있습니닀.

@erwbgy , 나에게 읎것읎 가장 좋아 볎읎지만 지불ꞈ읎 귞렇게 좋은지 확신하지 못합니닀.

  • 였류가 아닌 반환 값은 묎엇입니까? 귞듀은 항상 0 값입니까? 명명된 반환에 대핮 읎전에 할당된 값읎 _was_ 있는 겜우 핎당 값읎 재정의됩니까? 명명된 값읎 였류 핚수의 결곌륌 저장하는 데 사용되멎 반환됩니까?
  • ? 연산자륌 였류가 아닌 값에 적용할 수 있습니까? (!ok)? 또는 ok!? 와 같은 작업을 수행할 수 있습니까? 아니멎 읎 구묞은 error 에만 유용합니까?

@rodcorsi , 핚수가 ReadDir 아니띌 ReadBuildTargetDirectoryForFileInfo 읎거나 얎늬석은 Ꞟ읎멎 얎떻게 될까요 ? 또는 많은 수의 읞수가 있을 수 있습니닀. preparePath 대한 였류 처늬도 화멎 밖윌로 밀렀납니닀. 가로 화멎 크Ʞ가 제한된 장치(또는 Github와 같읎 귞렇게 넓지 않은 뷰포튞)에서는 =? 부분을 ​​잃을 가능성읎 높습니닀. 우늬는 수직 슀크례에 맀우 능숙합니닀. 수평에서는 귞닀지.

@gladkikhartem , error 읞터페읎슀륌 구현하는 음부(마지막?) 읞수에 연결된 것 같습니닀. 귞것은 핚수 선얞곌 맀우 흡사하고, 귞것은 닚지... _느낌_ 읎상합니닀. ok 슀타음 반환 값에 묶음 수 있는 방법읎 있습니까? 전첎적윌로 1쀄만 구맀합니닀.

@object88
쀄 바꿈은 정말 ꎑ범위한 윔드 묞제륌 핎결합니닀. 널늬 사용되지 않습니까?

맀우 ꞎ 핚수 혞출곌 ꎀ렚하여 @object88 . 여Ʞ서 죌요 묞제륌 처늬핎 볎겠습니닀. 묞제는 화멎 밖윌로 밀렀난 였류 처늬가 아닙니닀. 묞제는 ꞎ 핚수 읎늄 및/또는 많은 읞수 목록입니닀. 화멎을 벗얎나는 였류 처늬에 대핮 녌쟁을 벌읎Ʞ 전에 수정핎알 합니닀.

Ʞ볞적윌로 쀄 바꿈윌로 섀정된 IDE 또는 윔드 친화적읞 텍슀튞 펞집Ʞ륌 아직 볎지 못했습니닀. 귞늬고 페읎지가 로드된 후 CSS륌 수동윌로 핎킹하는 것 왞에는 Github을 사용하여 전혀 수행할 수 있는 방법을 찟지 못했습니닀.

귞늬고 저는 윔드 너비가 쀑요한 요소띌고 생각합니닀. 읎것은 읎 제안의 추진력읞 _가독성_에 대핮 말합니닀. 죌장은 였류 죌변에 "너묎 많은 윔드"가 있닀는 것입니닀. Ʞ능읎 없거나 였류륌 닀륞 방식윌로 구현핎알 하는 것읎 아니띌 윔드가 잘 읜히지 않는닀는 것입니닀.

@object88
예, 읎 윔드는 였류 읞터페읎슀륌 마지막 맀개변수로 반환하는 몚든 핚수에서 작동합니닀.

쀄 저장곌 ꎀ렚하여 더 적은 수의 쀄에 더 많은 정볎륌 넣을 수는 없습니닀. 윔드는 너묎 조밀하지 않고 몚든 묞장 뒀에 공백읎 없얎알 하며 고륎게 분포되얎알 합니닀.
나는 귞것읎 핚수 선얞처럌 볎읞닀는 것에 동의하지만 동시에 졎재하는 if ...; err != nil { 묞, 귞래서 사람듀은 너묎 혌란슀러워하지 않을 것입니닀.

윔드 너비는 쀑요한 요소입니닀. 80쀄의 펞집Ʞ와 80쀄의 윔드가 핚수 혞출읎고 ê·ž 후에 || 반환 ? 나는 ê·ž 핚수가 묎얞가륌 반환한닀는 것을 식별할 수 없을 것입니닀. 왜냐하멎 ë‚Žê°€ 읜을 것은 반환읎 없는 유횚한 go 윔드가 될 것읎Ʞ 때묞입니닀.

완전성을 위핎 || 구묞, 자동 였류 래핑 및 였류가 아닌 반환 값의 자동 제로화륌 사용하여 예제륌 던질 것입니닀.

func (l *Loader) processDirectory(p *Package) (*build.Package, error) {
        absPath := p.preparePath() || errors.New("prepare path")
    fis := l.context.ReadDir(absPath) || errors.New("ReadDir")
    if len(fis) == 0 {
        return nil, nil
    }

    buildPkg, err := l.context.Import(".", absPath, 0)
    if err != nil {
        if _, ok := err.(*build.NoGoError); ok {
            // There isn't any Go code here.
            return nil, nil
        }
        return nil, err
    }

    return buildPkg, nil
}

닀륞 반환 값에 대한 질묞에 대핮. 였류의 겜우 몚든 겜우에 값읎 0입니닀. 나는 귞것읎 왜 쀑요하닀고 믿는지 읎믞 닀뀘습니닀.

묞제는 당신의 예가 처음부터 ꎀ렚읎 없닀는 것입니닀. 귞러나 적얎도 나에게는 읎 제안읎 의믞하는 바륌 여전히 볎여쀍니닀. ë‚Žê°€ 핎결하고 싶은 것은 가장 음반적읎고 많읎 사용되는 ꎀ용구입니닀.

err := func()
if err != nil {
    return err
}

우늬는 읎러한 종류의 윔드가 음반적윌로 였류 처늬의 큰 부분(가장 큰 부분은 아니지만)읎띌는 데 동의할 수 있습니닀. 따띌서 ê·ž 겜우륌 핎결하는 것읎 녌늬적음 뿐입니닀. 귞늬고 였류와 ꎀ렚된 더 많은 작업을 수행하렀멎 몇 가지 녌늬륌 적용하십시였. 프로귞래뚞가 읜고 읎핎할 수 있는 싀제 녌늬가 있는 곳에서 자섞한 정볎가 있얎알 합니닀. 우늬에게 필요하지 않은 것은 생각 없는 상용구륌 읜는 데 공간곌 시간을 낭비하는 것입니닀. 묎의믞하지만 여전히 Go 윔드의 필수적읞 부분입니닀.

암시적윌로 0 값을 반환하는 것에 대한 읎전 읎알Ʞ와 ꎀ렚하여. 였류가 발생했을 때 의믞 있는 값을 반환핎알 하는 겜우 싀행하십시였. 여Ʞ서도 장황핚읎 좋고 윔드륌 읎핎하는 데 도움읎 됩니닀. 더 복잡한 작업을 수행핎알 하는 겜우 구묞 섀탕을 버늬는 것은 아묎런 묞제가 없습니닀. 귞늬고 || 는 두 가지 겜우륌 몚두 í•Žê²°í•  수 있을 만큌 충분히 유연합니닀. 였류가 아닌 값을 생략할 수 있윌며 암시적윌로 0읎 됩니닀. 또는 필요한 겜우 명시적윌로 지정할 수 있습니닀. 나는 였류륌 반환하고 닀륞 몚든 것을 0윌로 만듀고 싶은 겜우륌 포핚하는 별도의 제안도 있닀는 것을 Ʞ억합니닀.

@object88

죌장은 였류 죌변에 "너묎 많은 윔드"가 있닀는 것입니닀.

닚순한 윔드가 아닙니닀. 죌요 묞제는 였류와 맀우 음반적읞 였류 처늬 사례에 대한 의믞 없는 상용구가 너묎 많닀는 것입니닀. 읜을 가치가 있는 것읎 있을 때 장황핚읎 쀑요합니닀. if err == nil then return err 에는 였류륌 닀시 발생시킀렀는 것 왞에는 가치가 없습니닀. 읎러한 원시적 녌늬에는 많은 공간읎 필요합니닀. 귞늬고 로직, 띌읎람러늬 혞출, 래퍌 등읎 몚두 였류륌 반환할 수 있는 겜우가 많을수록 읎 상용구는 윔드의 싀제 로직읞 쀑요한 항목을 더 많읎 지배하Ʞ 시작합니닀. 귞늬고 ê·ž 녌늬에는 싀제로 몇 가지 쀑요한 였류 처늬 녌늬가 포핚될 수 있습니닀. 귞러나 죌변의 대부분의 상용구의 읎러한 반복적읞 특성에서 Ꞟ을 잃습니닀. 귞늬고 귞것은 핎결될 수 있고 Go가 겜쟁하는 닀륞 현대 얞얎듀은 귞것을 핎결하렀고 녞력합니닀. 였류 처늬는 맀우 쀑요하Ʞ 때묞에 음반적읞 윔드가 아닙니닀.

@크레컀
err != nil return err 가 너묎 많은 상용구띌멎 우늬가 두렀욎 것은 슀택 위로 였류륌 전달하는 쉬욎 방법을 만듀멎 통계적윌로 프로귞래뚞, 특히 죌니얎가 특정 상황에서 적절한 것.
Go의 였류 처늬와 동음한 아읎디얎입니닀. 적절한 작업을 수행하도록 강제합니닀.
따띌서 읎 제안에서 우늬는 닀륞 사람듀읎 였류륌 신쀑하게 처늬하고 감싞도록 권장하고자 합니닀.

ê°„ë‹ší•œ 였류 처늬륌 구현하Ʞ에는 볎Ʞ 흉하고 Ꞟ게 만듀얎알 하지만, 래핑 또는 슀택 추적을 사용한 우아한 였류 처늬는 멋지고 쉜게 수행할 수 있도록 í•Žì•Œ 한닀고 말하고 싶습니닀.

@gladkikhartem 나는 항상 고대 펞집자듀에 대한 읎 죌장읎 얎늬석은

@gladkikhartem Go는 읎믞 ê·ž 묞제륌 가지고 있윌며 우늬가 귞것에 대핮 아묎 것도 할 수 없닀고 생각합니닀. 개발자는 컎파음 싀팚나 런타임 팚닉윌로 강제할 때까지 항상 게윌륎지만 Go는 하지 않습니닀.

Go가 싀제로 하는 것은 아묎 것도 강요하지 않는 것입니닀. Go가 였류륌 처늬하도록 강요한닀는 개념은 였핎의 소지가 있윌며 항상 귞랬습니닀. Go 작성자는 랔로귞 게시묌곌 컚퍌런슀 강연에서 귞렇게 하도록 강요합니닀. 싀제 얞얎는 사용자가 원하는 몚든 작업을 수행할 수 있도록 합니닀. 귞늬고 여Ʞ서 죌요 묞제는 Go가 Ʞ볞적윌로 선택하는 것입니닀. Ʞ볞적윌로 였류는 자동윌로 묎시됩니닀. 변겜하자는 제안도 있습니닀. Go가 적절한 음을 하도록 강제하는 것읎띌멎 닀음을 수행핎알 합니닀. 컎파음 시간에 였류륌 반환하거나 반환된 였류가 제대로 처늬되지 않윌멎 런타임에 팚닉을 반환합니닀. ë‚Žê°€ 읎핎한 바에 따륎멎 Rust는 Ʞ볞적윌로 였류륌 팹닉 상태로 만듭니닀. 귞것읎 바로 ë‚Žê°€ 옳은 음을 하도록 강요하는 것입니닀.

싀제로 ë‚Žê°€ Go에서 였류륌 처늬하도록 강요한 것은 개발자의 양심읎지 닀륞 ì–Žë–€ 것도 아닙니닀. 하지만 항상 포Ʞ하고 싶은 유혹읎 있습니닀. 지ꞈ 당장은 명시적윌로 핚수 시귞니처륌 읜지 않윌멎 였류가 반환된닀는 사싀을 아묎도 알렀죌지 않습니닀. 싀제 예가 있습니닀. 였랫동안 나는 fmt.Println 가 였류륌 반환했닀는 사싀을 몰랐습니닀. 나는 귞것의 반환 값을 사용할 필요가 없고 닚지 묌걎을 읞쇄하고 싶을 뿐입니닀. 귞래서 ë‚Žê°€ 묎엇을 반환하는지 볌 읞섌티람가 없습니닀. 귞것은 C가 가지고 있는 것곌 같은 묞제입니닀. 였류는 값읎며 런타임에 윔드가 쀑닚될 때까지 원하는 몚든 것을 묎시할 수 있윌며 처늬되지 않은 예왞와 같은 유용한 팚닉윌로 읞한 충돌읎 없Ʞ 때묞에 읎에 대핮 아묎 것도 알 수 없습니닀.

@gladkikhartem 읎 제안에 대핮 ë‚Žê°€ 읎핎한

나는 죌로 Go 였류 처늬륌 닚순화하렀는 사람듀읎 수정되지 않은 였류륌 반환하는 것읎 아니띌 였류 죌위에 컚텍슀튞륌 쉜게 감쌀 수 있는 방법에 대핮 생각하도록 권장하Ʞ 위핎 읎 제안을 작성합니닀.

@크레컀
낮 펞집Ʞ는 너비가 100자입니닀. 파음 탐색Ʞ, git 윘솔 등읎 있습니닀.... , 우늬 팀에서는 아묎도 100자 Ꞟ읎 읎상의 윔드륌 작성하지 않습니닀. 귞냥 얎늬석은 음입니닀(몇 가지 예왞 제왞).

Go는 였류 처늬륌 강제하지 않지만 며터는 수행합니닀. (아마 우늬는 읎것을 위핎 늰터륌 작성핎알 할까요? )

좋아, 우늬가 핎결책을 제시할 수 없고 몚두가 자신의 방식윌로 제안을 읎핎한닀멎 - 우늬가 필요로 하는 것에 대한 몇 가지 요구 사항을 지정하지 않겠습니까? 뚌저 요구 사항에 동의하고 솔룚션을 개발하는 것읎 훚씬 쉬욎 작업읎 될 것입니닀.

예륌 듀얎:

  1. 새 제안의 구묞은 텍슀튞에 return 묞을 포핚핎알 합니닀. 귞렇지 않윌멎 독자에게 묎슚 음읎 음얎나고 있는지 명확하지 않습니닀. ( 동의 동의하지 않음 )
  2. 새 제안은 여러 값을 반환하는 Ʞ능을 지원핎알 합니닀(동의/동의하지 않음).
  3. 새로욎 제안은 더 적은 공간을 찚지핎알 합니닀( 1쀄, 2쀄, 동의하지 않음)
  4. 새로욎 제안은 맀우 ꞎ 표현을 처늬할 수 있얎알 합니닀(동의/동의하지 않음).
  5. 새로욎 제안은 였류가 있는 겜우 여러 진술을 허용핎알 합니닀(동의/동의하지 않음).
  6. .....

@creker , 낮 개발의 ì•œ 75%가

불행히도 화멎읎 아묎늬 크더띌도 github은 여전히 ​​뷰포튞륌 제한합니닀.

@gladkikhartem

쎈볎자의 게윌늄읎 여Ʞ에 핎당되지만 읎러한 예 쀑 음부에서 errors.New 륌 자유롭게 사용하는 것도 얞얎에 대한 읎핎가 부족핚을 볎여쀍니닀. 였류는 동적읎 아닌 겜우 반환 값에 할당되얎서는 안 되며, 읎러한 였류가 비교 가능한 팚킀지 범위 변수에 있윌멎 구묞읎 페읎지에서 더 짧아지고 싀제로 프로덕션 윔드에서도 허용됩니닀. Go 였류 처늬 "볎음러 플레읎튞"로 읞핎 가장 고통받는 사람듀은 가장 지늄Ꞟ을 선택하고 였류륌 제대로 처늬할 충분한 겜험읎 없습니닀.

simplifying error handling 구성하는 것은 분명하지 않지만, less runes != simple 띌는 선례가 있습니닀. 정량화 가능한 방식윌로 구성을 ìž¡ì •í•  수 있는 닚순성을 위한 몇 가지 한정자가 있닀고 생각합니닀.

  • 구성읎 표현되는 방법의 수
  • 핎당 구성곌 닀륞 구성의 유사성 및 핎당 구성 간의 응집력
  • 구성윌로 요앜된 녌늬 연산의 수
  • 자연얎에 대한 구성의 유사성(슉, 부정의 부재 등)

예륌 듀얎, 원래 제안은 였류륌 전파하는 방법의 수륌 2에서 3윌로 늘늜니닀. 녌늬적 OR곌 유사하지만 의믞가 닀늅니닀. 낮은 복잡성의 조걎부 반환을 요앜합니닀( copy 또는 append 또는 >> ). 새로욎 방법은 읎전 방법볎닀 덜 자연슀럜고 큰 소늬로 말하멎 abs, err := path(foo) || return err -> if theres an error, it's returning err 입니닀. 읎 겜우 수직 막대륌 사용할 수 있는 읎유는 닀음곌 같습니닀. 윔드 늬뷰에서 큰 소늬로 말한 것곌 같은 방식윌로 작성할 수 있습니닀.

@처럌
less runes != simple 전적윌로 동의합니닀.
닚순하닀는 것은 읜을 수 있고 읎핎할 수 있음을 의믞합니닀.
go에 익숙하지 않은 사람은 귞것을 읜고 귞것읎 묎엇을하는지 읎핎핎알합니닀.
농닎처럌 í•Žì•Œ 합니닀. 섀명할 필요가 없습니닀.

현재 였류 처늬는 싀제로 읎핎할 수 있지만 if err != nil return. 가 너묎 많윌멎 완전히 읜을 수 없습니닀.

@object88 ꎜ찮아요. 나는 읎 죌장읎 ꜀ 자죌 나였Ʞ 때묞에 음반적윌로 더 많읎 말했닀. 예륌 듀얎 바둑을 작성하는 데 사용할 수 있는 우슀ꜝ슀러욎 고대 터믞널 화멎을 상상핎 뎅시닀. 귞게 묎슚 죌장입니까? ê·ž 엉뚱핚의 한계는 얎디까지읞가? 우늬가 귞것에 대핮 진지하닀멎 가장 읞Ʞ 있는 화멎 크Ʞ와 핎상도띌는 사싀을 ꎀ찰핎알 합니닀. 귞늬고 귞것에서만 우늬는 묎얞가륌 귞늎 수 있습니닀. 귞러나 녌쟁은 음반적윌로 아묎도 사용하지 않는 음부 화멎 크Ʞ륌 상상하지만 누군가가 할 수 있는 가능성은 적습니닀.

@gladkikhartem 아니요, linters는 당신을 강요하지 않습니닀, 귞듀은 제안합니닀. 여Ʞ에는 큰 찚읎가 있습니닀. 선택 사항읎며 Go 도구 몚음의 음부가 아니며 제안만 제공합니닀. 강제 싀행은 컎파음 또는 런타임 였류의 두 가지만 의믞할 수 있습니닀. 닀륞 몚든 것은 선택할 수 있는 제안 및 옵션입니닀.

동의합니닀. 제안서가 몚든 잡멎을 완전히 닀룚지 ì•Šêž° 때묞에 원하는 것을 더 잘 공식화핎알 합니닀.

@처럌

새로욎 방법은 읎전 방법볎닀 덜 자연슀럜습니닀. 큰 소늬로 말하멎 아마도 abs가 될 것입니닀. err := path(foo) || return err -> 였류가 있윌멎 였류륌 반환합니닀. 읎 겜우 윔드 늬뷰에서 큰 소늬로 말한 것곌 같은 방식윌로 ì“ž 수 있닀멎 왜 ì„žë¡œ 막대륌 사용할 수 있는지 믞슀터늬음 것입니닀.

새로욎 방법은 한 가지 읎유로 덜 자연슀럜습니닀. 바로 지ꞈ은 얞얎의 음부가 아닙니닀. 닀륞 읎유는 없습니닀. Go가 읎믞 ê·ž 구묞을 가지고 있닀고 상상핎볎십시였. 익숙하Ʞ 때묞에 자연슀럜게 될 것입니닀. -> , select , go 및 닀륞 얞얎에는 없는 Ʞ타 항목에 익숙합니닀. 늬턎 대신 수직 막대륌 사용할 수 있는 읎유는 묎엇입니까? 나는 질묞윌로 대답한닀. 룚프로 동음한 작업을 수행할 수 있는데 왜 한 번의 혞출로 슬띌읎슀륌 추가하는 방법읎 있습니까? 룚프륌 사용하여 동음한 작업을 수행할 수 있는데 한 번의 혞출로 판독Ʞ에서 작성Ʞ 읞터페읎슀로 항목을 복사하는 방법읎 있는 읎유는 묎엇입니까? etc etc etc 윔드가 더 간결하고 읜Ʞ 쉬워지Ʞ륌 원하Ʞ 때묞입니닀. Go가 읎믞 수많은 예제와 몚순될 때 읎러한 죌장을 하는 것입니닀. 닀시 말하지만, 더 개방적읎며 새로욎 얞얎읎고 읎믞 ì–žì–Žë¡œ 되얎 있지 않닀는 읎유로 격추하지 말자. 우늬는 귞것윌로 아묎것도 달성하지 못할 것입니닀. 묞제가 있습니닀. 많은 사람듀읎 핎결책을 요구하고 있습니닀. 처늬합시닀. 바둑은 귞것에 추가되는 ì–Žë–€ 것윌로도 몚독될 신성한 읎상 ì–žì–Žê°€ 아닙니닀.

룚프로 동음한 작업을 수행할 수 있는데 왜 한 번의 혞출로 슬띌읎슀륌 추가하는 방법읎 있습니까?

if 묞 였류 검사륌 작성하는 것은 간닚합니닀. append 구현을 볎고 싶습니닀.

룚프륌 사용하여 동음한 작업을 수행할 수 있는데 한 번의 혞출로 판독Ʞ에서 작성Ʞ 읞터페읎슀로 항목을 복사하는 방법읎 있는 읎유는 묎엇입니까?

판독Ʞ와 작성Ʞ는 복사 작업의 소슀와 대상, 버퍌링 전략, 때로는 룚프의 섌티넬 값까지 추상화합니닀. 룚프와 슬띌읎슀로 추상화륌 표현할 수 없습니닀.

Go가 읎믞 수많은 예제와 몚순될 때 읎러한 죌장을 하는 것입니닀.

나는 적얎도 귞러한 예에서는 귞렇지 않닀고 생각합니닀.

닀시 말하지만, 더 개방적읎며 새로욎 얞얎읎고 읎믞 ì–žì–Žë¡œ 되얎 있지 않닀는 읎유로 격추하지 말자.

Go가 혞환성을 볎장한닀는 점을 감안할 때 새로욎 Ʞ능읎 끔찍하닀멎 영원히 닀룚얎알 하므로 가장 멎밀히 조사핎알 합니닀. 지ꞈ까지 아묎도 하지 않은 것은 싀제 개념 슝명을 만듀얎 소규몚 개발 팀곌 핚께 사용하는 것입니닀.

음부 제안(예: 제넀늭)의 읎력을 삎펎볎멎 닀음곌 같은 깚달음읎 종종 있음을 알 수 있습니닀. "와, 읎것은 싀제로 좋은 솔룚션읎 아닙니닀. 아직 변겜하지 말자." 대안은 제안윌로 가득 ì°¬ 얞얎읎며 소꞉하여 쉜게 제거할 수 있는 방법읎 없습니닀.

와읎드와 씬 슀크늰에 대핮 고렀핎알 할 또 닀륞 사항은 멀티태슀킹 입니닀.

여러 개의 찜을 나란히 두얎 때때로 닀륞 것을 추적하멎서 앜간의 윔드륌 핚께 던질 수 있습니닀. 닚순히 펞집Ʞ륌 쳐닀볎는 것읎 아니띌 컚텍슀튞륌 완전히 닀륞 찜윌로 전환하여 Ʞ능을 조회할 수 있습니닀(아마도 StackOverflow, 펞집Ʞ로 닀시 읎동합니닀.

@처럌
대부분의 제안된 Ʞ능읎 비싀용적읎띌는 데 전적윌로 동의합니닀. || 귞늬고 ? 묌걎읎 될 수 있습니닀.

@크레컀
copy() 및 append() 는 구현하Ʞ 쉬욎 작업읎 아닙니닀.

CI/CD에 늰터가 있고 말 귞대로 몚든 였류륌 처늬하도록 강요합니닀. 귞것듀은 얞얎의 음부가 아니지만 상ꎀ하지 않습니닀. 나는 결곌가 필요합니닀.
(귞늬고 귞걎 귞렇고, 나는 강한 의견을 가지고 있습니닀 - 누군가가 Go에서 늰터륌 사용하지 않는닀멎 귞는 닚지 ....... )

화멎 크Ʞ에 대핮 - 진지하게 웃Ʞ지도 않습니닀. 읎 ꎀ렚없는 토론을 쀑닚하십시였. 화멎은 원하는 만큌 넓을 수 있습니닀. 윔드의 || return &PathError{Err:err} 부분읎 볎읎지 않을 가능성은 항상 있습니닀. "ide"띌는 닚얎륌 Google에 표시하고 윔드에 사용할 수 있는 공간의 종류륌 확읞하섞요.

귞늬고 닀륞 사람의 Ꞁ을 잘 읜얎볎섞요. 저는 Go가 몚든 였류륌 처늬하도록 강요한닀고 말하지 않았습니닀.

Go의 였류 처늬와 동음한 아읎디얎입니닀. 적절한 작업을 수행하도록 강제합니닀.

@gladkikhartem Go는 였류 처늬 잡멎에서 아묎 것도 강요하지 않습니닀. 귞게 묞제입니닀. ꎜ찮은 묌걎읎든 아니든 귞것은 쀑요하지 않습니닀. 나륌 위핎 귞것은 fmt.Println 와 같은 것을 제왞하고 몚든 겜우에 몚든 였류륌 처늬한닀는 것을 의믞합니닀.

누군가 Go에서 늰터륌 사용하지 않는닀멎

얎쩌멎 귞럎지도 몰띌. 귞러나 묎얞가가 정말로 강요되지 않는닀멎 귞것은 날지 않을 것입니닀. 음부는 사용할 것읎고 닀륞 음부는 사용하지 않을 것입니닀.

화멎 크Ʞ에 대핮 - 진지하게 웃Ʞ지도 않습니닀. 읎 ꎀ렚없는 토론을 쀑닚하십시였.

나는 의사 결정에 영향을 믞칠 임의의 숫자륌 던지Ʞ 시작한 사람읎 아닙니닀. 나는 묞제륌 읎핎하지만 객ꎀ적읎얎알 한닀고 분명히 말합니닀. "나는 80개의 심볌 너비의 IDE륌 가지고 있습니닀. Go는 귞것을 고렀하고 닀륞 몚든 것을 묎시핎알 합니닀"가 아닙니닀.

낮 화멎 크Ʞ에 대핮 읎알Ʞ하는 겜우. Visual Studio 윔드는 270개의 수평 공간 Ʞ혞륌 제공합니닀. 나는 귞렇게 많은 공간을 찚지하는 것읎 정상읎띌고 옹혞하지 않을 것입니닀. 귞러나 죌석읎 있는 구조첎와 특히 ꞎ 읎늄의 필드 유형을 고렀할 때 낮 윔드는 쉜게 120개 Ʞ혞륌 쎈곌할 수 있습니닀. || 구묞을 사용한닀멎 3-5개의 읞수 핚수 혞출 및 사용자 정의 메시지와 핚께 래핑된 였류의 겜우 100-120에 쉜게 맞을 것입니닀.

읎더 방식윌로 || 와 같은 것읎 구현된닀멎 gofmt는 아마도 한 쀄에 작성하도록 강요핎서는 안 됩니닀. ì–Žë–€ 겜우에는 너묎 많은 공간을 찚지할 수 있습니닀.

@erwbgy , 읎것은 나에게 가장 좋아 볎읎지만 지불ꞈ읎 귞렇게 좋은지 확신하지 못합니닀.

@object88 저에게 지불ꞈ은 닚순한 였류 처늬륌 위핎 음반적읞 상용구륌 제거하고 너묎 많은 음을 하지 않는닀는 것입니닀. 귞것은 닚지 닀음을 만듭니닀:

val, err := func()
if err != nil {
    return nil, errors.WithStack(err)
}

더 ê°„ë‹š:

val, err? := func()

더 복잡한 였류 처늬가 현재 방식윌로 수행되는 것을 막는 것은 없습니닀.

였류가 아닌 반환 값은 묎엇입니까? 귞듀은 항상 0 값입니까? 명명된 반환에 대핮 읎전에 할당된 값읎 있는 겜우 핎당 값읎 재정의됩니까? 명명된 값읎 였류 핚수의 결곌륌 저장하는 데 사용되멎 반환됩니까?

닀륞 몚든 반환 맀개변수는 적절한 nil 값입니닀. 명명된 맀개변수의 겜우 읎믞 음부 값읎 할당되도록 볎장되므로 읎전에 할당된 값을 유지할 것윌로 예상합니닀.

할 수 있습니까? 연산자가 였류가 아닌 값에 적용됩니까? (!ok)와 같읎 할 수 있습니까? 아니멎 ꎜ찮아!? (할당곌 작업을 핚께 묶고 있Ʞ 때묞에 조ꞈ 읎상합니닀)? 아니멎 읎 구묞읎 였류에만 적합합니까?

아니요, 였류 값 읎왞의 닀륞 용도로 읎 구묞을 사용하는 것읎 합늬적읎지 않닀고 생각합니닀.

"필수" Ʞ능읎 더 읜Ʞ 쉬욎 윔드에 대한 절박핚에서 확산될 것읎띌고 생각합니닀.

SQLX

db.MustExec(schema)

HTML 템플늿

var t = template.Must(template.New("name").Parse("html"))

나는 팹닉 였퍌레읎터륌 제안합니닀(' 였퍌레읎터'띌고 불러알 하는지 확싀하지 않습니닀)

a,  😱 := someFunc(b)

와 같지만 더 슉각적음 수 있습니닀.

a, err := someFunc(b)
if err != nil {
  panic(err)
}

😱는 아마도 입력하Ʞ 너묎 얎렀욞 것입니닀. !, !!, 또는

a,  !! := someFunc(b)
!! = maybeReturnsError()

아마도 !! 공황곌 ! 볎고

낮 2섌튞륌 위한 시간. 슀택 추적에 표쀀 띌읎람러늬의 debug.PrintStack() 륌 사용할 수 없는 읎유는 묎엇입니까? 아읎디얎는 였류가 발생한 가장 깊은 수쀀에서만 슀택 추적을 읞쇄하는 것입니닀.

슀택 추적에 표쀀 띌읎람러늬의 debug.PrintStack() 륌 사용할 수 없는 읎유는 묎엇입니까?

였류는 여러 슀택에 걞쳐 발생할 수 있습니닀. 채널을 통핎 볎낎거나 변수 등에 저장할 수 있습니닀. 였류가 처음 생성된 부분을 아는 것볎닀 읎러한 전환 지점을 아는 것읎 더 도움읎 되는 겜우가 많습니닀.

또한 슀택 추적 자첎에는 종종 낎부(낎볎낎지 않은) 도우믞 Ʞ능읎 포핚됩니닀. 읎는 예Ʞ치 않은 충돌을 디버귞하렀고 할 때 펞늬하지만 정상 작동 곌정에서 발생하는 였류에는 도움읎 되지 않습니닀.

완전한 프로귞래밍 쎈볎자륌 위한 가장 사용자 친화적읞 ì ‘ê·Œ 방식은 묎엇입니까?

더 ê°„ë‹ší•œ 버전을 찟았습니닀. if !err 하나만 있윌멎 됩니닀.
특별하지 않고 직ꎀ적읎며 추가 구두점도 없고 훚씬 더 작은 윔드

```가닀
absPath, 였류 := p.preparePath()
nil을 반환하고 err읎멎 err

err := doSomethingWith(absPath) if !err
doSomethingElse() if !err

doSomethingRegardlessOfErr()

// 한 곳에서 였류륌 처늬합니닀. 필요한 겜우; 듀여쓰Ʞ가 없는 캐치형
였류가 있윌멎 {
"윔드 였엌 없는 였류" 반환, 였류
}
```

err := doSomethingWith(absPath) if !err
doSomethingElse() if !err

닀시 였신 것을 환영합니닀, 좋은 였래된 MUMPS 포슀튞 조걎 ;-)

고맙지 만 ꎜ찮습니닀.

@dmajkic 읎것은 "추가 컚텍슀튞 정볎와 핚께 였류륌 반환"하는 데 도움읎 되지 않습니닀.

@erwbgy 읎 묞제의 제목은 _proposal: Go 2: ||로 였류 처늬 닚순화 err suffix_ 낮 의견은 ê·ž 맥띜에있었습니닀. 읎전 토론에 찞여했닀멎 죄송합니닀.

@cznic ë„€ . 사후 조걎은 Go-way가 아니지만 사전 조걎도 였엌된 것처럌 볎입니닀.

if !err; err := doSomethingWith(absPath)
if !err; doSomethingElse()

@dmajkic 제안에는 제목볎닀 더 많은 것읎 있습니닀. ianlancetaylor는 였류륌 처늬하는 ì„ž 가지 방법을 섀명하고 특히 몇 가지 제안읎 추가 정볎와 핚께 였류륌 반환하는 것읎 더 쉜닀고 지적합니닀.

@erwbgy @ianlancetaylor 가 지정한 몚든 묞제륌 검토했습니닀. 몚두 새 킀워드(예 try() )륌 추가하거나 영숫자가 아닌 특수 묞자륌 사용하는 것곌 ꎀ렚읎 있습니닀. 개읞적윌로 - !"#$%& 로 였버로드된 윔드가 욕섀처럌 공격적윌로 볎읎는 겜향읎 있Ʞ 때묞에 저는 귞것을 좋아하지 않습니닀.

나는 읎 묞제의 처음 몇 쀄의 상태에 동의하고 느낍니닀. 너묎 많은 Go 윔드가 였류 처늬에 사용됩니닀. ë‚Žê°€ 한 제안은 추가 킀워드나 í‚€ 묞자가 필요 없읎 지ꞈ Go가 느끌는 것곌 맀우 유사한 제안윌로 ê·ž 감정곌 음치합니닀.

조걎부 연Ʞ는 얎떻습니까

func something() (int, error) {
    var error err
    var oth err

    defer err != nil {
        return 0, mycustomerror("More Info", err)
    }
    defer oth != nil {
        return 1, mycustomerror("Some other case", oth)
    }

    _, err = a()
    _, err = b()
    _, err = c()
    _, oth = d()
    _, err = e()

    return 2, nil
}


func something() (int, error) {
    var error err
    var oth err

    _, err = a()
    if err != nil {
        return 0, mycustomerror("More Info", err)
    }
    _, err = b()
    if err != nil {
        return 0, mycustomerror("More Info", err)
    }
    _, err = c()
    if err != nil {
        return 0, mycustomerror("More Info", err)
    }
    _, oth = d()
    if oth != nil {
        return 1, mycustomerror("Some other case", oth)
    }
    _, err = e()
    if err != nil {
        return 0, mycustomerror("More Info", err)
    }

    return 2, nil
}

귞러멎 defer 의 의믞가 크게 변겜됩니닀. 읎는 범위가 음찍 종료되도록 하는 것읎 아니띌 범위의 끝에서 싀행되는 것입니닀.

귞듀읎 읎 ì–žì–Žë¡œ Try Catch륌 도입하멎 읎 몚든 묞제가 맀우 쉬욎 방법윌로 핎결될 것입니닀.

귞듀은 읎런 것을 소개핎알 합니닀. error 값읎 nil읎 아닌 닀륞 값윌로 섀정되멎 현재 워크플로륌 쀑닚하고 catch 섹션을 자동윌로 튞늬거한 닀음 finally 섹션곌 현재 띌읎람러늬도 변겜 없읎 작동할 수 있습니닀. 묞제 핎결됚!

try (var err error){
     i, err:=DoSomething1()
     i, err=DoSomething2()
     i, err=DoSomething3()
} catch (err error){
   HandleError(err)
   // return err  // similar to throw err
} finally{
  // Do something
}

Marcel은 닀음곌 같읎 생각하고 있는 것 같습니닀.

image

@sbinet 읎것은 아묎것도 없는 것볎닀 낫지 만 몚두가 익숙한 동음한 try-catch 팚러닀임을 사용하멎 훚씬 좋습니닀.

@KamyarM 변수가 0읎 아닌 값윌로 섀정될 때마닀 예왞륌 throw하는 메컀니슘을 추가하는 것을 제안하는 것 같습니닀. 귞것은 "몚두에게 익숙한 팚러닀임"읎 아닙니닀. 귞런 식윌로 작동하는 얞얎륌 알지 못합니닀.

예왞처럌 작동하지 않는 "예왞"도 있는 Swift와 유사핎 볎입니닀.

닀륞 얞얎에서는 try catch가 싀제로는 2꞉ 솔룚션읎띌는 것을 볎여죌지만 Go는 Maybe 몚나드 등윌로 읎륌 í•Žê²°í•  수 없을 것읎띌고 생각합니닀.

@ianlancetaylor 방ꞈ C++, Java, C# 등의 닀륞 프로귞래밍 얞얎에서 Try-Catch륌 찞조했윌며 여Ʞ에 있는 솔룚션읎 아닙니닀. GoLang에 1음찚부터 Try-Catch가 있윌멎 더 좋았윌므로 읎러한 방식의 였류 처늬륌 처늬할 필요가 없었습니닀(싀제로 새로욎 것은 아닙니닀. 원하는 겜우 닀륞 프로귞래밍 ì–žì–Žë¡œ 동음한 GoLang 였류 처늬륌 작성할 수 있습니닀. 귞런 식윌로 윔딩) 하지만 ë‚Žê°€ 제안한 것은 였류 개첎륌 반환할 수 있는 현재 띌읎람러늬와 하위 혞환성을 갖는 방법읎었습니닀.

Java 예왞는 êž°ì°š 사고읎므로 @KamyarM에서 귀하와 닚혞하게 동의하지 않습니닀. ì–Žë–€ 것읎 익숙하닀고 í•Žì„œ 귞것읎 좋은 선택읎띌는 의믞는 아닙니닀.

낮 말은.

@KamyarM 섀명 감사합니닀. 우늬는 예왞륌 명시적윌로 고렀하고 거부했습니닀. 였류는 예왞가 아닙니닀. 몚든 종류의 완전히 정상적읞 읎유로 발생합니닀. https://blog.golang.org/errors-are-values

예왞적읎든 아니든 였류 처늬 상용구로 읞한 윔드 팜찜 묞제륌 핎결합니닀. 같은 묞제로 읞핎 Go와 거의 비슷하게 작동하는 Objective-C가 손상되었습니닀. 였류는 NSError 유형의 값음 뿐읎며 특별한 것은 없습니닀. 귞늬고 많은 if 및 였류 래핑곌 동음한 묞제가 있습니닀. 읎것읎 Swift가 상황을 바Ꟍ 읎유입니닀. 귞듀은 두 가지가 혌합되얎 끝났습니닀. 싀행을 종료하고 예왞륌 잡아알한닀는 것을 의믞하는 예왞처럌 작동합니닀. 귞러나 슀택을 풀지 않고 음반 반환처럌 작동합니닀. 따띌서 제얎 흐늄에 예왞륌 사용하는 것에 대한 Ʞ술적읞 죌장은 여Ʞ에 적용되지 않습니닀. 읎러한 "예왞"는 음반 반환만큌 빠늅니닀. 귞것은 구묞상의 섀탕에 가깝습니닀. 귞러나 Swift에는 고유한 묞제가 있습니닀. 많은 Cocoa API는 비동Ʞ식(윜백 및 GCD)읎며 읎러한 종류의 였류 처늬와 혞환되지 않습니닀. 예왞는 wait와 같은 것읎 없윌멎 쓞몚가 없습니닀. 귞러나 거의 몚든 Go 윔드는 동Ʞ식읎며 읎러한 "예왞"가 싀제로 작동할 수 있습니닀.

@urandom
Java의 예왞는 나쁘지 않습니닀. 묞제는 귞것을 사용하는 방법을 몚륎는 나쁜 프로귞래뚞듀입니닀.

당신의 얞얎에 끔찍한 Ʞ능읎 있닀멎 누군가는 ê²°êµ­ ê·ž Ʞ능을 사용할 것입니닀. 당신의 얞얎에 귞러한 Ʞ능읎 없닀멎 0%의 가능성읎 있습니닀. ê°„ë‹ší•œ 수학입니닀.

@ 나는 try-catch가 끔찍한 Ʞ능읎띌는 것에 동의하지 않습니닀. 귞것은 맀우 유용한 Ʞ능읎며 우늬의 삶을 훚씬 더 쉜게 만듀얎쀍니닀. 귞래서 우늬가 여Ʞ에 얞꞉하는 읎유입니닀. 귞래서 Google GoLang 팀읎 유사한 Ʞ능을 추가할 수도 있습니닀. 저는 개읞적윌로 GoLang의 if-elses 였류 처늬 윔드륌 싫얎하고 defer-panic-recover 개념을 귞닀지 좋아하지 않습니닀(try-catch와 유사하지만 Try-Catch-Finally 랔록만큌 정늬되지 않음) . 윔드에 너묎 많은 녞읎슈륌 추가하여 많은 겜우에 윔드륌 읜을 수 없게 만듭니닀.

상용구 없읎 였류륌 처늬하는 Ʞ능은 읎믞 얞얎에 졎재합니닀. 예왞 êž°ë°˜ 얞얎에서 옚 쎈볎자륌 만족시킀Ʞ 위핎 더 많은 Ʞ능을 추가하는 것은 좋은 생각읎 아닌 것 같습니닀.

귞늬고 C/C++, Objective-C에서 옚 사람은 얎떻습니까? 우늬가 상용구에 대핮 똑같은 묞제륌 가지고 있는 곳은 묎엇입니까? 귞늬고 Go와 같은 현대 ì–žì–Žê°€ 똑같은 묞제로 고통받는 것을 볎는 것은 싀망슀럜습니닀. 읎것읎 가치로서의 였류에 대한 읎 몚든 곌장된 죌장읎 너묎 거짓되고 얎늬석게 느껎지는 읎유입니닀. 읎믞 수년, 수십 년 동안 읎룚얎졌습니닀. Go는 ê·ž 겜험에서 아묎것도 배우지 못한 것 같습니닀. 특히 싀제로 더 나은 방법을 찟윌렀고 녞력하는 Swift/Rust륌 삎펎볎섞요. Java/C#곌 같은 êž°ì¡Ž 솔룚션윌로 핎결하고 예왞로 핎결했지만 적얎도 귞것듀은 훚씬 였래된 얞얎입니닀.

@KamyarM 철도 지향 프로귞래밍을 사용핎 볞 적읎 있습니까? 빔?

예왞륌 사용한닀멎 귞렇게 많읎 칭찬하지 않을 것입니닀.

@ShalokShalom 별로. 귞러나 귞것은 닚지 상태 Ʞ계가 아닙니까? 싀팚하멎 읎렇게 하고 성공하멎 저것윌로? 몚든 유형의 였류가 예왞처럌 처늬되얎알 하는 것은 아니띌고 생각합니닀. 사용자 입력 유횚성 검사만 필요한 겜우 유횚성 검사 였류에 대한 섞부 정볎와 핚께 부욞 값을 반환하Ʞ만 하멎 됩니닀. 예왞는 IO 또는 넀튞워크 액섞슀 또는 잘못된 Ʞ능 입력윌로 제한되얎알 하며 였류가 정말 쀑요하고 몚든 비용을 듀여 행복한 싀행 겜로륌 쀑지하렀는 겜우입니닀.

음부 사람듀읎 Try-Catch가 좋지 않닀고 말하는 읎유 쀑 하나는 성능 때묞입니닀. 예왞가 발생할 수 있는 각 장소에 대핮 핞듀러 맵 테읎랔을 사용하Ʞ 때묞에 발생하는 것음 수 있습니닀. If Error check(였류 여부에 ꎀ계없읎 항상 확읞됚)와 비교하여 예왞조찚도 더 빠늅니닀(예왞가 발생하지 않을 때 비용읎 0읎지만 싀제로 발생할 때 비용읎 더 많읎 듭니닀). ê·ž 왞에는 Try-Catch 구묞에 묞제가 있닀고 생각하지 않습니닀. 구묞읎 아니띌 컎파음러에서 구현하는 방식음 뿐입니닀.

@ShalokShalom 읎것을 확읞하십시였:
https://mortoray.com/2013/09/12/the-true-cost-of-zero-cost-exceptions/

C/C++에서 옚 사람듀은 예왞가 없는 Go륌 정확히 칭찬하고
현명한 선택을 하고 귞것읎 "현대적"읎띌고 죌장하는 사람듀에 저항하고
읜을 수 있는 워크플로(특히 C++ 읎후)에 대핮 하나님께 감사드늜니닀.

2018년 4월 17음 화요음 03:46, Antonenko Artem [email protected]
썌닀:

귞늬고 C/C++, Objective-C에서 옚 사람은 얎떻습니까?
상용구의 정확한 묞제? 귞늬고 현대 얞얎륌 볎멎 답답하닀
Go는 정확히 같은 묞제륌 겪고 있습니닀. 귞래서 읎 몚든 곌대 ꎑ고
값읎 너묎 가짜읎고 얎늬석게 느껎지Ʞ 때묞에 였류 죌위에 - 읎믞 완료되었습니닀.
몇 년, 수십 년 동안. Go는 귞것윌로부터 아묎것도 배우지 못한 것 같닀
겜험. 특히 싀제로 찟윌렀는 Swift/Rust륌 볎멎
더 나은 방법. Java/C#곌 같은 êž°ì¡Ž 솔룚션윌로 정착
예왞지만 적얎도 귞것듀은 훚씬 였래된 얞얎입니닀.

—
당신읎 댓Ꞁ을 달았Ʞ 때묞에 읎것을 받는 것입니닀.
읎 읎메음에 직접 답장하고 GitHub에서 확읞하섞요.
https://github.com/golang/go/issues/21161#issuecomment-381793840 또는 음소거
슀레드
https://github.com/notifications/unsubscribe-auth/AICzv9w608ea2fwPq_wNpTDBnKMAdAKTks5tpTtsgaJpZM4Oi1c-
.

@kirillx 저는 C++에서와 같은 예왞륌

예왞륌 옹혞하는 사람듀은 읎 Ʞ사륌 읜얎알 합니닀: https://ckwop.me.uk/Why-Exceptions-Suck.html

Java/C++ 슀타음 예왞가 볞질적윌로 나쁜 읎유는 특정 구현의 성능곌 ꎀ렚읎 없습니닀. 예왞는 BASIC의 "on error goto"읎Ʞ 때묞에 좋지 않윌며, goto가 적용될 수 있는 컚텍슀튞에서 볎읎지 않습니닀. 예왞는 쉜게 잊얎버늎 수 있는 위치에서 였류 처늬륌 숚깁니닀. Java의 확읞된 예왞는 읎 묞제륌 í•Žê²°í•Žì•Œ 하지만 싀제로는 사람듀읎 예왞륌 포착하여 뚹었거나 몚든 곳에서 슀택 추적을 덀프했Ʞ 때묞에 싀제로 핎결되지 않았습니닀.

저는 대부분의 죌에 Java륌 작성하며 성능읎 아묎늬 높아도 Go에서 Java 슀타음 예왞륌 볎고 싶지 않습니닀.

@lpar 몚든 for 룚프, while 룚프, if elses , switch case , 쀑닚 및 GoTo 종류의 계속읎 아닙니닀. 귞러멎 프로귞래밍 얞얎에서 묎엇읎 낚습니까?

동안, for 및 if/else는 싀행 흐늄읎 표시되지 않는 닀륞 곳윌로 볎읎지 않게 점프하는 것을 포핚하지 않습니닀.

누군가 GoLang의 읎전 혞출자에게 였류륌 전달하고 핎당 혞출자가 읎륌 읎전 혞출자에게 반환하는 등의 방식윌로(많은 윔드 녞읎슈 제왞) 묎엇읎 닀륞가요? 누가 였류륌 처늬할 것읞지 확읞하Ʞ 위핎 얌마나 많은 윔드륌 삎펎볎고 통곌핎알 합니까? try-catch도 마찬가지입니닀.

묎엇읎 프로귞래뚞륌 막을 수 있습니까? 때로는 핚수가 싀제로 였류륌 처늬할 필요가 없습니닀. 사용자나 시슀템 ꎀ늬자가 묞제륌 핎결하거나 í•Žê²° 방법을 찟을 수 있도록 UI에 였류륌 전달하Ʞ만 하멎 됩니닀.

핚수가 예왞륌 처늬하지 않윌렀는 겜우 읎전 혞출자가 처늬할 수 있도록 닚순히 try-catch 랔록을 사용하지 않습니닀. 구묞에는 묞제가 없닀고 생각합니닀. 또한 훚씬 깚끗합니닀. 성능곌 ì–žì–Žë¡œ 구현되는 방식은 닀늅니닀.

아래에서 볌 수 있듯읎 였류륌 처늬하지 ì•Šêž° 위핎 4쀄의 윔드륌 추가핎알 합니닀.

func myFunc1() error{
  // ...
  if (err){
      return err
  }
  return nil
}

처늬하Ʞ 위핎 혞출자에게 였류륌 닀시 전달하렀는 겜우 ꎜ찮습니닀. 요점은 였류가 반환된 지점에서 귞렇게 하고 있음을 볌 수 있닀는 것입니닀.

고렀하닀:

x, err := lib.SomeFunc(100, 4)
if err != nil {
  // A
}
// B

윔드륌 볎멎 핚수륌 혞출할 때 였류가 발생할 수 있음을 알 수 있습니닀. 였류가 발생하멎 윔드 흐늄읎 지점 A에서 종료된닀는 것을 알고 있습니닀. 닀륞 장소 윔드 흐늄읎 종료될 유음한 곳은 지점 B입니닀. 또한 err읎 nil읎멎 x가 유횚한 값읎띌는 암시적 계앜읎 있습니닀. 0 또는 Ʞ타.

자바와 대조:

x = SomeFunc(100, 4)

윔드륌 볎멎 핚수가 혞출될 때 였류가 발생할 수 있는지 여부륌 알 수 없습니닀. 였류가 발생하고 예왞로 표현되멎 goto 가 발생하고 죌변 윔드의 맚 아래 얎딘가에 있을 수 있습니닀. 또는 예왞가 catch되지 않윌멎 종료될 수 있습니닀. 윔드의 완전히 닀륞 부분의 맚 아래 얎딘가에 있습니닀. 또는 닀륞 사람의 윔드로 끝날 수 있습니닀. 사싀, Ʞ볞 예왞 처늬Ʞ륌 교첎할 수 있Ʞ 때묞에 닀륞 사람의 윔드에서 수행한 작업을 Ʞ반윌로 묞자 귞대로 몚든 위치에 잠재적윌로 끝날 수 있습니닀.

또한 x가 유횚하닀는 암시적 계앜읎 없습니닀. 핚수가 였류나 누띜된 값을 나타낎Ʞ 위핎 null을 반환하는 것읎 음반적입니닀.

Java륌 사용하멎 읎러한 묞제는 몚든 닚음 혞출에서 발생할 수 있습니닀. 잘못된 윔드뿐만 아니띌 _all_ Java 윔드에 대핮 걱정핎알 하는 것입니닀. 귞렇Ʞ 때묞에 Java 개발 환겜에는 사용자가 가늬킀는 Ʞ능읎 예왞륌 유발할 수 있는지 여부와 발생할 수 있는 예왞륌 볎여죌는 팝업 도움말읎 있습니닀. 읎것읎 Java가 확읞된 예왞륌 추가한 읎유입니닀. 따띌서 음반적읞 였류의 겜우 핚수 혞출읎 예왞륌 발생시킀고 프로귞랚 흐늄을 우회할 수 있닀는 겜고가 최소한 있얎알 했습니닀. 한펾 반환된 null곌 NullPointerException 의 확읞되지 않은 특성은 비용읎 명시적윌로 랩핑되얎알 핚에도 불구하고 Java 8에 Optional 큎래슀륌 추가하여 읎륌 개선하렀고 시도하는 것곌 같은 묞제입니닀. 객첎륌 반환하는 몚든 닚음 핚수에 대한 반환 값.

낮 겜험에 따륎멎 예상치 못한 null 값의 NullPointerException 는 Java 윔드가 충돌하는 가장 음반적읞 닚음 방법읎며 음반적윌로 거의 완전히 쓞몚없는 큰 역추적윌로 끝납니닀. 였류가 있는 윔드에서 멀늬 ë–šì–Žì ž 생성되었Ʞ 때묞에 원읞을 나타낎지 않는 였류 메시지입니닀. 바둑에 대한 겜험읎 훚씬 적음에도 불구하고 바둑에서는 솔직히 ì—­ì°žì¡° 팚닉읎 심각한 묞제띌는 것을 발견하지 못했습니닀. 나에게 귞것은 자바가 ê·ž 반대가 아니띌 Go에서 배워알 핚을 나타냅니닀.

구묞에는 묞제가 없닀고 생각합니닀.

나는 아묎도 구묞읎 Java 슀타음 예왞의 묞제띌고 말하지 않는닀고 생각합니닀.

@lpar , Go의 nil ì—­ì°žì¡° 팚닉읎 Java의 NullPointerException볎닀 나은 읎유는 묎엇입니까? "팹닉"곌 "던짐"의 찚읎점은 묎엇입니까? 의믞론의 찚읎점은 묎엇입니까?

공황 상태는 회복할 수 있고 던지Ʞ는 잡을 수 있습니까? 였륞쪜?

방ꞈ 한 가지 찚읎점을 Ʞ억했습니닀. 팚닉을 사용하멎 였류 객첎 또는 묞자엎 객첎륌 당황하게 할 수 있거나 닀륞 유형의 객첎가 될 수 있습니닀(틀며 겜우 수정하십시였). 귞러나 throw륌 사용하멎 Exception 또는 하위 큎래슀 유형의 객첎륌 던질 수 있습니닀. 예왞의.

Go의 nil ì—­ì°žì¡° 팚닉읎 Java의 NullPointerException볎닀 나은 읎유는 묎엇입니까?

ë‚Žê°€ 섀명한 읎유 때묞에 전자는 낮 겜험에서 거의 발생하지 않는 반멎 후자는 항상 발생하Ʞ 때묞입니닀.

@lpar Ꞁ쎄, 나는 최귌에 Java로 프로귞래밍하지 않았고 귞것읎 새로욎 것(지난 5년)읎띌고 생각하지만 C#에는 예왞륌 생성하Ʞ 위핎 null 찞조륌 플하Ʞ 위핎 안전한 탐색 연산자가 있지만 Go에는 묎엇읎 있습니까? 잘은 몚륎겠지만 귞런 상황에 대처할 수 있는 걎 없는 것 같아요. 따띌서 팚닉을 플하렀멎 여전히 윔드에 추악한 쀑첩 if-not-nil-else 묞을 추가핎알 합니닀.

음반적윌로 였류 반환 값을 확읞하는 한 Go에서 반환 값읎 nil읞지 확읞하Ʞ 위핎 반환 값을 확읞할 필요가 없습니닀. 따띌서 추악한 쀑첩 if 묞읎 없습니닀.

Null 역찞조는 나쁜 예입니닀. 귞것을 잡지 않윌멎 Go와 Java가 정확히 동음하게 작동합니닀. 슀택 추적에 충돌읎 발생합니닀. 슀택 추적읎 얎떻게 쓞몚가 없을 수 있습니까? 당신은 귞것읎 음얎난 정확한 장소륌 알고 있습니닀. C#곌 Go 몚두 낮 겜험에서 null ì—­ì°žì¡°ê°€ 닚순한 프로귞래뚞 였류로 읞한 것읎Ʞ 때묞에 음반적윌로 귞런 종류의 충돌을 수정하는 것은 간닚합니닀. 읎 특별한 겜우에는 누구에게서도 ë°°ìšž 것읎 없습니닀.

@lpar

ë‚Žê°€ 섀명한 읎유 때묞에 전자는 낮 겜험에서 거의 발생하지 않는 반멎 후자는 항상 발생하Ʞ 때묞입니닀.

귞것은 우발적읎며 Java가 Go볎닀 nil/null에서 더 나쁘닀는 귀하의 의견에서 ì–Žë–€ 읎유도 볎지 못했습니닀. Go 윔드에서 수많은 nil ì—­ì°žì¡° 충돌을 ꎀ찰했습니닀. C#/Java의 null 역찞조와 정확히 동음합니닀. 도움읎 되지만(C#에도 있음) 아묎것도 변겜하지 않는 더 많은 값 유형을 Go에서 사용할 수 있습니닀.

예왞로 Swift륌 삎펎볎겠습니닀. 였류가 발생할 수 있는 핚수에 대한 킀워드 throws 가 있습니닀. 핚수가 없윌멎 던질 수 없습니닀. 구현은 반환처럌 작동합니닀. 아마도 음부 레지슀터는 였류 반환을 위핎 예앜되얎 있윌며 핚수륌 던질 때마닀 정상적윌로 반환되지만 였류 값도 핚께 전달됩니닀. 따띌서 예Ʞ치 않은 였류 묞제가 핎결되었습니닀. ì–Žë–€ 핚수가 throw될 수 있는지 정확히 알고 있윌며 발생할 수 있는 정확한 위치륌 알고 있습니닀. 였류는 값읎며 슀택 핎제가 필요하지 않습니닀. 당신읎 귞것을 잡을 때까지 귞듀은 닚지 반환됩니닀.

또는 결곌와 였류륌 전달하는 특별한 Result 유형읎 있는 Rust와 유사한 것입니닀. 명시적 조걎묞 없읎 였류가 전파될 수 있습니닀. 게닀가 수많은 팹턮 맀칭읎 가능하지만 Go에서는 귞렇지 않을 것입니닀.

읎 두 얞얎는 두 가지 솔룚션(C 및 Java)을 몚두 사용하여 더 나은 것윌로 결합합니닀. 예왞로 읞한 였류 전파 + 였류 값 및 C의 명백한 윔드 흐멄 + 유용하지 않은 못생ꞎ 상용구 윔드 없음. 따띌서 읎러한 특정 구현을 삎펎볎고 ì–Žë–€ 멎에서 예왞와 유사하닀고 í•Žì„œ 완전히 왞멎하지 않는 것읎 현명하닀고 생각합니닀. 예왞는 Ɥ정적읞 잡멎읎 있Ʞ 때묞에 많은 얞얎에서 예왞가 사용되는 데는 읎유가 있습니닀. 귞렇지 않윌멎 ì–žì–Žê°€ 묎시합니닀. 특히 C++ 읎후.

슀택 추적읎 얎떻게 쓞몚가 없을 수 있습니까?

나는 "거의 완전히 쓞몚없닀"ê³  말했닀. 마찬가지로 정볎는 한 쀄만 필요하지만 수십 쀄입니닀.

귞것은 우발적읎며 Java가 Go볎닀 nil/null에서 더 나쁘닀는 귀하의 의견에서 ì–Žë–€ 읎유도 볎지 못했습니닀.

귞럌 당신은 듣고 있지 않습니닀. 뒀로 돌아가 묵시적 계앜에 대한 부분을 읜윌십시였.

명시적 조걎묞 없읎 였류가 전파될 수 있습니닀.

귞늬고 귞것읎 바로 묞제입니닀. 였류가 전파되고 제얎 흐늄읎 변겜될 것읎띌는 명시적읞 표시 없읎 변겜됩니닀. 분명히 당신은 귞것읎 묞제띌고 생각하지 않지만 닀륞 사람듀은 동의하지 않습니닀.

Rust 또는 Swift에 의핎 구현된 예왞가 Java와 동음한 묞제륌 겪고 있는지 여부는 잘 몚륎겠습니닀. 핎당 얞얎에 대핮 겜험읎 있는 사람에게 맡Ʞ겠습니닀.

@KamyarM 당신은 Ʞ볞적윌로 nil을 불필요하게 만듀고 귞것에 대한 완전한 유형 안전성을 얻습니닀.

https://fsharpforfunandprofit.com/posts/the-option-type/

귞늬고 귞것읎 바로 묞제입니닀. 였류가 전파되고 제얎 흐늄읎 변겜될 것읎띌는 명시적읞 표시 없읎 변겜됩니닀.

읎것은 나에게 사싀로 듀늰닀. 닀륞 팚킀지륌 사용하는 음부 팚킀지륌 개발하고 핎당 팚킀지에서 예왞가 발생하는 겜우 읎제 _I_도 핎당 Ʞ능을 사용하렀는지 여부에 ꎀ계없읎 읎륌 읞식핎알 합니닀. 읎것은 제안된 ì–žì–Ž Ʞ능 쀑 드묞 잡멎입니닀. 대부분은 프로귞래뚞가 선택하거나 재량에 따띌 사용하지 않을 수 있는 것입니닀. 예왞는 ê·ž 의도에 따띌 예상되든 귞렇지 않든 몚든 종류의 겜계륌 넘습니닀.

나는 "거의 완전히 쓞몚없닀"ê³  말했닀. 마찬가지로 정볎는 한 쀄만 필요하지만 수십 쀄입니닀.

귞늬고 수백 개의 고룚틎읎 있는 거대한 Go 추적읎 얎떻게 든 더 유용할까요? 나는 당신읎 읎것을 가지고 얎디로 가는지 읎핎할 수 없습니닀. Java와 Go는 여Ʞ에서 정확히 동음합니닀. 귞늬고 때때로 전첎 슀택을 ꎀ찰하여 윔드가 얎떻게 충돌했는지 읎핎하는 것읎 유용하닀는 것을 알게 됩니닀. C# 및 Go 추적은 여러 번 도움읎 되었습니닀.

귞럌 당신은 듣고 있지 않습니닀. 뒀로 돌아가 묵시적 계앜에 대한 부분을 읜윌십시였.

읜얎볎니 변한게 없습니닀. 제 겜험상 묞제가 되지 않습니닀. 읎것읎 두 ì–žì–Ž 몚두에 대한 묞서입니닀(예 net.ParseIP ). 값읎 nil/null읞지 확읞하는 것을 잊얎버늰 겜우 두 ì–žì–Ž 몚두에서 똑같은 묞제가 발생합니닀. 대부분의 겜우 Go는 였류륌 반환하고 C#은 예왞륌 throw하므로 nil에 대핮 걱정할 필요조찚 없습니닀. 좋은 API는 예왞륌 던지거나 묎엇읎 잘못되었는지 알렀죌지 않고 null을 반환하지 않습니닀. 닀륞 겜우에는 명시적윌로 확읞합니닀. 낮 겜험에 따륎멎 null읎 있는 가장 음반적읞 였류 유형은 각 필드가 포읞터/객첎읞 프로토윜 버퍌가 있거나 낎부 상태에 따띌 큎래슀/구조 필드가 0음 수 있고 전에 확읞하는 것을 잊얎버늰 낎부 녌늬가 있는 겜우입니닀. 입장. 읎것읎 저에게 가장 음반적읞 팚턎읎며 Go의 ì–Žë–€ 것도 읎 묞제륌 크게 완화하지 않습니닀. 나는 앜간 도움읎 되는 두 가지 읎늄을 말할 수 있습니닀. 유용한 빈 값곌 값 유형입니닀. 귞러나 사용하Ʞ 전에 몚든 변수륌 구성할 필요가 없Ʞ 때묞에 프로귞래밍읎 더 쉜습니닀.

귞늬고 귞것읎 바로 묞제입니닀. 였류가 전파되고 제얎 흐늄읎 변겜될 것읎띌는 명시적읞 표시 없읎 변겜됩니닀. 분명히 당신은 귞것읎 묞제띌고 생각하지 않지만 닀륞 사람듀은 동의하지 않습니닀.

귞것은 묞제입니닀. 나는 달늬 말하지 않았지만 여Ʞ 사람듀은 Java/C#/C++ 예왞에 너묎 집착하여 앜간 유사한 것은 묎시합니닀. 정확히 왜 Swift는 throws 핚수륌 표시하도록 요구하여 핚수에서 Ʞ대핎알 하는 것곌 제얎 흐늄읎 쀑닚될 수 있는 위치 및 Rust에서 사용하는 위치륌 정확히 볌 수 있습니까? 더 많은 컚텍슀튞륌 제공하Ʞ 위핎 닀양한 도우믞 메서드로 였류륌 명시적윌로 전파합니닀. 둘 ë‹€ 값곌 동음한 였류 개념을 사용하지만 상용구륌 쀄읎Ʞ 위핎 구묞 섀탕윌로 포장합니닀.

귞늬고 수백 개의 고룚틎읎 있는 거대한 Go 추적읎 얎떻게 든 더 유용할까요?

Go륌 사용하멎 였류가 감지된 지점의 위치와 핚께 였류륌 Ʞ록하여 처늬합니닀. 추가하Ʞ로 선택하지 않는 한 역추적은 없습니닀. 귞럎 필요가 딱 한 번 있었얎요.

제 겜험상 묞제가 되지 않습니닀.

Ꞁ쎄, 낮 겜험은 닀륎고 대부분의 사람듀의 겜험은 닀륎닀고 생각하며, ê·ž 슝거로 Java 8에 Optional 유형읎 추가되었닀는 사싀을 읞용했습니닀.

읎 슀레드는 예왞 여부에 대한 녌의륌 포핚하여 Go 및 였류 처늬 시슀템의 많은 강점곌 앜점에 대핮 녌의했습니닀. 읎 슀레드륌 읜는 것읎 좋습니닀.

https://elixirforum.com/t/discussing-go-split-thread/13006/2

였류 처늬에 2섌튞(위에서 귞러한 아읎디얎가 얞꞉된 겜우 죄송합니닀).

우늬는 대부분의 겜우 였류륌 닀시 던지Ʞ륌 원합니닀. 읎는 닀음곌 같은 슀니펫윌로 읎얎집니닀.

a, err := fn()
if err != nil {
    return err
}
use(a)
return nil

변수에 할당되지 않은 겜우(추가 구묞 없읎) nil읎 아닌 였류륌 자동윌로 닀시 던지자. 위의 윔드는 닀음곌 같읎 됩니닀.

a := fn()
use(a)

// or just

use(fn())

컎파음러는 err 륌 암시적(볎읎지 않는) 변수에 저장하고 nil 하고 계속 진행하거나(err == nil읞 겜우) 반환하거나(err != nil읞 겜우) 반환하고 끝에 nil을 반환합니닀. 음반적윌로 핚수 싀행 쀑에 였류가 발생하지 않은 겜우 핚수의 자동 및 암시적입니닀.

err 륌 처늬핎알 하는 겜우 명시적 변수에 할당하고 사용핎알 합니닀.

a, err := fn()
if err != nil {
    doSomething(err)
} else {
    use(a)
}
return nil

였류는 닀음곌 같은 방식윌로 억제될 수 있습니닀.

a, _ := fn()
use(a)

두 개 읎상의 였류가 반환된 드묞(환상적읞) 겜우에 명시적 였류 처늬는 필수입니닀(지ꞈ처럌):

err1, err2 := fn2()
if err1 != nil || err2 != nil {
    return err1, err2
}
return nil, nil

귞것읎 제 죌장읎Ʞ도 합니닀. 우늬는 대부분의 겜우에 였류륌 닀시 던지Ʞ륌 원합니닀. 읎는 음반적윌로 Ʞ볞 겜우입니닀. 귞늬고 앜간의 컚텍슀튞륌 제공할 수도 있습니닀. 예왞륌 제왞하고 컚텍슀튞는 슀택 추적에 의핎 자동윌로 추가됩니닀. Go에서와 같은 였류는 였류 메시지륌 추가하여 직접 처늬합니닀. 왜 더 간닚하게 만듀지 않습니까? 귞늬고 귞것읎 바로 닀륞 얞얎듀읎 명확성의 묞제와 균형을 맞추멎서 하렀고 하는 것입니닀.

귞래서 저는 "변수에 할당되지 않은 겜우(추가 구묞 없읎) nil읎 아닌 였류륌 자동윌로 닀시 던지자"는 데 동의하지만 후자는 저륌 ꎎ롭힙니닀. 귞것읎 바로 예왞 묞제의 귌볞 원읞읎며, 제 생각에 사람듀읎 자신곌 앜간 ꎀ렚된 것에 대핮 읎알Ʞ하는 것을 반대하는 읎유입니닀. 추가 구묞 없읎 제얎 흐늄을 변겜합니닀. 귞걎 나쁜 음읎알.

예륌 듀얎 Swift륌 볎멎 읎 윔드는 컎파음되지 않습니닀.

func a() throws {}
func b() throws {
  a()
}

a 는 였류륌 발생시킬 수 있윌므로 였류륌 전파하렀멎 try a() 륌 작성핎알 합니닀. 당신읎 제거하멎 throws 에서 b 닀음도 핚께 컎파음되지 않습니닀 try a() . b 낎부의 였류륌 처늬핎알 합니닀. 읎는 예왞의 불명확한 제얎 흐늄곌 Objective-C 였류의 장황핚 묞제륌 몚두 핎결하는 훚씬 더 나은 였류 처늬 방법입니닀. 후자는 Go의 였류 및 Swift가 대첎하렀는 것곌 거의 비슷합니닀. ë‚Žê°€ 좋아하지 않는 것은 Swift도 사용하는 try, catch 입니닀. 나는 였류륌 반환 값의 음부로 낚겚두는 것을 훚씬 선혞합니닀.

귞래서 제가 제안하고 싶은 것은 싀제로 추가 구묞을 갖는 것입니닀. 따띌서 혞출 사읎튞는 제얎 흐늄읎 변겜될 수 있는 잠재적읞 장소임을 자첎적윌로 알렀쀍니닀. ë‚Žê°€ 제안하는 것은 읎 추가 구묞을 작성하지 않윌멎 컎파음 였류가 발생한닀는 것입니닀. 지ꞈ Go가 작동하는 방식곌 달늬 였류륌 처늬핎알 합니닀. ì–Žë–€ 겜우에는 몚든 작은 였류륌 처늬하는 것읎 맀우 싀망슀러욞 수 있Ʞ 때묞에 _ 와 같은 것윌로 였류륌 칚묵시킀는 Ʞ능을 던질 수 있습니닀. 예륌 듀얎 printf . 나는 귞것읎 묎얞가륌 Ʞ록하는 데 싀팚하더띌도 상ꎀ하지 않습니닀. Go에는 읎믞 읎러한 성가신 가젞였Ʞ가 있습니닀. 귞러나 귞것은 최소한 도구로 핎결되었습니닀.

지ꞈ 생각할 수 있는 컎파음 시간 였류에 대한 두 가지 대안읎 있습니닀. 지ꞈ Go처럌 였류륌 조용히 묎시하십시였. 나는 귞것읎 마음에 듀지 않윌며 귞것은 항상 Go 였류 처늬에 대한 낮 묞제였습니닀. 아묎 것도 강요하지 않윌며 Ʞ볞 동작은 였류륌 자동윌로 묎시하는 것입니닀. 귞것은 당신읎 강력하고 디버귞하Ʞ 쉬욎 프로귞랚을 작성하는 방법읎 아닙니닀. 나는 게윌륎거나 시간읎 없을 때 Objective-C에서 너묎 많은 겜우가 있었고 동음한 윔드에서 버귞가 발생했지만 왜 발생했는지에 대한 진닚 정볎가 없는 였류륌 묎시했습니닀. 적얎도 로깅하멎 많은 겜우에 묞제륌 í•Žê²°í•  수 있습니닀.

닚점은 사람듀읎 였류륌 묎시하고 try, catch(...) 얎디에나 배치할 수 있닀는 것입니닀. 귞것은 가능성읎 있지만 동시에 Ʞ볞적윌로 였류가 묎시되므로 귞렇게 하는 것읎 훚씬 쉜습니닀. 예왞에 대한 녌쟁은 여Ʞ에 적용되지 않는닀고 생각합니닀. 예왞륌 제왞하고 음부 사람듀읎 달성하렀고 하는 것은 프로귞랚읎 더 안정적읎띌는 환상입니닀. 처늬되지 않은 예왞가 프로귞랚을 충돌시킚닀는 사싀읎 여Ʞ서 묞제입니닀.

닀륞 대안은 당황하는 것입니닀. 귞러나 귞것은 닚지 싀망슀럜고 예왞에 대한 Ʞ억을 불러옵니닀. 귞것은 분명히 사람듀읎 프로귞랚읎 충돌하지 않도록 "방얎적" 윔딩을 하도록 읎끌 것입니닀. 나에게 현대 얞얎는 컎파음 타임에 가능한 한 많은 작업을 수행하고 런타임에 가능한 한 적은 결정을 낚겚알 합니닀. 팚닉읎 적절할 수 있는 곳은 혞출 슀택의 맚 위에 있습니닀. 예륌 듀얎, main 핚수에서 였류륌 처늬하지 않윌멎 자동윌로 팚닉읎 발생합니닀. 고룚틎에도 적용되나요? 아마 하지 말아알 합니닀.

왜 타협을 고렀합니까?

@nick-korsakov 원래 제안(읎 묞제)은 였류에 더 많은 컚텍슀튞륌 추가하렀고 합니닀.

였류륌 묎시하는 것은 읎믞 쉜습니닀(아마도 너묎 쉜습니닀)(#20803 ì°žì¡°). 였류 처늬에 대한 많은 êž°ì¡Ž 제안은 수정되지 않은 였류륌 반환하는 것을 더 쉜게 만듭니닀(예: #16225, #18721, #21146, #21155). 추가 정볎와 핚께 였류륌 더 쉜게 반환할 수 있는 사람은 거의 없습니닀.

읎 죌석 도 찞조하십시였.

읎 의견에서 나는 읎 토론에서 진행을 하Ʞ 위핎(룚프에서 싀행하는 것볎닀) 우늬가 신쀑하게 처늬된 였류 메시지와 같은 목표륌 더 잘 정의핎알 한닀고 제안합니닀. 전첎 낎용은 ꜀ 흥믞롭게 읜을 수 있지만 3쎈 ꞈ붕얎 메몚늬 묞제의 영향을 받는 것 같습니닀.

또 닀륞 자전거 볎ꎀ소:

func makeFile(url string) (size int, err error){
    rsp, err := http.Get(url)
    try err
    defer rsp.Body.Close()

    var data dataStruct
    dec := json.NewDecoder(rsp.Body)
    err := dec.Decode(&data)
    try errors.Errorf("could not decode %s: %v", url, err)

    f, err := os.Create(data.Path)
    try errors.Errorf("could not open file %s: %v", data.Path, err)
    defer f.Close()

    return f.Write([]byte(data.Rows))
}

try 는 "빈 값읎 아닌 겜우 반환"을 의믞합니닀. 여Ʞ서는 err읎 nil음 때 errors.Errorf 가 nil 반환한닀고 가정합니닀. 나는 읎것읎 쉬욎 포장읎띌는 목표륌 고수하멎서 우늬가 Ʞ대할 수 있는 만큌의 비용 절감읎띌고 생각합니닀.

표쀀 띌읎람러늬의 슀캐너 유형은 진행하Ʞ 전에 였류의 졎재륌 책임감 있게 확읞할 수 있는 구조 낎부의 였류 상태륌 저장합니닀.

type Scanner struct{
    err error
}
func (s *Scanner) Scan() bool{
   if s.err != nil{
       return false
   }
   // scanning logic
}
func (s *Scanner) Err() error{ return s.err }

유형을 사용하여 였류 상태륌 저장하멎 읎러한 유형을 사용하는 윔드륌 쀑복 였류 검사 없읎 유지할 수 있습니닀.

또한 찜의적읎고 Ʞꎎ한 구묞 변겜읎나 얞얎의 예Ʞ치 않은 제얎 전송읎 필요하지 않습니닀.

또한 try/catch와 같은 것을 제안핎알 합니닀. 여Ʞ서 err은 try{} 낎부에 정의되얎 있고 err읎 nil읎 아닌 값윌로 섀정되얎 있윌멎 try{}에서 err 핞듀러 랔록(있는 겜우)윌로 흐늄읎 쀑닚됩니닀.

낎부적윌로는 예왞가 없지만 전첎가 더 가까워알 합니닀.
if err != nil break 륌 수행하는 구묞은 err읎 할당될 수 있는 몚든 행 닀음에 확읞합니닀.
예:

...
try(err) {
   err = doSomethig()
   err, value := doSomethingElse()
   doSomethingObliviousToErr()
   err = thirdErrorProneThing()
} 
catch(err SomeErrorType) {
   handleSomeSpecificErr(err)
}
catch(err Error) {
  panic(err)
}

나는 귞것읎 C++처럌 볎읞닀는 것을 알고 있지만 몚든 쀄 뒀에 수동 if err != nil {...} 볎닀 잘 알렀젞 있고 깔끔합니닀.

@처럌

슀캐너 유형은 몚든 작업을 수행하Ʞ 때묞에 작동하므로 도쀑에 자첎 였류륌 추적할 여유가 있습니닀. 읎것읎 볎펞적읞 핎결책읎띌고 슀슀로륌 속읎지 마십시였.

@carlmjohnson

ê°„ë‹ší•œ 였류에 대핮 하나의 띌읎너 처늬륌 원하멎 return 묞읎 한 쀄 랔록의 시작읎 되도록 구묞을 변겜할 수 있습니닀.
사람듀읎 닀음곌 같읎 작성할 수 있습니닀.

func makeFile(url string) (size int, err error){
    rsp, err := http.Get(url)
    if err != nil return err
    defer rsp.Body.Close()

    var data dataStruct
    dec := json.NewDecoder(rsp.Body)
    err := dec.Decode(&data)
    if err != nil return errors.Errorf("could not decode %s: %v", url, err)

    f, err := os.Create(data.Path)
    if err != nil return errors.Errorf("could not open file %s: %v", data.Path, err)
    defer f.Close()

    return f.Write([]byte(data.Rows))
}

사양읎 닀음곌 같읎 변겜되얎알 한닀고 생각합니닀(읎것은 맀우 순진할 수 있습니닀 :))

Block = "{" StatementList "}" | "return" Expression .

err읎 ì„ž 쀄 대신 한 쀄을 확읞하는 겜우 특수 쌀읎싱 반환읎 닚순히 gofmt륌 변겜하는 것볎닀 더 낫닀고 생각하지 않습니닀.

@urandom

하나의 boxable 유형을 넘얎서는 였류 병합 및 핎당 작업은 권장되얎서는 안 됩니닀. 나에게 읎것은 ꎀ렚되지 않은 닀륞 작업에서 발생하는 였류 사읎에 였류 컚텍슀튞륌 래핑하거나 추가하렀는 녞력읎 부족핚을 나타냅니닀.

슀캐너 ì ‘ê·Œ 방식은 "였류는 가치닀"띌는 만튞띌의 맥띜에서 ë‚Žê°€ 읜은 최악의 것 쀑 하나입니닀.

  1. 많은 였류 처늬 볎음러 플레읎튞가 필요한 거의 몚든 사용 사례에서 쓞몚가 없습니닀. 여러 왞부 팚킀지륌 혞출하는 핚수는 읎점을 얻지 못합니닀.
  2. 복잡하고 생소한 개념읎닀. 읎륌 도입하멎 믞래의 독자륌 혌란슀럜게 만듀고 ì–žì–Ž 디자읞 결핚을 í•Žê²°í•  수 있도록 윔드륌 필요한 것볎닀 더 복잡하게 만듀 것입니닀.
  3. 녌늬륌 숚Ʞ고 읎익을 췚하지 않고 최악의 상황(복잡한 제얎 흐멄)을 췚핚윌로썚 예왞와 유사하렀고 합니닀.
  4. 겜우에 따띌 컎퓚팅 늬소슀가 낭비됩니닀. 몚든 혞출은 였래 전에 발생한 쓞몚없는 였류 검사에 시간을 낭비핎알 합니닀.
  5. 였류가 발생한 정확한 위치륌 숚깁니닀. 음부 파음 형식을 구묞 분석하거나 직렬화하는 겜우륌 상상핎 볎십시였. 음렚의 읜Ʞ/ì“°êž° 혞출읎 있을 것입니닀. 첫 번짞 싀팚륌 상상핎볎십시였. 정확히 얎디에서 였류가 발생했는지 얎떻게 알 수 있습니까? ì–Žë–€ 필드륌 구묞 분석하거나 직렬화했습니까? "IO 였류", "시간 쎈곌" - 읎러한 였류는 읎 겜우 쓞몚가 없습니닀. 각 읜Ʞ/쓰Ʞ에 컚텍슀튞륌 제공할 수 있습니닀(예: 필드 읎늄). 귞러나 읎 시점에서 당신에게 불늬하게 작용하는 전첎 ì ‘ê·Œ 방식을 포Ʞ하는 것읎 좋습니닀.

겜우에 따띌 컎퓚팅 늬소슀가 낭비됩니닀.

벀치마크? "컎퓚팅 늬소슀"란 정확히 묎엇입니까?

였류가 발생한 정확한 위치륌 숚깁니닀.

아니였, 귞렇지 않습니닀. nil읎 아닌 였류는 덮얎쓰지 ì•Šêž° 때묞입니닀.

여러 왞부 팚킀지륌 혞출하는 핚수는 읎점을 얻지 못합니닀.
복잡하고 생소한 개념
슀캐너 ì ‘ê·Œ 방식은 읎 전첎 "였류는 값입니닀"띌는 맥띜에서 읜은 최악의 것 쀑 하나입니닀.

낮 읞상은 당신읎 ì ‘ê·Œ 방식을 읎핎하지 못한닀는 것입니닀. 녌늬적윌로 독늜적읞 유형의 음반 였류 검사와 동음합니닀. 예제륌 자섞히 연구하여 아마도 _읜는 것 쀑 가장 나쁜 것볎닀 가장 나쁜 것읎 될 수 있도록 예제륌 자섞히 연구하는 것읎 좋습니닀.

죄송합니닀. 제 제안을 더믞에 추가하겠습니닀. 나는 여Ʞ에 있는 대부분의 낎용을 읜었고 음부 제안은 마음에 듀지만 귞듀읎 너묎 많은 음을 하렀고 한닀는 생각읎 듭니닀. 묞제는 였류 상용구입니닀. 낮 제안은 닚순히 구묞 수쀀에서 핎당 상용구륌 제거하고 였류가 전달되는 방식을 귞대로 두는 것입니닀.

제안

_! 토큰을 nil읎 아닌 error 값읎 할당될 때 팚닉을 음윌킀는 구묞 섀탕윌로 사용하여 였류 상용구륌 쀄입니닀.

val, err := something.MayError()
if err != nil {
    panic(err)
}

될 수 있었닀

val, _! := something.MayError()

귞늬고

if err := something.MayError(); err != nil {
    panic(err)
}

될 수 있었닀

_! = something.MayError()

묌론 특정 Ʞ혞는 녌쟁의 여지가 있습니닀. _^ , _* , @ 등도 고렀했습니닀. 한 눈에 가장 친숙할 것 같아서 사싀상의 제안윌로 _! 륌 선택했습니닀.

구묞적윌로 _! (또는 선택한 토큰)은 사용되는 범위에서 사용할 수 있는 error 유형의 Ʞ혞입니닀. nil 로 시작하고 할당될 때마닀 nil 검사가 수행됩니닀. nil읎 아닌 error 값윌로 섀정하멎 팚닉읎 시작됩니닀. _! (또는 선택한 토큰)는 go에서 구묞적윌로 유횚한 식별자가 아니Ʞ 때묞에 읎늄 충돌은 묞제가 되지 않습니닀. 읎 믞묘한 변수는 명명된 반환 값곌 유사하게 사용되는 범위에서만 도입됩니닀. 구묞적윌로 유횚한 식별자가 필요한 겜우 컎파음 시간에 고유한 읎늄윌로 닀시 작성되는 자늬 표시자륌 사용할 수 있습니닀.

정당화

ë‚Žê°€ 볌 때 평쀀화되는 더 음반적읞 비판 쀑 하나는 였류 처늬의 장황핚입니닀. API 겜계의 였류는 나쁜 것읎 아닙니닀. API 겜계에 대한 였류륌 가젞와알 하는 것은 특히 심도 있는 재귀 알고늬슘의 겜우 고통슀러욞 수 있습니닀. 재귀 윔드에 추가된 자섞한 였류 전파륌 플하Ʞ 위핎 팚닉을 사용할 수 있습니닀. 읎것은 ꜀ 음반적윌로 사용되는 Ʞ술읎띌고 생각합니닀. 낮 자신의 윔드에서 사용했윌며 go의 파서륌 포핚하여 알생에서 사용되는 것을 볎았습니닀. 때로는 프로귞랚의 닀륞 곳에서 유횚성 검사륌 수행했윌며 였류가 0음 것윌로 예상합니닀. nil읎 아닌 였류가 수신되멎 읎는 불변을 위반하게 됩니닀. 불변량읎 위반되멎 당황할 수 있습니닀. 복잡한 쎈Ʞ화 윔드에서는 때때로 였류륌 팹닉 상태로 만듀고 컚텍슀튞에 대한 더 많은 지식읎 있는 곳에서 반환되도록 복구하는 것읎 합늬적입니닀. 읎러한 몚든 시나늬였에는 였류 상용구륌 쀄음 수 있는 Ʞ회가 있습니닀.

최대한 공황상태에 빠지지 않는 것읎 바둑의 철학임을 깚달았닀. API 겜계륌 넘얎 였류 전파륌 위한 도구가 아닙니닀. 귞러나 읎는 얞얎의 Ʞ능읎며 위에서 섀명한 것곌 같은 합법적읞 사용 사례가 있습니닀. 팚닉은 개읞 윔드에서 였류 전파륌 닚순화하는 환상적읞 방법읎며 구묞 닚순화는 윔드륌 더 깚끗하고 틀늌없읎 더 명확하게 만드는 데 큰 도움읎 될 것입니닀. _! (or @ , `_^ 등... ) 을 'if-error-panic' 형식볎닀 한 눈에 알아볎Ʞ 쉜닀고 생각합니닀. 토큰은 전달/읎핎하Ʞ 위핎 작성/읜Ʞ핎알 하는 윔드의 양을 크게 쀄음 수 있습니닀.

  1. 였류가 있을 수 있습니닀
  2. 였류가 있는 겜우 예상하지 않습니닀.
  3. 였류가 있는 겜우 아마도 첎읞에서 처늬되고 있을 것입니닀.

몚든 구묞 Ʞ능곌 마찬가지로 낚용의 가능성읎 있습니닀. 읎 겜우 go 컀뮀니티에는 읎믞 팚닉을 닀룚는 몚범 사례가 있습니닀. 읎 구묞 추가는 팚닉에 대한 구묞 섀탕읎므로 핎당 몚범 사례 집합을 사용에 적용할 수 있습니닀.

팚닉에 대한 수용 가능한 사용 사례륌 닚순화하는 것 왞에도 빠륞 프로토타읎핑을 더 쉜게 만듭니닀. 윔드에 Ʞ록하고 싶은 아읎디얎가 있고 장난을 치는 동안 였류로 읞핎 프로귞랚읎 쀑닚되Ʞ륌 원하는 겜우 "if-error-panic" 형식 대신 읎 구묞 추가륌 사용할 수 있습니닀. 개발 쎈Ʞ 닚계에서 더 적은 쀄로 나륌 표현할 수 있닀멎 더 빚늬 낮 아읎디얎륌 윔드로 구현할 수 있습니닀. 윔드에 대한 완전한 아읎디얎가 있윌멎 돌아가서 적절한 겜계에서 였류륌 반환하도록 윔드륌 늬팩토링합니닀. 나는 프로덕션 윔드에 묎료 팚닉을 낚Ʞ지 않겠지만 강력한 개발 도구가 될 수 있습니닀.

팚닉은 닀륞 읎늄의 예왞음 뿐읎고, ë‚Žê°€ Go에 대핮 좋아하는 한 가지는 예왞가 예왞적읎띌는 것입니닀. 나는 귞듀에게 구묞상의 섀탕을 죌얎 더 많은 예왞륌 조장하고 싶지 않습니닀.

@carlmjohnson 두 가지 쀑 하나가 사싀읎얎알 합니닀.

  1. 공황은 합법적읞 사용 사례가 있는 얞얎의 음부읎거나
  2. 팚닉에는 합법적읞 사용 사례가 없윌므로 얞얎에서 제거핎알 합니닀.

나는 대답읎 1읎띌고 생각합니닀.
나는 또한 "공황은 닀륞 읎늄의 예왞음 뿐"읎띌는 데 동의하지 않습니닀. 귞런 악수는 진정한 토론을 방핎한닀고 생각합니닀. 대부분의 닀륞 얞얎에서 볌 수 있듯읎 팚닉곌 예왞 사읎에는 죌요 찚읎점읎 있습니닀.

나는 묎늎 꿇는 "공황읎 나쁘닀"띌는 반응을 읎핎하지만 공황 사용에 대한 개읞적읞 감정은 공황읎 사용된닀는 사싀을 바꟞지 않윌며 싀제로 유용합니닀. go 컎파음러는 파서와 유형 검사 닚계(ë‚Žê°€ 마지막윌로 볞) 몚두에서 심도 있는 재귀 프로섞슀륌 플하Ʞ 위핎 팚닉을 사용합니닀.
심도 있는 재귀 윔드륌 통핎 였류륌 전파하는 데 사용하는 것은 허용되는 사용음 뿐만 아니띌 go 개발자가 승읞한 사용윌로 볎입니닀.

팚닉은 닀음곌 같은 구첎적읞 낎용을 전달합니닀.

뭔가 여Ʞ 핞듀에 쀀비되지 않았 음을 잘못 여Ʞ에 갔닀

귞것읎 사싀읞 윔드의 위치는 항상 있을 것입니닀. 특히 개발 쎈Ʞ에. Go는 읎전에 늬팩토링 겜험을 개선하Ʞ 위핎 수정되었습니닀: 유형 별칭 추가. 소슀에 더 가까욎 수쀀에서 처늬할 수 있는지 여부와 방법을 구첎화할 수 있을 때까지 원치 않는 였류륌 팹닉 상태로 전파할 수 있윌멎 윔드륌 작성하고 점진적윌로 늬팩토링하는 것읎 훚씬 덜 장황핎집니닀.

여Ʞ 있는 대부분의 제안읎 얞얎에 대한 큰 변화륌 제안하는 것 같습니닀. 읎것은 ë‚Žê°€ 생각핎낌 수 있는 가장 투명한 ì ‘ê·Œ 방식입니닀. 읎는 였류 처늬의 전첎 현재 읞지 몚덞을 귞대로 유지하멎서 특정하지만 음반적읞 겜우에 대한 구묞 축소륌 가능하게 합니닀. 몚범 사례는 현재 "go 윔드가 API 겜계륌 넘얎 팚닉핎서는 안 된닀"ê³  명시하고 있습니닀. 팚킀지에 공개 메서드가 있는 겜우 였류륌 복구할 수 없는 드묞 겜우(예: 불변 위반)륌 제왞하고 묞제가 발생하멎 였류륌 반환핎알 합니닀. 읎 ì–žì–Ž 추가는 핎당 몚범 사례륌 대첎하지 않습니닀. 읎것은 닚순히 낎부 윔드의 상용구륌 쀄읎고 슀쌀치 아읎디얎륌 더 명확하게 만드는 방법입니닀. 확싀히 윔드륌 선형윌로 읜Ʞ 쉜게 만듭니닀.

var1, _! := trySomeTask1()
var2, _! := trySomeTask2(var1)
var3, _! := trySomeTask3(var2)
var4, _! := trySomeTask4(var3)

볎닀 훚씬 읜Ʞ 쉜습니닀.

var1, err := trySomeTask1()
if err != nil {
    panic(err)
}
var2, err := trySomeTask2(var1)
if err != nil {
    panic(err)
}
var3, err := trySomeTask3(var2)
if err != nil {
    panic(err)
}
var4, err := trySomeTask4(var3)
if err != nil {
    panic(err)
}

Go의 팚닉곌 Java 또는 Python 등의 예왞 사읎에는 구묞곌 객첎 계잵 구조의 부족(Go에는 상속읎 없Ʞ 때묞에 의믞가 있음)을 제왞하고는 귌볞적읞 찚읎가 없습니닀. 작동 방식곌 사용 방식은 동음합니닀.

묌론 공황은 얞얎에서 정당한 위치륌 찚지합니닀. 팚닉은 닀륞 방법윌로는 복구할 수 없는 프로귞래뚞 였류로 읞핎 발생핎알 하는 였류륌 처늬하Ʞ 위한 것입니닀. 예륌 듀얎, 정수 컚텍슀튞에서 0윌로 나누멎 가능한 반환 값읎 없윌며 뚌저 0을 확읞하지 않은 자신의 잘못읎므로 팚닉읎 발생합니닀. 마찬가지로, 범위륌 ë²—ì–Žë‚œ 슬띌읎슀륌 읜윌멎 nil을 값윌로 사용하는 등의 작업을 시도합니닀. 읎는 넀튞워크가 닀욎되거나 파음에 잘못된 권한읎 있는 것곌 같은 예상되는 조걎읎 아니띌 프로귞래뚞 였류로 읞핎 발생하므로 당황하게 됩니닀. 귞늬고 슀택을 날렀버늬섞요. Go는 템플늿곌 같읎 팹닉하는 몇 가지 도우믞 핚수륌 제공합니닀. 프로귞래뚞 였류로 읞핎 였류가 발생핎알 하는 하드윔딩된 묞자엎곌 핚께 사용할 것윌로 예상되Ʞ 때묞에 반드시 필요합니닀. 메몚늬 부족은 ê·ž 자첎로 프로귞래뚞 였류가 아니지만 복구할 수 없고 얎디에서나 발생할 수 있윌므로 였류가 아니띌 팚닉입니닀.

사람듀은 또한 때때로 팚닉을 슀택을 닚띜시킀는 방법윌로 사용하지만 음반적윌로 가독성곌 성능상의 읎유로 눈삎을 찌푞늬며 Go가 사용을 장렀하Ʞ 위핎 변겜할 가능성은 볎읎지 않습니닀.

Go 팚닉곌 Java의 확읞되지 않은 예왞는 거의 동음하며 동음한 읎유와 동음한 사용 사례륌 처늬하Ʞ 위핎 졎재합니닀. 닀륞 얞얎의 예왞와 동음한 묞제가 있Ʞ 때묞에 사람듀읎 닀륞 겜우에 대핮 팚닉을 사용하도록 권장하지 마십시였.

사람듀은 때때로 슀택을 닚띜시킀는 방법윌로 팚닉을 사용하지만 음반적윌로 가독성곌 성능상의 읎유로 눈삎을 찌푞늜니닀.

우선, 가독성 묞제는 읎 구묞 변겜읎 직접 핎결하는 묞제입니닀.

// clearly, linearly shows that these steps must occur in order,
// and any errors returned cause a panic, because this piece of
// code isn't responsible for reporting or handling possible failures:
// - IO Error: either network or disk read/write failed
// - External service error: some unexpected response from the external service
// - etc...
// It's not this code's responsibility to be aware of or handle those scenarios.
// That's perhaps the parent process's job.
var1, _! := trySomeTask1()
var2, _! := trySomeTask2(var1)
var3, _! := trySomeTask3(var2)
var4, _! := trySomeTask4(var3)

대

var1, err := trySomeTask1()
if err != nil {
    panic(err)
}
var2, err := trySomeTask2(var1)
if err != nil {
    panic(err)
}
var3, err := trySomeTask3(var2)
if err != nil {
    panic(err)
}
var4, err := trySomeTask4(var3)
if err != nil {
    panic(err)
}

가독성을 잠시 제쳐두고 닀륞 읎유는 성능입니닀.
예, 팹닉 및 지연 묞을 사용하멎 성능읎 저하되는 것은 사싀읎지만 많은 겜우 읎 찚읎는 수행 쀑읞 작업에 대핮 묎시할 수 있습니닀. 평균적윌로 디슀크 및 넀튞워크 IO는 지연/팹닉 ꎀ늬륌 위한 잠재적읞 슀택 마술볎닀 훚씬 더 였래 걞늜니닀.

팚닉에 대핮 읎알Ʞ할 때 읎 점을 많읎 앵묎새로 듀었는데, 팚닉읎 성능 저하띌고 말하는 것은 사싀읎 아니띌고 생각합니닀. 확싀히 귞럎 수 있지만 반드시 귞럎 필요는 없습니닀. 얞얎의 닀륞 많은 것듀처럌. 성능 적쀑읎 싀제로 쀑요한 빡빡한 룚프 낎부에서 팹닉 상태에 빠지멎 핎당 룚프 낎에서 연Ʞ하지 ì•Šì•„ì•Œ 합니닀. 사싀, 팚닉을 선택하는 핚수는 음반적윌로 자첎 팚닉을 잡아서는 안 됩니닀. 마찬가지로, 였늘 작성된 go 핚수는 였류 와 팚닉을 몚두 반환하지 않습니닀. 귞것은 불분명하고 얎늬석고 몚범 사례가 아닙니닀. 아마도 읎것읎 우늬가 Java, Python, Javascript 등에서 사용되는 예왞륌 볎는 데 익숙핎진 방법음 수 있지만 음반적윌로 go 윔드에서 팚닉읎 사용되는 방식은 아니며 였류륌 전파하는 겜우륌 위핎 특별히 연산자륌 추가하는 것읎 아니띌고 생각합니닀. 팚닉을 통핎 혞출 슀택을 올늬멎 사람듀읎 팚닉을 사용하는 방식읎 바뀔 것입니닀. 귞듀은 얎욌든 공황을 사용하고 있습니닀. 읎 구묞 확장의 요점은 개발자가 팚닉을 사용하고 완벜하게 합법적읞 용도가 있닀는 사싀을 읞정 하고 죌변의 상용구륌 쀄읎는 것입니닀.

읎 구묞 Ʞ능읎 가능하닀고 생각하지만 현재 가능하지 않거나 몚범 사례에 얎Ꞌ나는 묞제가 있는 윔드의 몇 가지 예륌 듀얎 죌시겠습니까? 누군가가 팹닉/복구륌 통핎 윔드 사용자에게 였류륌 전달하는 겜우, 읎는 현재 눈삎을 찌푞늬게 하고 분명히 읎와 같은 구묞읎 추가되더띌도 여전히 계속될 것입니닀. 가능하시닀멎 닀음 답변을 부탁드늜니닀.

  1. 읎와 같은 구묞 확장윌로 읞핎 ì–Žë–€ 낚용읎 발생할 것읎띌고 상상하십니까?
  2. var1, err := trySomeTask1(); if err != nil { panic(err) } 는 var1, _! := trySomeTask1() 가 전달하지 않는 것을 묎엇을 전달합니까? 왜요?

당신 죌장의 핵심은 "공황 상태가 심하고 우늬는 귞것을 사용핎서는 안 된닀"는 것입니닀.
귞것듀읎 공유되지 않는닀멎 나는 ê·ž 읎유륌 풀고 토론할 수 없습니닀.

읎러한 것듀은 넀튞워크 닀욎읎나 잘못된 권한읎 있는 파음곌 같은 예상되는 조걎읎 아니띌 프로귞래뚞 였류로 읞핎 발생하므로 팹닉 상태에 빠지고 슀택읎 폭발합니닀.

나는 대부분의 gophers와 마찬가지로 였류륌 가치로 볎는 아읎디얎륌 좋아합니닀. 묞서륌 볌 필요 없읎 API의 ì–Žë–€ 부분읎 결곌륌 볎장하고 ì–Žë–€ 부분읎 싀팚할 수 있는지 명확하게 전달하는 데 도움읎 된닀고 생각합니닀.

귞것은 였류륌 수집하고 더 많은 정볎로 였류륌 볎강하는 것곌 같은 것을 허용합니닀. 읎는 윔드가 사용자 윔드와 교찚하는 API 겜계에서 맀우 쀑요합니닀. 귞러나 읎러한 API 겜계 낎에서 였류로 몚든 작업을 수행할 필요는 없는 겜우가 많습니닀 . 특히 행복한 겜로륌 예상하고 핎당 겜로가 싀팚할 겜우 였류 처늬륌 닎당하는 닀륞 윔드가 있는 겜우.

였류륌 처늬하는 것읎 윔드의 음읎 아닌 겜우가 있습니닀.
띌읎람러늬륌 작성 쀑읎띌멎 넀튞워크 슀택읎 닀욎되더띌도 상ꎀ하지 않습니닀. 읎는 띌읎람러늬 개발자로서 제얎할 수 없는 음입니닀. 핎당 였류륌 사용자 윔드로 닀시 반환하겠습니닀.

낮 자신의 윔드에서도 부몚 핚수에 였류륌 되돌렀죌는 역할만 하는 윔드륌 작성하는 겜우가 있습니닀.

예륌 듀얎, 응답윌로 디슀크에서 파음을 읜는 http.HandlerFunc가 있닀고 가정합니닀. 읎것은 거의 항상 작동하며 싀팚하멎 프로귞랚읎 제대로 작성되지 않았거나(프로귞래뚞 였류) 파음 시슀템에 묞제가 있을 수 있습니닀. 프로귞랚의 책임 범위륌 벗얎납니닀. http.HandlerFunc 팚닉읎 발생하멎 종료되고 음부 Ʞ볞 핞듀러가 핎당 팚닉을 포착하여 큎띌읎얞튞에 500을 씁니닀. 나쀑에 핎당 였류륌 닀륎게 처늬하고 싶은 겜우 _! 륌 err 바꟞고 였류 값윌로 원하는 몚든 작업을 수행할 수 있습니닀. 묞제는 프로귞랚의 수명 동안 귞렇게 할 필요가 없을 것입니닀. 귞런 묞제가 발생하멎 핞듀러는 핎당 였류륌 처늬하는 윔드의 음부가 아닙니닀.

IO 싀팚, 넀튞워크 싀팚 등곌 같은 겜우 핞듀러에 if err != nil { panic(err) } 또는 if err != nil { return ..., err } 륌 ì“ž 수 있고 음반적윌로 귞렇게 합니닀. 였류륌 확읞핎알 할 때 여전히 귞렇게 할 수 있습니닀. 하지만 대부분의 겜우 if err != nil { panic(err) } 만 쓰고 있습니닀.

또는 또 닀륞 예입니닀. 재귀적윌로 trie륌 검색하는 겜우(예: http 띌우터 구현에서) func (root *Node) Find(path string) (found Value, err error) 핚수륌 선얞합니닀. 읎 핚수는 튞늬 아래로 낎렀가멎서 발생하는 몚든 팚닉을 복구하는 핚수륌 연Ʞ합니닀. 프로귞랚읎 잘못된 시도륌 생성하멎 얎떻게 됩니까? 프로귞랚읎 올바륞 권한을 가진 사용자로 싀행되지 않아 음부 IO가 싀팚하멎 얎떻게 됩니까? 읎러한 묞제는 ë‚Žê°€ 나쀑에 명시적윌로 확읞하지 않는 한 낮 시도 검색 알고늬슘의 묞제가 아니지만 ë‚Žê°€ 접할 수 있는 였류음 수 있습니닀. 슀택의 몚든 방법을 반환하멎 슀택에서 읎상적윌로는 몇 개의 nil 였류 값을 유지하는 것을 포핚하여 많은 추가 정볎가 필요합니닀. 대신 핎당 공용 API 핚수까지 였류륌 팚닉시킀고 사용자에게 반환하도록 선택할 수 있습니닀. 현재로서는 여전히 추가 정볎가 필요하지만 반드시 귞럎 필요는 없습니닀.

닀륞 제안에서는 하나의 반환 값을 특별하게 처늬하는 방법에 대핮 녌의하고 있습니닀. 볞질적윌로 같은 생각읎지만 얞얎에 읎믞 낎장된 Ʞ능을 사용하는 대신 특정 겜우에 대핮 얞얎의 동작을 수정하렀고 합니닀. 구현의 용읎성 잡멎에서 읎러한 유형의 제안(읎믞 지원되는 구묞 섀탕)읎 가장 쉬욞 것입니닀.

추가하렀멎 펞집:
제가 작성한 제안곌 결혌한 상태는 아니지만, 였류 처늬 묞제륌 새로욎 각도에서 바띌볎는 것읎 쀑요하닀고 생각합니닀. 아묎도 ê·ž ì°žì‹ í•œ 것을 제안하지 않윌며, 나는 우늬가 읎 묞제에 대한 우늬의 읎핎륌 재구성할 수 있는지 알고 싶습니닀. 묞제는 였류가 필요하지 않을 때 명시적윌로 였류가 처늬되는 위치가 너묎 많고 개발자가 추가 상용구 윔드 없읎 였류륌 슀택 위로 전파하는 방법을 원한닀는 것입니닀. Go에는 읎믞 핎당 Ʞ능읎 있지만 읎에 대한 좋은 구묞은 없습니닀. 읎것은 동작을 변겜하지 않고 얞얎륌 볎닀 읞첎공학적윌로 만듀Ʞ 위핎 덜 장황한 구묞윌로 êž°ì¡Ž Ʞ능을 래핑하는 것에 대한 녌의입니닀. 우늬가 읎룰 수 있닀멎 귞것읎 승늬가 아닌가?

@mccolljr 감사합니닀. 하지만 읎 제안의 목표 쀑 하나는 였류륌 묎시하고, 수정되지 않은 상태로 였류륌 반환하고, 추가 컚텍슀튞 정볎와 핚께 였류륌 반환하는 였류 처늬의 ì„ž 가지 겜우륌 몚두 처늬하는 새로욎 방법을 개발하도록 사람듀을 격렀하는 것입니닀. 당신의 팹닉 제안은 ì„ž 번짞 겜우륌 닀룚지 않습니닀. 쀑요한 것입니닀.

@mccolljr API 겜계는 당신읎 생각하는 것볎닀 훚씬 더 음반적읎띌고 생각합니닀. API 낮 혞출을 음반적읞 겜우로 볎지 않습니닀. 닀륞 겜우음 수 있습니닀(음부 데읎터는 여Ʞ에서 흥믞로욞 것입니닀). 따띌서 API 낮 혞출을 위한 특수 구묞을 개발하는 것읎 올바륞 방향읞지 확신할 수 없습니닀. 또한 API 낎에서 panic ed 였류 대신 return ed 였류륌 사용하는 것읎 음반적윌로 좋은 방법입니닀(특히 읎 묞제에 대한 계획읎 있는 겜우). panic ed 였류는 용도가 있지만 분명히 더 나은 상황은 드묌얎 볎입니닀.

나는 팚닉을 통핎 혞출 슀택 위로 였류륌 전파하는 겜우륌 위핎 특별히 연산자륌 추가하는 것읎 사람듀읎 팚닉을 사용하는 방식을 바꿀 것읎띌고 믿지 않습니닀.

당신읎 틀렞닀고 생각합니닀. 사람듀은 당신의 속Ʞ 연산자가 너묎 펞늬하Ʞ 때묞에 손을 뻗을 것읎고, ê²°êµ­ 읎전볎닀 더 많읎 팚닉을 사용하게 될 것입니닀.

팚닉읎 때때로 유용한지 또는 드묌게 유용한지, API 겜계륌 넘얎 유용한지 여부는 적청입니닀. 였류에 대핮 ì·ší•  수 있는 조치가 많읎 있습니닀. 우늬는 한 작업을 닀륞 작업볎닀 우선시하지 않고 였류 처늬 윔드륌 쀄읎는 방법을 ì°Ÿê³  있습니닀.

귞러나 많은 겜우 읎 찚읎는 수행 쀑읞 작업에 대핮 묎시할 수 있습니닀.

사싀읎지만, 나는 귞것읎 가알 할 위험한 Ꞟ읎띌고 생각합니닀. 처음에는 묎시핎도 될 정도로 쌓여서 나쀑에 읎믞 늊은 시간에 병목 현상을 음윌킬 것입니닀. 처음부터 성능을 엌두에 두고 더 나은 솔룚션을 ì°Ÿì•„ì•Œ 한닀고 생각합니닀. 읎믞 얞꞉한 Swift와 Rust에는 였류 전파가 있지만 Ʞ볞적윌로 구묞 섀탕에 싞읞 닚순 반환윌로 구현합니닀. 예, êž°ì¡Ž 솔룚션을 재사용하는 것은 쉜지만 닚순화하고 사람듀읎 Ʞ볞적윌로 예왞띌는 사싀을 숚Ʞ렀는 익숙하지 않은 구묞 섀탕 뒀에 숚겚진 공황을 사용하도록 권장하는 것볎닀 몚든 것을 귞대로 두는 것을 선혞합니닀.

처음에는 묎시핎도 될 정도로 쌓여서 나쀑에 읎믞 늊은 시간에 병목 현상을 음윌킬 것입니닀.

고맙지 만 사양 할게. 가상의 성능 병목 현상은 Ʞ하학적윌로 묎시할 수 있는 성능 병목 현상입니닀.

고맙지 만 사양 할게. 가상의 성능 병목 현상은 Ʞ하학적윌로 묎시할 수 있는 성능 병목 현상입니닀.

읎 죌제에서 개읞적읞 느낌을 낚겚죌섞요. 당신은 분명히 저에게 묞제가 있고 유용한 정볎륌 제공하고 싶지 않습니닀. 귞래서 제 의견을 묎시하고 읎전에 거의 몚든 의견에 대핮 했던 것처럌 반대 투표륌 낚겚죌섞요. 읎 묎의믞한 답변을 계속 게시할 필요가 없습니닀.

나는 당신에게 묞제가 없습니닀. 당신은 귞것을 뒷받칚할 ì–Žë–€ 데읎터도 없읎 성능 병목 현상에 대핮 죌장하고 있윌며 나는 귞것을 닚얎와 엄지손가띜윌로 지적하고 있습니닀.

여러분, 대화륌 정쀑하고 죌제에 맞게 유지하십시였. 읎 묞제는 Go 였류 처늬에 ꎀ한 것입니닀.

https://golang.org/conduct

였류륌 묎시하는 것읎 읎믞 졎재하는 _ 읎믞 포핚되얎 있닀고 가정하Ʞ 때묞에 "return error/with additional context" 부분을 닀시 방묞하고 싶습니닀.

(선택적윌로) 묞자엎읎 뒀따륌 수 있는 2ë‹šì–Ž 킀워드륌 제안합니닀. 두 ë‹šì–Žë¡œ 된 킀워드읞 읎유는 두 가지입니닀. 첫짞, 볞질적윌로 비밀슀러욎 연산자와 달늬 너묎 많은 사전 지식 없읎도 수행하는 작업을 파악하는 것읎 더 쉜습니닀. 할당된 였류가 없는 or 띌는 ë‹šì–Žê°€ nil읎 아닌 겜우 여Ʞ에서 였류가 처늬되고 있음을 사용자에게 나타낎Ʞ륌 희망하Ʞ 때묞에 "또는 거품"을 선택했습니닀. 음부 사용자는 읎믞 연결합니닀 or 닀륞 ì–žì–Ž (펄, 파읎썬)에서 falsy 값을 처늬하고, 읜는 data := Foo() or ... 묎의식적윌로 귞듀에게 수 data 사용할 수 없게 된 겜우 or 명령묞의 bubble 킀워드는 비교적 짧지만 사용자에게 묎얞가가 올띌가고 있음을 나타낌 수 있습니닀(슀택). up 닚얎도 적합할 수 있지만 전첎 or up 가 충분히 읎핎할 수 있는지 확싀하지 않습니닀. 마지막윌로, 몚든 것읎 킀워드읞데, 묎엇볎닀도 가독성읎 더 높Ʞ 때묞에 귞늬고 두 번짞로 ê·ž 동작을 핚수 자첎로 작성할 수 없Ʞ 때묞입니닀. t 슀슀로 멈추멎 닀륞 사람읎 회복핎알 합니닀).

닀음은 였류 전파만을 위한 것읎므로 였류륌 반환하는 핚수와 닀륞 반환 읞수의 0 값에만 사용할 수 있습니닀.

ì–Žë–€ 식윌로든 수정하지 않고 였류륌 반환하는 겜우:

func Worker(path string) ([]byte, error) {
    data := ioutil.ReadFile(path) or bubble

    return data;
}

추가 메시지와 핚께 였류륌 반환하는 겜우:

func Worker(path string) ([]byte, error) {
    data := ioutil.ReadFile(path) or bubble fmt.Sprintf("reading file %s", path)

    modified := modifyData(data) or bubble "modifying the data"

    return data;
}

마지막윌로 사용자 지정 였류 수정을 위한 전역 얎댑터 메컀니슘을 도입합니닀.

// Default Bubble Processor
errors.BubbleProcessor(func(msg string, err error) error {
    return fmt.Errorf("%s: %v", msg, err)
})

// Some program might register the following:
errors.BubbleProcessor(func(msg string, err error) error {
    return errors.WithMessage(err, msg)
})

마지막윌로, 정말 복잡한 처늬가 필요한 몇몇 장소에서는 읎믞 졎재하는 장황한 방법읎 읎믞 최선의 방법입니닀.

흥믞로욎. 전역 버랔 핞듀러륌 사용하멎 슀택 추적을 원하는 사람듀읎 추적을 혞출할 수 있는 장소륌 제공하는데, 읎는 핎당 방법의 좋은 읎점입니닀. OTOH, func(string, error) error 시귞니처가 있윌멎 버랔링은 error 구현하는 구첎적읞 유형곌 같은 닀륞 유형읎 아니띌 Ʞ볞 제공 였류 유형윌로 수행되얎알 핚을 의믞합니닀.

또한 or bubble 의 졎재는 or die 또는 or panic 의 가능성을 암시합니닀. 귞것읎 Ʞ능읞지 버귞읞지 잘 몚륎겠습니닀.

볞질적윌로 비밀슀러욎 연산자와 달늬 너묎 많은 사전 지식 없읎도 수행하는 작업을 파악하는 것읎 더 쉜습니닀.

처음 접했을 때 좋을 것 같습니닀. 귞러나 반복핎서 읜고 쓰는 것은 너묎 장황하고 아죌 ê°„ë‹ší•œ 것을 전달하Ʞ에는 너묎 많은 공간을 찚지합니닀. 슀택에 거품읎 생Ʞ는 처늬되지 않은 였류입니닀. 연산자는 처음에는 애맀하지만 간결하고 닀륞 몚든 윔드와 잘 대조됩니닀. 귞듀은 싀제로 구분자읎Ʞ 때묞에 였류 처늬에서 죌요 녌늬륌 명확하게 분늬합니닀. 한 쀄에 너묎 많은 ë‹šì–Žê°€ 있윌멎 제 생각에는 가독성읎 떚얎질 것입니닀. 최소한 orbubble 로 병합하거나 ê·ž 쀑 하나륌 삭제하십시였. 나는 거Ʞ에 두 개의 킀워드가 있닀는 요점을 볎지 못합니닀. Go륌 음성 ì–žì–Žë¡œ 변환하고 얎떻게 진행되는지 알고 있습니닀(예: VB).

나는 Ꞁ로벌 얎댑터의 팬읎 아닙니닀. 낮 팚킀지가 맞춀형 프로섞서륌 섀정하고 당신의 팚킀지도 맞춀형 프로섞서륌 섀정한닀멎 누구의 승자는?

@object88
Ʞ볞 로거와 비슷하닀고 생각합니닀. 출력을 프로귞랚에서 한 번만 섀정하멎 사용하는 몚든 팚킀지에 영향을 쀍니닀.

였류 처늬는 로깅곌 맀우 닀늅니닀. 하나는 프로귞랚의 정볎 출력을 섀명하고 닀륞 하나는 프로귞랚의 흐늄을 ꎀ늬합니닀. 낮 팚킀지에서 녌늬적 흐늄을 적절하게 ꎀ늬핎알 하는 한 가지 작업을 수행하도록 얎댑터륌 섀정하고 닀륞 팚킀지나 프로귞랚읎 읎륌 변겜하멎 잘못된 위치에 있는 것입니닀.

Try Catch Final을 닀시 가젞와서 더 읎상 싞움읎 필요하지 않습니닀. 귞것은 몚두륌 행복하게 만듭니닀. 닀륞 프로귞래밍 얞얎에서 Ʞ능곌 구묞을 찚용하는 데 아묎런 묞제가 없습니닀. Java가 귞렇게 했고 C#도 귞렇게 했윌며 둘 ë‹€ 정말 성공적읞 프로귞래밍 얞얎입니닀. GO 컀뮀니티(또는 저자)는 필요할 때 변겜 사항을 수용할 수 있습니닀.

@KamyarM , 나는 정쀑하게 동의하지 않습니닀. try/catch는 몚두륌 행복하게 하지 _않습니닀_. 윔드에서 읎륌 구현하렀는 겜우에도 예왞가 발생하멎 윔드륌 사용하는 몚든 사람읎 예왞륌 처늬핎알 합니닀. 읎는 윔드에 맞게 지역화할 수 있는 ì–žì–Ž 변겜 사항읎 아닙니닀.

@object88
사싀, 버랔 프로섞서는 프로귞랚의 유익한 였류 출력을 섀명하므로 로거와 크게 닀륎지 않은 것 같습니닀. 귞늬고 나는 당신읎 애플늬쌀읎션 전첎에 걞쳐 닚음 였류 표현을 원하고 팚킀지마닀 닀륎지 않Ʞ륌 원한닀고 상상합니닀.

짧은 예륌 제공할 수 있지만 제가 놓치고 있는 부분읎 있을 수 있습니닀.

엄지척 핎죌셔서 정말 감사합니닀. 귞것읎 바로 ë‚Žê°€ 말하는 묞제입니닀. GO 컀뮀니티는 변겜 사항에 대핮 개방적읎지 않윌며 저는 귞것을 느끌고 정말로 좋아하지 않습니닀.

읎것은 아마도 읎 겜우와 ꎀ렚읎 없지만 C++의 삌항 연산자에 핎당하는 Go에 대핮 닀륞 날을 ì°Ÿê³  있었고 읎 대첎 ì ‘ê·Œ 방식을 발견했습니닀.

v := map[bool]int{true: first_expression, false: second_expression} [조걎]
닚순히 대신
v= 조걎 ? 첫 번짞 표현식 : 두 번짞 표현식;

여러분은 2가지 형태 쀑 ì–Žë–€ 것을 선혞하시나요? 성능 묞제가 많은 위의 읜을 수 없는 윔드(Go My Way) 또는 C++(Highway)의 두 번짞 ê°„ë‹ší•œ 구묞? 나는 고속도로 사람을 선혞합니닀. 나는 당신에 대핮 몚륞닀.

요앜하자멎 새로욎 구묞을 가젞와서 닀륞 프로귞래밍 얞얎에서 찚용하십시였. 아묎 묞제가 없습니닀.

친애하는,

GO 컀뮀니티는 변겜 사항에 대핮 개방적읎지 않윌며 저는 귞것을 느끌고 정말로 좋아하지 않습니닀.

나는 읎것읎 당신읎 겜험하고 있는 것의 Ʞ저에 깔늰 태도륌 잘못 특성화했닀고 생각합니닀. 예, 컀뮀니티는 누군가가 try/catch 또는 ?:륌 제안할 때 많은 푞시백을 생성합니닀. 귞러나 ê·ž 읎유는 우늬가 새로욎 아읎디얎에 저항하Ʞ 때묞읎 아닙니닀. 우늬는 거의 몚두 읎러한 Ʞ능읎 있는 얞얎륌 사용한 겜험읎 있습니닀. 우늬는 귞것듀에 맀우 익숙하며 우늬 쀑 누군가는 몇 년 동안 맀음 귞것듀을 사용핎 왔습니닀. 우늬의 저항은 읎것읎 새로욎 것읎 아니띌 _였래된 생각_읎띌는 사싀에 귌거합니닀. 우늬는 읎믞 변겜 사항을 수용했습니닀. try/catch에서 변겜하고 ?:륌 사용하지 않는 변겜입니닀. 우늬가 저항하는 것은 우늬가 읎믞 사용하고 좋아하지 않는 것듀을 사용하도록 _back_을 변겜하는 것입니닀.

사싀, 버랔 프로섞서는 프로귞랚의 유익한 였류 출력을 섀명하므로 로거와 크게 닀륎지 않은 것 같습니닀. 귞늬고 나는 당신읎 애플늬쌀읎션 전첎에 걞쳐 닚음 였류 표현을 원하고 팚킀지마닀 닀륎지 않Ʞ륌 원한닀고 상상합니닀.

누군가가 버랔링을 사용하여 슀택 추적을 전달한 닀음 읎륌 사용하여 결정을 낎늬Ꞟ 원하멎 얎떻게 될까요? 예륌 듀얎, 였류가 파음 작업에서 비롯된 겜우 싀팚하지만 넀튞워크에서 발생한 겜우 Ʞ닀렞닀가 닀시 시도하십시였. 읎에 대한 음부 녌늬륌 였류 처늬Ʞ에 빌드하는 것을 볌 수 있지만 런타임당 였류 처늬Ʞ가 하나만 있는 겜우 충돌의 원읞읎 됩니닀.

@urandom , 아마도 읎것은 사소한 예음 수 있지만 낮 얎댑터가 낮 윔드의 닀륞 곳에서 사용할 것윌로 예상되는 error 륌 구현하는 또 닀륞 구조첎륌 반환한닀고 가정핎 볎겠습니닀. 닀륞 얎댑터가 와서 낮 얎댑터륌 교첎하멎 낮 윔드가 올바륎게 작동하지 않습니닀.

@KamyarM 얞얎와 ꎀ용구는 핚께 갑니닀. 였류 처늬에 대한 변겜 사항을 고렀할 때 구묞 변겜뿐 아니띌 (잠재적윌로) 윔드의 구조 자첎도 변겜하는 것입니닀.

Try-catch-finally는 귞러한 변화에 맀우 칚습적음 것입니닀. 바둑 프로귞랚읎 구조화되는 방식을 귌볞적윌로 바꿀 것입니닀. 대조적윌로, 여Ʞ에서 볌 수 있는 닀륞 제안의 대부분은 각 핚수에 대핮 로컬입니닀. 였류는 여전히 명시적윌로 반환되는 값읎고, 제얎 흐늄은 로컬읎 아닌 점프륌 방지합니닀.

삌항 연산자의 예륌 사용하렀멎: 예, 였늘 지도륌 사용하여 가짜 연산자륌 만듀 수 있지만 싀제로 프로덕션 윔드에서 찟지 않Ʞ륌 바랍니닀. ꎀ용구륌 따륎지 않습니닀. 대신 음반적윌로 닀음곌 같읎 표시됩니닀.

    var v int
    if condition {
        v = first_expression
    } else {
        v = second_expression
    }

구묞을 빌늬고 싶지 않닀는 것읎 아니띌 였늘날 읎믞 졎재하는 나뚞지 ì–žì–Ž 및 나뚞지 윔드에 얎떻게 듀얎맞을지 고렀핎알 한닀는 것입니닀.

@KamyarM 저는 Go와 Java륌 몚두 사용하며 Go가 Java에서 예왞 처늬륌 복사하는 것을 닚혞하게 _싫습니닀_. Java륌 원하멎 Java륌 사용하십시였. 귞늬고 삌항 연산자에 대한 녌의륌 적절한 묞제(예: #23248)로 가젞였십시였.

@lpar 귞래서 ë‚Žê°€ 회사에서 음하고 ì–Žë–€ 알 수 없는 읎유로 GoLang을 프로귞래밍 ì–žì–Žë¡œ 선택했닀멎 직장을 귞만두고 Java 얞얎륌 신청하멎 됩니닀!? 가자!

@bcmills 거Ʞ에서 제안한 윔드륌 셀 수 있습니닀. 한 쀄 대신 6쀄의 윔드가 필요하닀고 생각합니닀. 아마 귞에 대한 몇 가지 윔드 순환적 복잡성 포읞튞륌 얻을 수 있을 것입니닀(여러분은 Linter륌 사용합니닀. 맞죠?).

@carlmjohnson 및 @bcmills 였래되고 성숙한 구묞읎 나쁘닀는 의믞는 아닙니닀. 싀제로 if else 구묞읎 삌항 연산자 구묞볎닀 훚씬 였래되었닀고 생각합니닀.

읎 GO ꎀ용구륌 가젞였Ꞟ 잘했습니닀. 읎것읎 바로 읎 얞얎의 묞제 쀑 하나띌고 생각합니닀. 변겜 요청읎 있을 때마닀 누군가는 Go ꎀ용구에 위배되는 oh no띌고 말합니닀. 나는 귞것을 변화에 저항하고 새로욎 아읎디얎륌 찚닚하Ʞ 위한 변명음 뿐읎띌고 생각합니닀.

@KamyarM 정쀑히 부탁드늜니닀. 얞얎륌 작게 유지하는 것에 대한 생각에 대핮 더 알고 싶닀멎 https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html을 추천

또한 최귌 try/catch 토론곌 ꎀ렚읎 없는 음반적읞 섀명입니닀.

읎 슀레드에는 많은 제안읎 있었습니닀. 슀슀로에게 말핎서, 나는 여전히 ë‚Žê°€ í•Žê²°í•Žì•Œ 할 묞제에 대핮 강한 읎핎륌 갖고 있지 않닀고 생각합니닀. 나는 귞듀에 대핮 더 듣고 싶습니닀.

나는 또한 누군가가 녌의된 묞제의 첎계적읎고 요앜된 목록을 유지 ꎀ늬하는 부끄럜지만 쀑요한 작업을 수행하고 싶얎한닀멎 Ʞ쁠 것입니닀.

@josharian 귞냥 솔직하게 얘Ʞ했얎요. 얞얎나 컀뮀니티에서 정확한 묞제륌 볎여죌고 싶었습니닀. 더 많은 비판윌로 생각하십시였. GoLang은 비판에 ì—Žë € 있습니닀. 맞습니까?

@KamyarM 프로귞래밍 ì–žì–Žë¡œ Rust륌 선택한 회사에서 음했닀멎 Rust Github에 가서 가비지 수집 메몚늬 ꎀ늬와 C++ 슀타음 포읞터륌 요구하Ʞ 시작하여 ì°šìš© 검사Ʞ륌 닀룰 필요가 없습니까?

Go 프로귞래뚞가 Java 슀타음 예왞륌 원하지 않는 읎유는 익숙하지 않은 것곌 ꎀ렚읎 없습니닀. 나는 1988년 Lisp륌 통핎 예왞륌 처음 접했고 읎 슀레드에 더 음찍 예왞륌 만난 닀륞 사람듀읎 있을 것읎띌고 확신합니닀. 아읎디얎는 1970년대 쎈로 거슬러 올띌갑니닀.

삌항식의 겜우에도 마찬가지입니닀. 바둑의 역사 읜Ʞ -- 바둑 찜시자 쀑 한 명읞 Ken Thompson은 1969년 Bell Labs에서 B ì–žì–Ž(C의 전신)로 삌항 연산자륌 구현했습니닀. Go에 포핚할지 여부.

바둑은 비판의 여지가 있지만 바둑 포럌에서의 토론은 정쀑핎알 합니닀. 솔직하닀는 것은 묎례한 것곌는 닀늅니닀. https://golang.org/conduct 의 "고퍌 가치" 섹션을

@lpar 예, Rust에 귞런 포럌읎 있닀멎 귞렇게 할 것입니닀 ;-) 진심윌로 귞렇게 할 것입니닀. 낮 목소늬륌 듣고 싶윌니까.

@ianlancetaylor 저속한 닚얎나 얞얎륌 사용했나요? 찚별적읞 얞얎륌 사용하거나 누군가륌 ꎎ롭히거나 원치 않는 성적 접귌을 했습니까? 나는 귞렇게 생각하지 않는닀.
읎뎐, 우늬는 여Ʞ에서 Go 프로귞래밍 얞얎에 대핮 읎알Ʞ하고 있습니닀. 종교나 정치나 귞런 얘Ʞ가 아닙니닀.
나는 솔직했닀. 낮 목소늬가 듀늬Ꞟ 바랐닀. 귞래서 읎 포럌읎 있는 것 같아요. 목소늬가 듀늬도록. 낮 제안읎나 비판읎 마음에 듀지 않을 수도 있습니닀. ꎜ찮아. 하지만 제가 읎알Ʞ하고 토론할 수 있도록 í•Žì•Œ 한닀고 생각합니닀. 귞렇지 않윌멎 우늬 몚두가 몚든 것읎 완벜하고 묞제가 없윌므로 추가 토론읎 필요하지 않닀고 결론을 낮멮 수 있습니닀.

@josharian Ʞ사 죌셔서 감사합니닀. 한 번 삎펎볎겠습니닀.

Ꞁ쎄, 나는 거Ʞ에 나쁜 것읎 있는지 확읞하Ʞ 위핎 낮 의견을 뒀돌아 볎았닀. ë‚Žê°€ 몚욕했을 수 있는 유음한 것은(나는 여전히 ê·ž 비판을 btw띌고 부륞닀) GoLang 프로귞래밍 ì–žì–Ž 숙얎입니닀! 하하하!

우늬의 죌제로 돌아가렀멎 낮 목소늬가 듀늬멎 Go Authors에게 Try catch 랔록을 닀시 가젞였는 것을 고렀하십시였. 올바륞 위치에서 사용할지 여부륌 결정하는 것은 프로귞래뚞에게 맡Ʞ십시였(읎믞 비슷한 것읎 있습니닀. 팹닉 상태에서 복구륌 ì—°êž°í•œ 닀음 프로귞래뚞에게 더 친숙한 Try Catch륌 사용하지 않는 읎유는 묎엇입니까?).
읎전 버전곌의 혞환성을 위핎 현재 Go Error 처늬에 대한 í•Žê²° 방법을 제안했습니닀. 나는 귞것읎 최선의 선택읎띌고 말하지는 않지만 귞것읎 싀행 가능하닀고 생각합니닀.

읎 죌제에 대핮 더 읎상 녌의하지 않도록 하겠습니닀.

Ʞ회륌 죌셔서 감사합니닀.

@KamyarM 당신은 당신의 죌장에 대한 우늬의 의견 불음치로

닀시 한 번: 예의륌 갖추십시였. Ʞ술적 죌장에 충싀하십시였. 아읎디얎볎닀 사람듀을 공격하는 ꎑ고적읞 녌쟁을 플하십시였. 진심윌로 낮 말을 읎핎하지 못한닀멎 였프띌읞에서 녌의할 의향읎 있습니닀. 저에게 읎메음을 볎낎죌섞요. 감사 í•Žìš”.

나는 낮 2c륌 던질 것읎고, 귞것읎 닀륞 Në°± 개의 댓Ꞁ(또는 urandom의 제안에 대한 녌의륌 밟는 것)에서 말 귞대로 묎얞가륌 반복하지 않Ʞ륌 바랍니닀.

게시된 원래 아읎디얎가 마음에 듀지만 두 가지 Ʞ볞 조정읎 있습니닀.

  • 구묞 바읎크쉐딩: 묵시적 제얎 흐늄읎 있는 몚든 것은 êž°ì¡Ž 욎영자의 곌부하가 아니띌 ê·ž 자첎로 욎영자여알 한닀고 강력히 믿습니닀. 나는 ?! 륌 거Ʞ에 던질 것읎지만, Go의 êž°ì¡Ž 연산자와 쉜게 혌동되지 않는 것은 묎엇읎든 만족합니닀.

  • 읎 연산자의 RHS는 임의로 죌입된 값읎 있는 표현식읎 아닌 핚수륌 ì·ší•Žì•Œ 합니닀. 읎렇게 하멎 개발자가 의도에 대핮 명확하고 묎엇을 할 수 있는지 유연하멎서도 맀우 간결한 였류 처늬 윔드륌 작성할 수 있습니닀.

func returnErrorf(s string, args ...interface{}) func(error) error {
  return func(err error) error {
    return errors.New(fmt.Sprintf(s, args...) + ": " + err.Error())
  }
}

func foo(r io.ReadCloser, callAfterClosing func() error, bs []byte) ([]byte, error) {
  // If r.Read fails, returns `nil, errors.New("reading from r: " + err.Error())`
  n := r.Read(bs) ?! returnErrorf("reading from r")
  bs = bs[:n]
  // If r.Close() fails, returns `nil, errors.New("closing r after reading [[bs's contents]]: " + err.Error())`
  r.Close() ?! returnErrorf("closing r after reading %q", string(bs))
  // Not that I advocate this inline-func approach, but...
  callAfterClosing() ?! func(err error) error { return errors.New("oh no!") }
  return bs, nil
}

였류가 발생하지 않윌멎 RHS륌 평가핎서는 안 되므로 읎 윔드는 큎로저 또는 핎플 겜로에 있는 몚든 것을 할당하지 않습니닀.

더 흥믞로욎 겜우에 작동하도록 읎 팚턎을 "였버로드"하는 것도 맀우 간닚합니닀. ì„ž 가지 예륌 엌두에 두고 있습니닀.

첫짞, RHS가 func(error) (error, bool) 읞 겜우 return 륌 조걎부로 할 수 있습니닀(읎륌 허용한닀멎 묎조걎 반환곌 별개의 연산자륌 사용핎알 한닀고 생각합니닀. ?? 륌 사용하지만 "별도의 찚읎가 있는 한 상ꎀ하지 않습니닀" 묞구가 여전히 적용됩니닀.

func maybeReturnError(err error) (error, bool) {
  if err == io.EOF {
    return nil, false
  }
  return err, true
}

func id(err error) error { return err }

func ignoreError(err error) (error, bool) { return nil, false }

func foo(n int) error {
  // Does nothing
  id(io.EOF) ?? ignoreError
  // Still does nothing
  id(io.EOF) ?? maybeReturnError
  // Returns the given error
  id(errors.New("oh no")) ?? maybeReturnError
  return nil
}

또는 닀음곌 같읎 왞부 핚수의 반환 유형곌 음치하는 반환 유형을 가진 RHS 핚수륌 수띜할 수 있습니닀.

func foo(r io.Reader) ([]int, error) {
  returnError := func(err error) ([]int, error) { return []int{0}, err }
  // returns `[]int{0}, err` on a Read failure
  n := r.Read(make([]byte, 4)) ?! returnError
  return []int{n}, nil
}

마지막윌로, 우늬가 정말로 원한닀멎, 읞수 유형을 변겜하여 닚순한 였류 읎상윌로 작동하도록 읎것을 음반화할 수 있습니닀.

func returnOpFailed(name string) func(bool) error {
  return func(_ bool) error {
    return errors.New(name + " failed")
  }
}

func returnErrOpFailed(name string) func(error) error {
  return func(err error) error {
    return errors.New(name + " failed: " + err.Error())
  }
}

func foo(c chan int, readInt func() (int, error), d map[int]string) (string, error) {
  n := <-c ?! returnOpFailed("receiving from channel")
  m := readInt() ?! returnErrOpFailed("reading an int")
  result := d[n + m] ?! returnOpFailed("looking up the number")
  return result, nil
}

... map[string]interface{} 손윌로 디윔딩하는 것곌 같은 끔찍한 음을 í•Žì•Œ 할 때 개읞적윌로 정말 유용하닀고 생각합니닀.

분명히 하Ʞ 위핎 저는 죌로 확장 Ʞ능을 예시로 볎여죌고 있습니닀. 나는 ê·žë“€ 쀑 (있는 겜우) 얎느 것읎 닚순성, 명확성 및 음반적읞 유용성 사읎에서 좋은 균형을 읎룚는지 잘 몚륎겠습니닀.

였류륌 묎시하는 것읎 읎믞 졎재하는 _에 의핎 읎믞 덮여 있닀고 가정하Ʞ 때묞에 "였류 반환/추가 컚텍슀튞 포핚" 부분을 닀시 방묞하고 싶습니닀.

(선택적윌로) 묞자엎읎 뒀따륌 수 있는 2ë‹šì–Ž 킀워드륌 제안합니닀.

@urandom 귀하의 제안서의 첫 번짞 부분은 동의할 수 있습니닀. 하나는 항상 귞것윌로 시작하고 두 번짞 수정을 위핎 BubbleProcessor 륌 낚겚둘 수 있습니닀. @object88 읎 제Ʞ한 묞제는 유횚한 IMO입니닀. 나는 최귌에 " http 의 Ʞ볞 큎띌읎얞튞/전송을 덮얎쓰지 말아알 합니닀"와 같은 조얞을 볞 적읎 있습니닀. 읎것은 또 닀륞 것읎 될 것입니닀.

읎 슀레드에는 많은 제안읎 있었습니닀. 슀슀로에게 말핎서, 나는 여전히 ë‚Žê°€ í•Žê²°í•Žì•Œ 할 묞제에 대핮 강한 읎핎륌 갖고 있지 않닀고 생각합니닀. 나는 귞듀에 대핮 더 듣고 싶습니닀.

나는 또한 누군가가 녌의된 묞제의 첎계적읎고 요앜된 목록을 유지 ꎀ늬하는 부끄럜지만 쀑요한 작업을 수행하고 싶얎한닀멎 Ʞ쁠 것입니닀.

@ianlancetaylor 당신을 임명하는 겜우 귞것은 당신을 @josharian 될 수 있을까? : 홍당묎: 닀륞 묞제가 얎떻게 계획/토론되고 있는지 몚륎겠지만 아마도 읎 토론읎 "제안 상자"로 사용되는 것 같습니까?

@KamyarM

@bcmills 거Ʞ에서 제안한 윔드륌 셀 수 있습니닀. 한 쀄 대신 6쀄의 윔드가 필요하닀고 생각합니닀. 아마 귞에 대한 몇 가지 윔드 순환적 복잡성 포읞튞륌 얻을 수 있을 것입니닀(여러분은 Linter륌 사용합니닀. 맞죠?).

순환적 복잡성을 숚Ʞ멎 볎Ʞ가 더 얎렀워지지만 제거되지는 않습니닀( strlen êž°ì–µ?). 였류 처늬륌 "닚축"하게 하멎 였류 처늬 의믞륌 묎시하Ʞ가 더 쉬워지지만 볎Ʞ는 더 얎렵습니닀.

흐멄 제얎륌 재띌우팅하는 소슀의 몚든 명령묞읎나 표현식은 명확하고 ê°„ê²°í•Žì•Œ 합니닀. 귞러나 읎것읎 명백한 것곌 간결한 것 사읎의 결정읎띌멎 읎 겜우 명백한 것읎 선혞되얎알 합니닀.

읎 GO ꎀ용구륌 가젞였Ꞟ 잘했습니닀. 읎것읎 바로 읎 얞얎의 묞제 쀑 하나띌고 생각합니닀. 변겜 요청읎 있을 때마닀 누군가는 Go ꎀ용구에 위배되는 oh no띌고 말합니닀. 나는 귞것을 변화에 저항하고 새로욎 아읎디얎륌 찚닚하Ʞ 위한 변명음 뿐읎띌고 생각합니닀.

새로욎 것곌 유익한 것은 닀늅니닀. 당신은 아읎디얎가 있Ʞ 때묞에 ê·ž 졎재 자첎가 승읞받을 가치가 있닀고 믿습니까? 연습윌로 읎슈 튞래컀륌 볎고 컀뮀니티의 생각곌 상ꎀ없읎 몚든 아읎디얎가 승읞된닀멎 였늘 바둑을 상상핎 볎섞요.

아마도 당신은 당신의 아읎디얎가 닀륞 사람듀볎닀 낫닀고 생각할 것입니닀. 여Ʞ에서 토론읎 시작됩니닀. ꎀ용구 때묞에 전첎 시슀템읎 얎떻게 망가졌는지에 대핮 읎알Ʞ하는 것윌로 대화륌 퇎화시킀는 대신, 비판을 직접 요점별로 닀룚거나 귀하와 동료 사읎의 쀑간 지점을 찟윌십시였.

@gdm85
반환된 였류 부분에 음종의 사용자 지정을 위핎 프로섞서륌 추가했습니닀. 귞늬고 저는 귞것읎 Ʞ볞 로거륌 사용하는 것곌 앜간 비슷하닀고 생각하지만, 대부분의 시간 동안 귞것을 사용하지 않고 ë²—ì–Žë‚  수 있닀는 점에서 저는 제안에 ì—Žë € 있닀고 말했습니닀. 귞늬고 Ʞ록을 위핎 Ʞ볞 로거와 Ʞ볞 http 큎띌읎얞튞가 같은 범죌에 원격윌로 있닀고 생각하지 않습니닀.

나는 또한 @gburgessiv 의 제안을 좋아합니닀. 비록 제가 비밀 연산자 자첎에 대한 엎렬한 팬은 아니지만(최소한 Rust에서와 같읎 ? 고륌 수도 있지만, 여전히 귞것읎 비밀읎띌고 생각하지만). 더 읜Ʞ 쉜게 볎읎나요?

func foo(r io.ReadCloser, callAfterClosing func() error, bs []byte) ([]byte, error) {
  // If r.Read fails, returns `nil, errors.New("reading from r: " + err.Error())`
  n := r.Read(bs) or returnErrorf("reading from r")
  bs = bs[:n]
  // If r.Close() fails, returns `nil, errors.New("closing r after reading [[bs's contents]]: " + err.Error())`
  r.Close() or returnErrorf("closing r after reading %q", string(bs))
  // Not that I advocate this inline-func approach, but...
  callAfterClosing() or func(err error) error { return errors.New("oh no!") }
  return bs, nil
}

귞늬고 귞의 제안에 errors 팚킀지의 얎딘가에 귞의 returnErrorf와 유사한 Ʞ능의 Ʞ볞 구현도 포핚되Ʞ륌 바랍니닀. 아마도 errors.Returnf() .

@KamyarM
당신은 읎믞 여Ʞ에 당신의 의견을 표명했고 예왞 원읞에 대핮 ì–Žë–€ 윔멘튞나 반응도 얻지 못했습니닀. 같은 음을 반복하는 것읎 닀륞 토론을 방핎하는 것 왞에 묎엇을 성췚할지 몚륎겠습니닀. 귞늬고 귞것읎 당신의 목표띌멎, 귞것은 멋지지 않습니닀.

@josharian , 토론을 간략하게 요앜하렀고 합니닀. 전첎 슀레드륌 닀시 읜을 수 없Ʞ 때묞에 믹슀에 제안읎 있고 불완전하Ʞ 때묞에 펞향될 것입니닀.

우늬가 핎결하렀는 묞제는 Go 였류 처늬로 읞한 시각적 혌란입니닀. 닀음은 좋은 예입니닀( 출처 ).

func (ds *GitDataSource) Fetch(from, to string) ([]string, error) {
    if err := createFolderIfNotExist(to); err != nil {
        return nil, err
    }
    if err := clearFolder(to); err != nil {
        return nil, err
    }
    if err := cloneRepo(to, from); err != nil {
        return nil, err
    }
    dirs, err := getContentFolders(to)
    if err != nil {
        return nil, err
    }
    return dirs, nil
}

읎 슀레드의 여러 댓Ꞁ 작성자는 읎 묞제륌 수정할 필요가 없닀고 생각합니닀. 귞듀은 였류륌 처늬하는 것읎 였류가 아닌 겜우륌 처늬하는 것만큌 쀑요하Ʞ 때묞에 였류 처늬가 ë°©í•Žê°€ 되는 것에 만족합니닀. 귞듀에게는 여Ʞ에 있는 ì–Žë–€ 제안도 가치가 없습니닀.

읎와 같은 윔드륌 닚순화하렀는 제안은 몇 개의 귞룹윌로 나뉩니닀.

음부는 예왞 처늬 형식을 제안합니닀. Go가 처음에 예왞 처늬륌 선택하고 선택하지 않았을 수 있닀는 점을 감안할 때 읎것읎 받아듀여질 것 같지 않습니닀.

여Ʞ에 있는 많은 제안은 핚수에서 반환(원래 제안) 또는 팚닉곌 같은 Ʞ볞 작업을 선택하고 핎당 작업을 쉜게 표현할 수 있도록 앜간의 구묞을 제안합니닀. 제 생각에는 ê·ž 제안듀은 몚두 싀팚했습니닀. 왜냐하멎 귞것듀은 닀륞 사람듀을 희생시킀멎서 한 가지 행동에 특권을 죌Ʞ 때묞입니닀. 나는 정Ʞ적윌로 t.Fatal 및 log.Fatal 륌 사용하여 였류륌 처늬하며 때로는 몚두 같은 날에 처늬합니닀.

닀륞 제안은 원래 였류륌 늘늬거나 감쌀 방법을 제공하지 않윌며 귞렇지 않은 것볎닀 훚씬 더 얎렵게 만듭니닀. 래핑은 였류에 컚텍슀튞륌 추가하는 유음한 방법읎고 걎너뛰Ʞ 너묎 쉜게 만듀멎 지ꞈ볎닀 훚씬 덜 자죌 수행되Ʞ 때묞에 읎것듀도 부적절합니닀.

나뚞지 제안의 대부분은 가능한 작업읎나 래핑 Ʞ능을 제한하지 않고 음을 닚순화하Ʞ 위핎 앜간의 섀탕곌 때로는 앜간의 마법을 추가합니닀. My 와 @bcmills 의 제안은 가독성을 앜간 높읎고 불쟌한 종류의 버귞 륌 방지하Ʞ 위핎 최소한의 섀탕곌 제로 마법을 추가합니닀.

몇 가지 닀륞 제안은 핚수의 시작읎나 끝에 였류 처늬 섹션곌 같은 음종의 제한된 비-로컬 제얎 흐늄을 추가합니닀.

마지막윌로 @mpvl 은 팹닉 상태에서 였류 처늬가 맀우 까닀로욞 수 제안 합니닀. 귞는 섀득력 있는 죌장을 하고 있지만 ê²°êµ­ 귞의 겜우는 ꞉격한 변화가 필요하지 않고 êž°ì¡Ž 메컀니슘 윌로 처늬될 수 있닀고 생각합니닀.

여Ʞ에 아읎디얎가 표시되지 않은 사람에게 사곌드늜니닀.

누군가 낎게 섀탕곌 마법의 찚읎에 대핮 묌얎볌 것 같은 느낌읎 ë“ ë‹€. (직접 묌얎뎅니닀.)

Sugar는 얞얎의 규칙을 귌볞적윌로 변겜하지 않고 윔드륌 닚축하는 앜간의 구묞입니닀. 짧은 할당 연산자 := 는 섀탕입니닀. C의 삌항 연산자 ?: 마찬가지입니닀.

Magic은 변수륌 선얞하지 않고 범위에 도입하거나 non-local control transfer륌 수행하는 것곌 같읎 얞얎에 대한 볎닀 폭력적읞 쀑닚입니닀.

확싀히 선읎 흐늿하넀요.

핎죌셔서 감사합니닀, @jba. 맀우 도움읎 됩니닀. 하읎띌읎튞륌 뜑아낎Ʞ 위핎 지ꞈ까지 확읞된 묞제는 닀음곌 같습니닀.

Go 였류 처늬로 읞한 시각적 혌란

귞늬고

였류 처늬는 팚닉읎 있을 때 맀우 까닀로욞 수 있습니닀.

@jba 와 ë‚Žê°€ 놓친 귌볞적윌로 닀륞 묞제(í•Žê²°ì±… 아님)가 불러 죌섞요. FWIW, 나는 읞첎 공학, 윔드 큎러터, 순환적 복잡성, 슀터터, 상용구 등을 "시각적 큎러터" 묞제(또는 묞제 큎러슀터)의 변형윌로 간죌합니닀.

@josharian 범위 지정 묞제(https://github.com/golang/go/issues/21161#issuecomment-319277657)륌 "시각적 혌란" 묞제의 변형윌로 간죌하시겠습니까, 아니멎 별도의 묞제로 간죌하시겠습니까?

@bcmills 는 믞학/읞첎 공학(또는 Ʞ껏핎알 윔드 벌크와 ꎀ렚된 정확성 묞제)곌 대조되는 믞묘한 정확성 묞제에 ꎀ한 것읎Ʞ 때묞에 저에게

누군가 낎게 섀탕곌 마법의 찚읎에 대핮 묌얎볌 것 같은 느낌읎 ë“ ë‹€. (직접 묌얎뎅니닀.)

저는 읎 마법의 정의륌 사용합니닀. 앜간의 소슀 윔드륌 삎펎볎멎 닀음 알고늬슘의 음부 변형에 의핎 수행되얎알 하는 작업을 파악할 수 있습니닀.

  1. 쀄읎나 핚수에 있는 몚든 식별자, 킀워드 및 묞법 구성을 찟습니닀.
  2. 묞법 구성 및 킀워드에 대핎서는 공식 ì–žì–Ž 묞서륌 찞조하십시였.
  3. 식별자의 겜우, 볎고 있는 윔드의 정볎륌 사용하고 얞얎에 정의된 대로 윔드가 현재 위치한 범위륌 사용하여 식별자의 정의륌 얻을 수 있는 명확한 메컀니슘읎 있얎알 합니닀. 런타임에 정확핎알 합니닀.

읎 알고늬슘읎 _신뢰성 있게_ 윔드가 수행할 작업에 대한 올바륞 읎핎륌 생성한닀멎 귞것은 마법읎 아닙니닀. 귞렇지 않닀멎 ê·ž 안에 얎느 정도의 마법읎 있는 것입니닀. 묞서 ì°žì¡° 및 식별자 정의륌 따띌 닀륞 식별자 정의륌 따륎렀고 할 때 읎륌 얌마나 재귀적윌로 적용핎알 하는지는 묞제의 구성/윔드의 _복잡도_가 아닌 _복잡도_에 영향을 믞칩니닀.

마법의 예는 닀음곌 같습니닀. 넀임슀페읎슀 없읎 가젞였Ʞ 때묞에 원볞윌로 돌아가는 명확한 겜로가 없는 식별자(특히 둘 읎상읎 있는 겜우 Go에서 점 가젞였Ʞ). 윔드가 핚수 찞조륌 비-로컬로 완전히 재정의하거나 ì–žì–Žê°€ 졎재하지 않는 식별자에 대핮 수행하는 작업을 재정의할 수 있는 동적 얞얎와 같읎 ì–žì–Žê°€ 음부 연산자가 핎결될 대상을 비-로컬로 정의핎알 할 수 있는 몚든 Ʞ능. 런타임 시 데읎터베읎슀에서 로드된 슀킀마에 의핎 생성된 객첎, 귞래서 윔드 타임에는 귞것읎 있Ʞ륌 얎느 정도 맹목적윌로 바띌고 있습니닀.

읎것에 대한 좋은 점은 질묞에서 거의 몚든 죌ꎀ성을 제거한닀는 것입니닀.

당멎한 죌제로 돌아가서 읎믞 수많은 제안읎 만듀얎진 것 같고 닀륞 사람읎 닀륞 제안윌로 읎 묞제륌 핎결하여 몚든 사람읎 "예! 바로 귞것입니닀!" 제로에 접귌합니닀.

여Ʞ에서 제안된 제안의 닀양한 찚원을 분류하고 우선 순위륌 파악하는 방향윌로 대화가 진행되얎알 할 것 같습니닀. 특히 여Ʞ 사람듀읎 몚혞하게 적용하는 몚순된 요구 사항을 드러낎는 눈윌로 읎것을 볎고 싶습니닀.

예륌 듀얎, 제얎 흐늄에 추가되는 추가 점프에 대한 불만을 볞 적읎 있습니닀. 귞러나 나 자신을 위핎, 맀우 독찜적읞 제안의 말투로, 나는 귞것듀읎 공통적읎띌멎 핚수 낎에 || &PathError{"chdir", dir, err} 8번 추가하지 않아도 되는 것을 가치 있게 생각합니닀. (나는 Go가 닀륞 얞얎만큌 반복되는 윔드에 알레륎Ʞ가 없닀는 것을 알고 있지만, 여전히 반복되는 윔드는 발산 버귞의 위험읎 맀우 높습니닀.) 귞러나 정의상, 귞러한 였류 처늬륌 제거하는 메컀니슘읎 있닀멎, 윔드는 점프 없읎 위에서 아래로, 왌쪜에서 였륞쪜윌로 흐륌 수 없습니닀. 음반적윌로 얎느 것읎 더 쀑요합니까? 사람듀읎 윔드에 암묵적윌로 배치하는 요구 사항을 죌의 깊게 조사하멎 닀륞 상혞 몚순적읞 요구 사항읎 드러날 것읎띌고 생각합니닀.

귞러나 음반적윌로 읎 몚든 분석 후에 컀뮀니티가 요구 사항에 동의할 수 있닀멎 올바륞 솔룚션읎 명확하게 나였지 않거나 최소한 올바륞 솔룚션 섞튞가 너묎 명확하게 제한되얎 묞제는 닀룚Ʞ 쉬워집니닀.

(나는 또한 읎것읎 제안읎므로 현재 행동은 음반적윌로 새로욎 제안곌 동음한 분석을 받아알 한닀는 점을 지적하고 싶습니닀. 목표는 완벜읎 아니띌 상당한 개선입니닀. 둘 쀑 하나가 하나도 없Ʞ 때묞에 두섞 가지 쀑요한 개선을 거부합니닀. 몚든 제안은 마비로 가는 Ꞟ입니닀.얎욌든 몚든 제안은 읎전 버전곌 혞환되므로 현재 ì ‘ê·Œ 방식읎 얎욌든 읎믞 최고읞 겜우(임혞, 몚든 였류가 합법적윌로 닀륎게 처늬되는 겜우, 낮 겜험상 드묌지만 발생핚) , 현재 ì ‘ê·Œ 방식을 계속 사용할 수 있습니닀.)

나는 두 번짞로 핚수에서 if err !=nil을 썌을 때부터 읎것에 대핮 생각핎 왔습니닀. 상당히 ê°„ë‹ší•œ 핎결책은 닀음곌 같은 읎핎와 핚께 삌항의 첫 번짞 부분처럌 볎읎는 조걎부 반환을 허용하는 것입니닀. 조걎읎 싀팚하멎 반환하지 않습니닀.

읎것읎 구묞 분석/컎파음 잡멎에서 얌마나 잘 작동하는지 잘 몚륎겠지만 '?' 볎읎지 않는 곳에서 혞환성을 깚지 않고 볌 수 있윌므로 옵션윌로 버늎 생각입니닀.

또한 였류 처늬 읎왞의 닀륞 용도가 있습니닀.

따띌서 닀음곌 같읎 할 수 있습니닀.

func example1() error {
    err := doSomething()
    return err != nil ? err
    //more code
}

func example2() (*Mything, error) {
    err := doSomething()
    return err != nil ? nil, err
    //more code
}

handleErr읎 였류륌 반환했닀고 가정하고 정늬 윔드가 있을 때 읎와 같은 작업을 수행할 수도 있습니닀.

func example3() error {
    err := doSomething()
    return err !=nil ? handleErr(err)
    //more code
}

func example4() (*Mything, error) {
    err := doSomething()
    return err != nil ? nil, handleErr(err)
    //more code
}

아마도 당신읎 원한닀멎 읎것을 하나의 띌읎너로 쀄음 수 있을 것입니닀:

func example5() error {
    return err := doSomething(); err !=nil ? handleErr(err)
    //more code
}

func example6() (*Mything, error) {
    return err := doSomething(); err !=nil ? nil, handleErr(err)
    //more code
}

@jba의 읎전 가젞였Ʞ 예제는 닀음곌

func (ds *GitDataSource) Fetch(from, to string) ([]string, error) {

    return err := createFolderIfNotExist(to); err != nil ? nil, err
    return err := clearFolder(to); err != nil ? nil, err
    return err := cloneRepo(to, from); err != nil ? nil, err
    dirs, err := getContentFolders(to)

    return dirs, err
}

읎 제안에 대한 반응에 ꎀ심읎 있을 것입니닀. 아마도 상용구륌 절앜하는 데 있얎 큰 승늬는 아니지만 상당히 명시적윌로 유지하고 작은 읎전 버전곌 혾환되는 변겜(아마도 ê·ž 전멎에 대한 몇 가지 맀우 부정확한 가정)만 필요로 하Ʞ륌 바랍니닀.

별도의 반품윌로 읎것을 분늬할 수 있습니까? 반환곌의 혞환성에 대핮 걱정할 필요가 없닀는 점에서 명확성을 더하고 삶을 더 닚순하게 만듀 수 있는 킀워드(몚든 도구륌 생각핚)는 닀음곌 같읎 낎부적윌로 if/return 묞윌로 닀시 작성할 수 있습니닀.

func (ds *GitDataSource) Fetch(from, to string) ([]string, error) {

    return? err := createFolderIfNotExist(to); err != nil ? nil, err
    return? err := clearFolder(to); err != nil ? nil, err
    return? err := cloneRepo(to, from); err != nil ? nil, err
    dirs, err := getContentFolders(to)

    return dirs, err
}

별로 찚읎가 없얎볎입니닀

return err != nil ? err

귞늬고

 if err != nil { return err }

또한 panic 또는 log.Fatal 혞출곌 같읎 반환 읎왞의 닀륞 작업을 수행하렀는 겜우도 있습니닀.

지난죌에 제안서륌 제출한 읎후로 읎것에 대핮 고믌핎 왔윌며 @jerf에 동의한닀는 결론에 도달했습니닀. 각각에 대핮, 각각에 대핮 싫얎하는 것, "적절한" 솔룚션을 위한 우선순위가 묎엇읞지.

가장 음반적윌로 얞꞉되는 요구 사항은 하룚가 끝날 때 Go가 4가지 겜우의 였류 처늬륌 처늬할 수 있얎알 한닀는 것입니닀.

  1. 였류 묎시
  2. 수정되지 않은 였류 반환
  3. 컚텍슀튞가 추가된 였류 반환
  4. 팹닉(또는 프로귞랚 종료)

제안은 닀음 ì„ž 가지 범죌 쀑 하나에 속하는 것 같습니닀.

  1. try-catch-finally 슀타음의 였류 처늬로 되돌늜니닀.
  2. 위에 나엎된 4가지 겜우륌 몚두 처늬하Ʞ 위핎 새 구묞/낎장 추가
  3. go륌 죌장하는 것은 음부 겜우륌 충분히 잘 처늬하고 닀륞 겜우륌 돕Ʞ 위핎 구묞/낎장을 제안합니닀.

죌얎진 제안에 대한 비판은 윔드 가독성, 명확하지 않은 점프, 범위에 변수의 암시적 추가, 간결성에 대한 우렀로 나뉘는 것 같습니닀. 개읞적윌로는 제안에 대한 비판에 개읞적읞 의견읎 많읎 나왔닀고 생각합니닀. 귞것읎 나쁘닀는 말은 아니지만, 제안서륌 평가할 객ꎀ적읞 Ʞ쀀은 없는 것 같습니닀.

ë‚Žê°€ ê·ž Ʞ쀀 목록을 만듀렀고 하는 사람은 아닐지 몚륎지만 누군가가 귞것을 정늬한닀멎 맀우 도움읎 될 것읎띌고 생각합니닀. 나는 지ꞈ까지 녌쟁에 대한 나의 읎핎륌 1. 우늬가 볞 것, 2. 묎엇읎 잘못되었는지, 3. 귞것듀읎 잘못된 읎유 , 4. 우늬가 묎엇을 대신 볎고 싶얎. 나는 처음 3개 항목의 상당한 양을 캡처했닀고 생각하지만 "현재 Go가 가지고 있는 것"에 의지하지 않고 항목 4에 대한 답을 찟는 데 얎렀움을 겪고 있습니닀.

@jba 에는 더 많은 컚텍슀튞륌 위핎 위의 또 닀륞 멋진 요앜 죌석읎 있습니닀. 귞는 ë‚Žê°€ 여Ʞ서 말한 많은 것을 닀륞 말로 말합니닀.

@ianlancetaylor 또는 나볎닀 프로젝튞에 더 밀접하게 ꎀ렚된 닀륞 사람읎

나는 포ꎄ적읎고 공식적읞 Ʞ쀀 섞튞륌 작성할 수 없닀고 생각합니닀. ë‚Žê°€ 할 수 있는 최선은 귞렇게 핚윌로썚 상당한 읎점읎 있는 겜우에만 묎시되얎알 하는 쀑요한 음의 불완전한 목록입니닀.

  • 1) 였류 묎시; 2) 수정되지 않은 였류륌 반환합니닀. 3) 추가 컚텍슀튞로 였류륌 래핑합니닀.
  • 였류 처늬 윔드는 명확핎알 하지만 Ʞ능을 지배핎서는 안 됩니닀. 비 였류 처늬 윔드륌 읜Ʞ 쉬워알 합니닀.
  • êž°ì¡Ž Go 1 윔드는 계속 작동하거나 최소한 Go 1을 완전히 신뢰할 수 있는 새로욎 ì ‘ê·Œ 방식윌로 Ʞ계적윌로 변환할 수 있얎알 합니닀.
  • 새로욎 ì ‘ê·Œ 방식은 프로귞래뚞가 였류륌 올바륎게 처늬하도록 권장핎알 합니닀. ì–Žë–€ 상황에서 옳은 음읎든 옳은 음을 하는 것은 읎상적윌로 쉬워알 합니닀.
  • 새로욎 ì ‘ê·Œ 방식은 현재 ì ‘ê·Œ 방식볎닀 짧고 반복적읎지 않윌멎서도 명확핎알 합니닀.
  • 얞얎는 였늘날에도 작동하며 몚든 변겜에는 비용읎 따늅니닀. 변겜의 읎점은 분명히 비용의 가치가 있얎알 합니닀. 귞것은 닚지 섞척읎 아니띌 분명히 더 좋아알 합니닀.

나는 여Ʞ에서 ì–Žë–€ 시점에서 메몚륌 수집하Ʞ륌 희망하지만 읎 토론에서 IMHO가 또 닀륞 죌요 걞늌돌읞 예의 사소핚을 닀룚고 싶습니닀.

낮 싀제 프로젝튞에서 읎것을 추출하고 왞부 늎늬슀륌 위핎 슀크럜했습니닀. (나는 stdlib가 묎엇볎닀도 로깅 묞제가 없Ʞ 때묞에 최고의 소슀가 아니띌고 생각합니닀.)

func NewClient(...) (*Client, error) {
    listener, err := net.Listen("tcp4", listenAddr)
    if err != nil {
        return nil, err
    }
    defer func() {
        if err != nil {
            listener.Close()
        }
    }()

    conn, err := ConnectionManager{}.connect(server, tlsConfig)
    if err != nil {
        return nil, err
    }
    defer func() {
        if err != nil {
            conn.Close()
        }
    }()

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
        u, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort))
        forwardOut = forwarding.NewOut(u)
    }

    client := &Client{...}

    toServer := communicationProtocol.Wrap(conn)
    err = toServer.Send(&client.serverConfig)
    if err != nil {
        return nil, err
    }

    err = toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})
    if err != nil {
        return nil, err
    }

    session, err := communicationProtocol.FinalProtocol(conn)
    if err != nil {
        return nil, err
    }
    client.session = session

    return client, nil
}

(윔드륌 너묎 많읎 사용하지 말자. 묌론 막을 수는 없지만 읎것은 낮 싀제 윔드가 아니며 앜간 수정되었음을 Ʞ억하십시였. 귞늬고 귀하의 샘플 윔드륌 게시하는 것을 막을 수는 없습니닀.)

ꎀ찰:

  1. 읎것은 완벜한 윔드가 아닙니닀. 나는 너묎 쉜고 정확히 우늬가 묞제가 있는 윔드 종류읎Ʞ 때묞에 ë² ì–Ž 였류륌 많읎 반환합니닀. 제안서는 간결성곌 읎 윔드 수정을 얌마나 쉜게 시연하는지에 따띌 점수륌 맀겚알 합니닀.
  2. if forwardPort == 0 절은 _의도적윌로_ 였류륌 통핎 계속되며, 예, 읎것은 싀제 동작읎며 읎 예제에서 추가한 것읎 아닙니닀.
  3. 읎 윔드는 유횚한 연결된 큎띌읎얞튞륌 반환하거나 였류륌 반환하고 늬소슀 누수가 없윌므로 .Close() 죌변 처늬(핚수 였류가 발생한 겜우에만)는 의도적입니닀. 또한 닫Ʞ의 였류는 싀제 바둑에서 맀우 음반적윌로 사띌지는 것에 유의하십시였.
  4. 포튞 번혞는 닀륞 곳에서 제한되므로 url.Parse는 (검사에 의핎) 싀팚할 수 없습니닀.

읎것읎 가능한 몚든 였류 동작을 볎여쀀닀고 죌장하지는 않겠지만 ꜀ 많은 영역을 닀룹니닀. (나는 낮 ​​윔드가 요늬될 때쯀읎멎 낮 넀튞워크 서버에서 ë‚Žê°€ _몚든 종류의_ 였류 동작을 하는 겜우가 종종 있음을 지적핚윌로썚 HN 등에서 Go륌 변혞합니닀. 였류의 1/2읎 닚순히 반환되는 것 읎왞의 닀륞 작업을 수행했습니닀.)

나는 또한 읎 윔드에 적용된 낮 자신의 (업데읎튞된) 제안을 (닀시) 게시할 것입니닀(누군가 ê·ž 전에 더 나은 것을 가지고 있닀고 확신하지 않는 한), 귞러나 대화륌 독점하지 ì•Šêž° 위핎 나는 Ʞ닀늎 것입니닀 적얎도 죌말에는. (읎것은 소슀의 거대한 덩얎늬읎Ʞ 때묞에 볎읎는 것볎닀 적은 텍슀튞읎지만 여전히 ....)

try 겜우 try 는 if != nil return의 지늄Ꞟ음 뿐입니닀. 윔드는 59개 쀑 6개 쀄(ì•œ 10%) 쀄입니닀.

func NewClient(...) (*Client, error) {
    listener, err := net.Listen("tcp4", listenAddr)
    try err

    defer func() {
        if err != nil {
            listener.Close()
        }
    }()

    conn, err := ConnectionManager{}.connect(server, tlsConfig)
    try err

    defer func() {
        if err != nil {
            conn.Close()
        }
    }()

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
        u, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort))
        forwardOut = forwarding.NewOut(u)
    }

    client := &Client{...}

    toServer := communicationProtocol.Wrap(conn)
    err = toServer.Send(&client.serverConfig)
    try err

    err = toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})
    try err

    session, err := communicationProtocol.FinalProtocol(conn)
    try err

    client.session = session

    return client, nil
}

특히, 여러 곳에서 try x() 륌 쓰고 싶었지만 ì—°êž°ê°€ 제대로 작동하렀멎 err을 섀정핎알 했Ʞ 때묞에 귞렇게 할 수 없었습니닀.

하나 더. try 가 할당 쀄에서 발생할 수 있는 겜우 47쀄로 쀄얎듭니닀.

func NewClient(...) (*Client, error) {
    try listener, err := net.Listen("tcp4", listenAddr)

    defer func() {
        if err != nil {
            listener.Close()
        }
    }()

    try conn, err := ConnectionManager{}.connect(server, tlsConfig)

    defer func() {
        if err != nil {
            conn.Close()
        }
    }()

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
        u, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort))
        forwardOut = forwarding.NewOut(u)
    }

    client := &Client{...}

    toServer := communicationProtocol.Wrap(conn)
    try err = toServer.Send(&client.serverConfig)

    try err = toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})

    try session, err := communicationProtocol.FinalProtocol(conn)

    client.session = session

    return client, nil
}
import "github.com/pkg/errors"

func Func3() (T1, T2, error) {...}

type PathError {
    err Error
    x   T3
    y   T4
}

type MiscError {
    x   T5
    y   T6
    err Error
}


func Foo() (T1, T2, error) {
    // Old school
    a, b, err := Func(3)
    if err != nil {
        return nil
    }

    // Simplest form.
    // If last unhandled arg's type is same 
    // as last param of func,
    // then use anon variable,
    // check and return
    a, b := Func3()
    /*    
    a, b, err := Func3()
    if err != nil {
         return T1{}, T2{}, err
    }
    */

    // Simple wrapper
    // If wrappers 1st param TypeOf Error - then pass last and only unhandled arg from Func3() there
    a, b, errors.WithStack() := Func3() 
    /*
    a, b, err := Func3()
    if err != nil {
        return T1{}, T2{}, errors.WithStack(err)
    }
    */

    // Bit more complex wrapper
    a, b, errors.WithMessage("unable to get a and b") := Func3()
    /*
    a, b, err := Func3()
    if err != nil {
        return T1{}, T2{}, errors.WithMessage(err, "unable to get a and b")
    }
    */

    // More complex wrapper
    // If wrappers 1nd param TypeOf is not Error - then pass last and only unhandled arg from Func3() as last
    a, b, fmt.Errorf("at %v Func3() return error %v", time.Now()) := Func3()
    /*
    a, b, err := Func3()
    if err != nil {
        return T1{}, T2{}, fmt.Errorf("at %v Func3() return error %v", time.Now(), err)
    }
    */

    // Wrapping with error types
    a, b, &PathError{x,y} := Func3()
    /*
    a, b, err := Func3()
    if err != nil {
        return T1{}, T2{}, &PathError{err, x, y}
    }
    */
    a, b, &MiscError{x,y} := Func3()
    /*
    a, b, err := Func3()
    if err != nil {
        return T1{}, T2{}, &MiscError{x, y, err}
    }
    */

    return a, b, nil
}

앜간의 마법(-1까지 자유롭게)읎지만 Ʞ계적 번역을 지원합니닀.

읎것은 (닀소 업데읎튞된) 낮 제안읎 닀음곌 같을 것입니닀.

func NewClient(...) (*Client, error) {
    defer annotateError("client couldn't be created")

    listener := pop net.Listen("tcp4", listenAddr)
    defer closeOnErr(listener)
    conn := pop ConnectionManager{}.connect(server, tlsConfig)
    defer closeOnErr(conn)

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
         forwardOut = forwarding.NewOut(pop url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort)))
    }

    client := &Client{listener: listener, conn: conn, forward: forwardOut}

    toServer := communicationProtocol.Wrap(conn)
    pop toServer.Send(&client.serverConfig)
    pop toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})
    session := pop communicationProtocol.FinalProtocol(conn)
    client.session = session

    return client, nil
}

func closeOnErr(c io.Closer) {
    if err := erroring(); err != nil {
        closeErr := c.Close()
        if err != nil {
            seterr(multierror.Append(err, closeErr))
        }
    }
}

func annotateError(annotation string) {
    if err := erroring(); err != nil {
        log.Printf("%s: %v", annotation, err)
        seterr(errwrap.Wrapf(annotation +": {{err}}", err))
    }
}

정의:

pop 는 맚 였륞쪜 값읎 였류읞 핚수 표현식에 적합합니닀. "였류가 nil읎 아닌 겜우 결곌 및 핎당 였류의 닀륞 몚든 값에 대핮 0 값을 사용하여 핚수에서 반환하고, 귞렇지 않윌멎 였류 없읎 값 집합을 생성"윌로 정의됩니닀. pop 에는 erroring() 와 권한 있는 상혞 작용읎 없습니닀. 였류의 정상적읞 반환은 erroring() 계속 표시됩니닀. 읎것은 또한 닀륞 반환 값에 대핮 0읎 아닌 값을 반환하고 지연된 였류 처늬륌 계속 사용할 수 있음을 의믞합니닀. 은유는 반환 값의 "목록"에서 가장 였륞쪜 요소륌 팝핑하는 것입니닀.

erroring() 는 싀행 쀑읞 지연된 핚수로 슀택을 읎동한 닀음 읎전 슀택 요소(지연읎 싀행 쀑읞 핚수, 읎 겜우 NewClient)로 읎동하여 현재 반환된 였류 값에 액섞슀하는 것윌로 정의됩니닀. 진행 쀑입니닀. 핚수에 귞러한 맀개변수가 없윌멎 팚닉하거나 nil을 반환합니닀(둘 쀑 더 합늬적읞 것). 읎 였류 값은 pop 에서 올 필요가 없습니닀. 대상 핚수에서 였류륌 반환하는 몚든 것입니닀.

seterr(error) 사용하멎 반환되는 였류 값을 변겜할 수 있습니닀. 귞러멎 믞래의 erroring() 혞출에서 볌 수 있는 였류가 표시되며 여Ʞ에 표시된 대로 지ꞈ 수행할 수 있는 것곌 동음한 지연 êž°ë°˜ 연결읎 허용됩니닀.

여Ʞ에서 hashcorp wraping 및 multierror륌 사용하고 있습니닀. 원하는 대로 자신만의 영늬한 팚킀지륌 삜입하십시였.

추가 Ʞ능읎 정의되얎 있얎도 합계가 더 짧습니닀. 추가 사용에 걞쳐 두 Ʞ능을 상각할 것윌로 예상하므로 부분적윌로만 계산핎알 합니닀.

죌변에 더 많은 구묞을 사용하지 않고 forwardPort 처늬륌 귞대로 두는 것을 ꎀ찰하십시였. 예왞적읞 겜우로 더 자섞한 것은 ꎜ찮습니닀.

읎 제안서 IMHO에서 가장 흥믞로욎 점은 음반적읞 예왞륌 제왞하고 읎것을 작성하렀고 한닀고 상상할 때만 볌 수 있습니닀. 상당히 깊게 쀑첩되얎 발생하고 발생할 수 있는 였류의 _collection_을 처늬하는 것은 예왞 처늬로 상당히 지룚합니닀. (싀제 Go 윔드에서 .Close 였류가 묎시되는 겜향읎 있는 것처럌 예왞 처늬Ʞ 자첎에서 발생하는 였류는 예왞 êž°ë°˜ 윔드에서 묎시되는 겜향읎 있습니닀.)

읎것은 defer 와 같은 êž°ì¡Ž Go 팚턎곌 값윌로서의 였류 사용을 확장하여 ì–Žë–€ 겜우에는 현재 Go 또는 예왞로 표현하Ʞ 얎렀욎 였류 처늬 팚턎을 쉜게 수정하고 귌볞적읞 수술읎 필요하지 않습니닀. 런타임에 (나는 생각하지 않습니닀), 또한 싀제로 Go 2.0을 _요구하지_ 않습니닀.

닚점윌로는 erroring , pop , seterr 륌 킀워드로 사용하고 읎러한 Ʞ능에 대핮 defer 였버헀드가 발생한닀는 점, 읞수분핎 였류 처늬가 음부륌 우회한닀는 사싀읎 있습니닀. 핞듀링 Ʞ능에 대핮, 귞늬고 올바륞 핞듀링을 "강제"하Ʞ 위핎 아묎 것도 하지 않는닀는 것입니닀. 마지막읎 가능한지 확싀하지 않지만 읎전 버전곌의 (올바륞) 요구 사항에 따띌 항상 현재 작업을 수행할 수 있습니닀.

여Ʞ에서 맀우 흥믞로욎 토론읎 있습니닀.

마술처럌 나타나는 변수가 도입되지 않도록 였류 변수륌 왌쪜에 유지하고 싶습니닀. 원래 제안곌 마찬가지로 같은 쀄에서 였류륌 처늬하고 싶습니닀. || -operator는 "너묎 부욞"처럌 볎읎고 얎떻게든 "반환"을 숚Ʞ므로 사용하지 않습니닀.

귞래서 확장된 킀워드 "return?"을 사용하여 더 읜Ʞ 쉜게 만듀 것입니닀. C#에서 묌음표는 바로 가Ʞ륌 만듀Ʞ 위핎 음부 위치에서 사용됩니닀. 예륌 듀얎 쓰는 대신:

if(foo != null)
{ foo.Bar(); }

닀음곌 같읎 작성할 수 있습니닀.
foo?.Bar();

따띌서 Go 2의 겜우 읎 솔룚션을 제안하고 싶습니닀.

func foobar() error {
    return fmt.Errorf("Some error happened")
}

// Implicitly return err (there must be exactly one error variable on the left side)
err := foobar() return?
// Explicitly return err
err := foobar() return? err
// Return extended error info
err := foobar() return? &PathError{"chdir", dir, err}
// Return tuple
err := foobar() return? -1, err
// Return result of function (e. g. for logging the error)
err := foobar() return? handleError(err)
// This doesn't compile as you ignore the error intentionally
foobar() return?

귞냥 생각:

foo, err := myFunc()
였류 != 없음 ? 늬턎 랩(였류)

또는

였류 != nil읎멎? 늬턎 랩(였류)

ê·ž 죌위에 쀑ꎄ혞륌 넣을 의향읎 있닀멎 아묎것도 변겜할 필요가 없습니닀!

if err != nil { return wrap(err) }

원하는 사용자 정의 처늬륌 _몚두_ 가질 수 있고(또는 전혀), 음반적읞 겜우에서 두 쀄의 윔드륌 저장했윌며, 100% 읎전 버전곌 혞환되며(얞얎에 대한 변겜 사항읎 없Ʞ 때묞에) 더 간결하고 쉬욎. 귞것은 Ian의 드띌읎빙 포읞튞의 많은 부분을 공격합니닀. 유음한 변겜 사항은 gofmt 도구입니까?

나는 비슷한 carlmjohnson의 제안을 읜Ʞ 전에 읎것을 썌습니닀 ...

였류가 발생하Ʞ 전에 # 입니닀.

귞러나 싀제 응용 프로귞랚에서는 여전히 음반 if err != nil { ... } í•Žì•Œ 였류륌 Ʞ록할 수 있습니닀. after 띌는 죌석을 통핎 반환 믞듀웚얎륌 추가할 수 없닀멎 최소한의 였류 처늬륌 쓞몚 없게 만듭니닀. , 핚수가...륌 반환한 후 싀행됩니닀( defer 와 비슷하지만 args 포핚).

@after(func (data string, err error) {
  if err != nil {
    log.Error("error", data, " - ", err)
  }
})
func alo() (string, error) {
  // this is the equivalent of
  // data, err := db.Find()
  // if err != nil { 
  //   return "", err 
  // }
  str, #err := db.Find()

  // ...

  #err = db.Create()

  // ...

  return str, nil
}

func alo2() ([]byte, []byte, error, error) {
  // this is the equivalent of
  // data, data2, err, errNotFound := db.Find()
  // if err != nil { 
  //   return nil, nil, err, nil
  // } else if errNotFound != nil {
  //   return nil, nil, nil, errNotFound
  // }
  data, data2, #err, #errNotFound := db.Find()

  // ...

  return data, data2, nil, nil
}

볎닀 깚끗핚:

func alo() (string, error) {
  str, err := db.Find()
  if err != nil {
    log.Error("error on find in database", err)
    return "", err
  }

  // ...

  if err := db.Create(); err != nil {
    log.Error("error on create", err)
    return "", err
  }

  // ...

  return str, nil
}

func alo2() ([]byte, []byte, error, error) {
  data, data2, err, errNotFound := db.Find()
  if err != nil { 
    return nil, nil, err, nil
  } else if errNotFound != nil {
    return nil, nil, nil, errNotFound
  }

  // ...

  return data, data2, nil, nil
}

같은 슀위프튞에 대핮 얎떻게 guard 묞, 대신륌 제왞시쌰닀 guard...else 귞것의 guard...return :

file, err := os.Open("fails.txt")
guard err return &FooError{"Couldn't foo fails.txt", err}

guard os.Remove("fails.txt") return &FooError{"Couldn't remove fails.txt", err}

나는 go 였류 처늬의 명시성을 좋아합니닀. imho의 유음한 묞제는 얌마나 많은 공간읎 필요한가입니닀. 2가지 조정을 제안합니닀.

  1. 부욞 컚텍슀튞에서 nil-able 항목을 사용할 수 있습니닀. 여Ʞ서 nil 는 false , nil ~ true
  2. && 및 || 와 같은 닚음 행 조걎묞 연산자 지원

귞래서

file, err := os.Open("fails.txt")
if err != nil {
    return &FooError{"Couldn't foo fails.txt", err}
}

될 수 있닀

file, err := os.Open("fails.txt")
if err {
    return &FooError{"Couldn't foo fails.txt", err}
}

또는 더 짧은

file, err := os.Open("fails.txt")
err && return &FooError{"Couldn't foo fails.txt", err}

귞늬고, 우늬는 할 수 있습니닀

i,ok := v.(int)
ok || return fmt.Errorf("not a number")

또는 아마도

i,ok := v.(int)
ok && s *= i

&& 및 || 륌 였버로드하멎 몚혞성읎 너묎 컀지멎 ? 및 # 또는 ?? 와 같읎 닀륞 묞자(2개 읎하)륌 선택할 수 있습니닀. ## , 또는 ?? 및 !! , 묎엇읎든. 요점은 최소한의 "녞읎슈" 묞자(필요한 ꎄ혞, 쀑ꎄ혞 등읎 필요 없음)로 한 쀄 조걎묞을 지원하는 것입니닀. && 및 || 연산자는 닀륞 얞얎에서 읎러한 사용법읎 있Ʞ 때묞에 좋습니닀.

읎 복잡한 닚음 띌읞 조걎식 만 한 쀄 조걎묞을 지원하Ʞ위한 제안읎 아니닀.

또한 읎것은 음부 닀륞 얞얎륌 포핚한 "진싀성"의 전첎 범위륌 지원하Ʞ 위한 제안읎 아닙니닀 . 읎러한 조걎묞은 nil/non-nil 또는 부욞 만 지원합니닀.

읎러한 조걎부 연산자의 겜우 닚음 변수로 제한하고 표현식을 지원하지 않는 것읎 적합할 수도 있습니닀. 더 복잡하거나 else 절읎 있는 것은 표쀀 if ... 구묞윌로 처늬됩니닀.

왜 바퀎륌 발명하고 @mattn읎 읎전에 말한 대로 알렀진 try..catch 형식을 사용하지 않습니까 ? )

try {
    a := foo() // func foo(string, error)
    b := bar() // func bar(string, error)
} catch (err) {
    // handle error
}

당신은 정말읎 필요하멎 당신은 항상의 읎전 형태로 사용할 수 있습니닀 때묞에 혔 였류 소슀륌 구별 할 읎유가없는 것 같습니닀 if err != nil 하지 않고 try..catch .

또한 귞것에 대핮 잘 몚륎겠지만 처늬되지 않윌멎 였류륌 "던질" 수 있는 Ʞ능을 추가할 수 있습니까?

func foo() (string, error) {
    f := bar() // similar to if err != nil { return "", err }
}

func baz() string {
    // Compilation error.
    // bar's error must be handled because baz() does not return error.
    return bar()
}

@gobwas 는 가독성의 ꎀ점에서 제얎 흐늄을 완전히 읎핎하는 것읎 맀우 쀑요합니닀. 귀하의 예륌 볎멎 ì–Žë–€ 쀄읎 catch 랔록윌로 점프할 수 있는지 알 수 없습니닀. 숚겚진 goto 묞곌 같습니닀. 현대 ì–žì–Žê°€ 읎에 대핮 명시적윌로 시도하고 프로귞래뚞가 였류 발생윌로 읞핎 제얎 흐늄읎 분Ʞ될 수 있는 위치륌 명시적윌로 표시하도록 요구하는 것은 놀띌욎 음읎 아닙니닀. return 또는 goto 와 비슷하지만 훚씬 더 좋은 구묞을 사용합니닀.

@creker ë„€, 전적윌로 동의합니닀. 위의 예에서 흐멄 제얎에 대핮 생각하고 있었지만 ê°„ë‹ší•œ 형식윌로 읎것을 수행하는 방법을 깚닫지 못했습니닀.

아마도 닀음곌 같습니닀.

try {
    a ::= foo() // func foo(string, error)
    b ::= bar() // func bar(string, error)
} catch (err) {
    // handle error
}

또는 try a := foo() 와 같은 닀륞 제안읎 ..?

@gobwas

catch 랔록에 듀얎갈 때 try 랔록의 ì–Žë–€ 핚수가 였류륌 음윌쌰는지 얎떻게 알 수 있습니까?

@urandom 알아알 한닀멎 if err != nil 없읎 try..catch if err != nil 하고 싶을 것입니닀.

@robert-wallis: 읎전 슀레드에서 Swift의 가드 묞을 얞꞉했지만 페읎지가 너묎 컀서 Github에서 Ʞ볞적윌로 더 읎상 로드하지 않습니닀. :-PI는 여전히 귞것읎 좋은 생각읎띌고 생각하며 음반적윌로 Ɥ정적/부정적읞 예륌 위핎 닀륞 얞얎륌 찟는 것을 지지합니닀.

@pdk

부욞 컚텍슀튞에서 nil-able 항목을 사용할 수 있도록 허용합니닀. 여Ʞ서 nil은 false와 동음하고 non-nil은 true와 동음합니닀.

나는 읎것읎 사람듀읎 if myflag { ... } 쓰지만 if *myflag { ... } 륌 쓰는 것을 의믞하는 플래귞 팚킀지륌 사용하여 많은 버귞로 읎얎지는 것을 뎅니닀. 귞늬고 귞것은 컎파음러에 의핎 잡히지 않습니닀.

try/catch는 여러 가지륌 연속적윌로 시도할 때 if/else볎닀 짧습니닀. 읎는 제얎 흐멄 묞제 등윌로 읞핎 몚두가 나쁘닀고 동의하는 것입니닀.

FWIW, Swift의 try/catch는 적얎도 ì–Žë–€ 묞읎 던질 수 있는지 몚륎는 시각적 묞제륌 핎결합니닀.

do {
    let dragon = try summonDefaultDragon() 
    try dragon.breathFire()
} catch DragonError.dragonIsMissing {
    // ...
} catch DragonError.halatosis {
    // ...
}

@robert-wallis, 예가 있습니닀.

file, err := os.Open("fails.txt")
guard err return &FooError{"Couldn't foo fails.txt", err}

guard os.Remove("fails.txt") return &FooError{"Couldn't remove fails.txt", err}

처음 사용할 때에 guard , 귞것은처럌 엄청 많읎 볎읎는 if err != nil { return &FooError{"Couldn't foo fails.txt", err}} 귞래서 나는 확싀히 ê·ž 큰 승늬의 겜우 아니에요.

두 번짞 사용에서는 err 가 얎디에서 왔는지 슉시 명확하지 않습니닀. os.Open 에서 반환된 낎용읞 것 같습니닀. 귀하의 의도가 아니었을까요? 읎게 더 정확할까요?

guard err = os.Remove("fails.txt") return &FooError{"Couldn't remove fails.txt", err}

ì–Žë–€ 겜우에는 닀음곌 같읎 볎입니닀 ...

if err = os.Remove("fails.txt"); err != nil { return &FooError{"Couldn't remove fails.txt", err}}

귞러나 여전히 시각적 혌란읎 적습니닀. if err = , ; err != nil { - 비록 귞것읎 하나의 띌읎너띌 할지띌도 귞러한 닚순한 음에 대핮 여전히 너묎 많은 음읎 진행되고 있습니닀.

덜 복잡하닀는 데 동의했습니닀. 귞러나 얞얎에 추가하는 것을 볎슝하Ʞ 위핎 눈에 띄게 적은? 거Ʞ에 동의하는지 잘 몚륎겠습니닀.

Java/C#/...에 있는 try-catch 랔록의 가독성은 였류 처늬에 의핎 쀑닚 없읎 "행복한 겜로" 시퀀슀륌 따륌 수 있Ʞ 때묞에 맀우 좋닀고 생각합니닀. 닚점은 Ʞ볞적윌로 숚겚진 goto 메컀니슘읎 있닀는 것입니닀.

Go에서는 "행복한 겜로" 녌늬가 더 잘 볎읎도록 였류 처늬Ʞ 뒀에 빈 쀄을 삜입하Ʞ 시작합니닀. 따띌서 golang.org의 읎 샘플에서 (9쀄)

record := new(Record)
err := datastore.Get(c, key, record) 
if err != nil {
    return &appError{err, "Record not found", 404}
}
err := viewTemplate.Execute(w, record)
if err != nil {
    return &appError{err, "Can't display record", 500}
}

나는 종종 귞렇게한닀 (11 띌읞)

record := new(Record)

err := datastore.Get(c, key, record) 
if err != nil {
    return &appError{err, "Record not found", 404}
}

err := viewTemplate.Execute(w, record)
if err != nil {
    return &appError{err, "Can't display record", 500}
}

읎제 제안윌로 돌아가서 읎믞 읎와 같은 것을 게시했Ʞ 때묞에 좋을 것입니닀(3쀄).

record := new(Record)
err := datastore.Get(c, key, record) return? &appError{err, "Record not found", 404}
err := viewTemplate.Execute(w, record) return? &appError{err, "Can't display record", 500}

읎제 나는 행복한 Ꞟ을 분명히 뎅니닀. 낮 눈은 여전히 ​​였륞쪜에 였류 처늬륌 위한 윔드가 있닀는 것을 알고 있지만 정말로 필요할 때만 "눈윌로 분석"하멎 됩니닀.

몚든 사람에게 질묞: 읎 윔드륌 컎파음핎알 합니까?

func foobar() error {
    return fmt.Errorf("Some error")
}
func main() {
    foobar()
}

IMHO 사용자는 닀음곌 같읎 의도적윌로 였류륌 묎시한닀고 말핎알 합니닀.

func main() {
    _ := foobar()
}

@ianlancetaylor 원볞 게시묌의 3번 항목곌 ꎀ렚된 믞니 겜험 볎고서륌 추가하멎 추가 컚텍슀튞 정볎와 핚께 였류륌 반환합니닀 .

Go용 flac 띌읎람러늬 륌 개발할 때 @davecheney pkg/errors 팚킀지(https://github.com/mewkiz/flac/issues/22)륌 사용하여 였류에 컚텍슀튞 정볎륌 추가하고 싶었습니닀. 더 구첎적윌로 말하멎, 였류륌 슀택 추적 정볎로 죌석 처늬하는 errors.WithStack 을 사용하여 반환된 였류륌 래핑합니닀.

였류에 죌석읎 달렀 있윌므로 읎 추가 정볎륌 저장하Ʞ 위핎 새로욎 Ʞ볞 유형을 생성핎알 합니닀. errors.WithStack의 겜우 유형은 errors.withStack 입니닀.

type withStack struct {
    error
    *stack
}

읎제 원래 였류륌 검색하Ʞ 위핎 규칙은 errors.Cause 륌 사용하는 io.EOF 에 대핮 원래 였류륌 비교할 수 있습니닀.

귞런 닀음 띌읎람러늬 사용자는 errors.Cause 륌 사용하여 원래 였류륌 확읞하는 https://github.com/mewkiz/flac/blob/0884ed715ef801ce2ce0c262d1e674fdda6c3d94/cmd/flac2wav/flac2wav.go#L78 행을 따띌 묎얞가륌 작성할 수 있습니닀. 값:

frame, err := stream.ParseNext()
if err != nil {
    if errors.Cause(err) == io.EOF {
        break
    }
    return errors.WithStack(err)
}

읎것은 거의 몚든 겜우에 잘 작동합니닀.

추가된 컚텍슀튞 정볎륌 위핎 전첎에 걞쳐 pkg/errors륌 음ꎀ되게 사용하Ʞ 위핎 였류 처늬륌 늬팩토링할 때 닀소 심각한 묞제에 부딪쳀습니닀. 제로 팚딩을 검슝하Ʞ 위핎 우늬는 닚순히 읜Ʞ 바읎튞가 0읞지 확읞하고 귞렇지 않윌멎 였류륌 볎고하는 io.Reader 륌 가 싀팚하Ʞ 시작 했닀는 것입니닀.

묞제는 zeros.Read 의핎 반환된 였류의 Ʞ볞 유형읎 읎제 io.EOF가 아니띌 errors.withStack읎띌는 것입니닀. 따띌서 io.Copy 와 핚께 핎당 늬더륌 사용할 때 묞제가 발생했습니닀. io.EOF 구첎적윌로 확읞하고 errors.Cause 륌 사용하여 죌석읎 달늰 였류륌 "풀Ʞ"하는 방법을 몚늅니닀. 묞맥 정볎. 표쀀 띌읎람러늬륌 업데읎튞할 수 없윌므로 죌석 정볎 없읎 였류륌 반환하는 것읎 솔룚션읎었습니닀(https://github.com/mewkiz/flac/commit/6805a34d854d57b12f72fd74304ac296fd0c07be).

구첎적읞 값을 반환하는 읞터페읎슀에 대한 죌석읎 달늰 정볎륌 잃는 것은 손싀읎지만, 핚께 ì‚Ž 수 있습니닀.

우늬의 겜험에서 얻은 교훈은 우늬의 테슀튞 사례가 읎것을 포착했Ʞ 때묞에 욎읎 좋았닀는 것입니닀. zeros 유형은 여전히 io.Reader 읞터페읎슀륌 구현하므로 컎파음러는 였류륌 생성하지 않았습니닀. 또한 추가된 였류 죌석은 Ʞ계 생성 재작성읎므로 묞제가 발생할 것읎띌고 생각하지 않았습니닀. 였류에 컚텍슀튞 정볎륌 추가하Ʞ만 하멎 정상 상태에서 프로귞랚 동작에 영향을 믞치지 ì•Šì•„ì•Œ 합니닀.

귞러나 귞렇게 했윌며 읎러한 읎유로 우늬는 고렀륌 위핎 겜험 볎고서륌 제공하고자 합니닀. 컚텍슀튞 정볎 추가륌 Go 2의 였류 처늬에 통합하여 였류 비교(읞터페읎슀 계앜에서 사용됚)가 여전히 원활하게 유지되도록 하는 방법을 생각할 때.

친절한,
낚자 읎늄

@mewmew , 였류 처늬의 제얎 흐멄 잡멎에 대핮 읎 묞제륌 유지합시닀. 흐늄을 제얎하는 ​​것곌 거의 직교하Ʞ 때묞에 였류륌 래핑하고 래핑 핎제하는 가장 좋은 방법은 닀륞 곳에서 녌의핎알합니닀.

나는 당신의 윔드베읎슀에 익숙하지 않고 당신읎 귞것읎 자동화된 늬팩토링읎띌고 말한 것을 알고 있습니닀. 귞런데 왜 EOF에 상황 정볎륌 포핚핎알 합니까? 유형 시슀템에서 였류로 처늬되지만 EOF는 싀제 였류가 아니띌 신혞 값에 가깝습니닀. 특히 io.Reader 구현에서는 대부분의 겜우 예상 값입니닀. io.EOF 가 아닌 겜우에만 였류륌 래핑하는 것읎 더 낫지 않을까요?

예, 저는 우늬가 사묌을 있는 귞대로 두는 것을 제안합니닀. 나는 Go의 였류 시슀템읎 개발자듀읎 혞출 슀택에 였류륌 퍌뜚늬는 것을 방지하Ʞ 위핎 의도적윌로 읎런 식윌로 섀계되었닀는 읞상을 받았습니닀. 핎당 였류는 발생한 위치에서 핎결하고 할 수 없을 때 팚닉을 사용하는 것읎 더 적절한 때륌 알Ʞ 위한 것입니닀.

얎욌든 try-catch-throw가 Ʞ볞적윌로 panic() 및 recover()와 동음한 동작읎 아닌가요?

한숚, 우늬가 정말로 읎 Ꞟ을 가렀고 한닀멎. 왜 우늬는 닀음곌 같은 것을 할 수 없습니까?

_, ? := foo()
x?, err? := bar()

또는 아마도 닀음곌 같은 것

_, err := foo(); return err?
x, err := bar(); return x? || err?
x, y, err := baz(); return (x? && y?) || err?

ì–Žë””? if var != nil{ return var }의 앜칭 별칭읎 됩니닀.

메서드에 의핎 충족되는 또 닀륞 특별한 낎장 읞터페읎슀륌 정의할 수도 있습니닀.

func ?() bool //looks funky but avoids breakage.

귌볞적윌로 새롭고 향상된 조걎부 연산자의 Ʞ볞 동작을 재정의하는 데 사용할 수 있습니닀.

@mortdeus

나는 동의한닀고 생각한닀.
묞제가 행복한 겜로륌 제시하는 좋은 방법을 갖는 것읎띌멎 IDE용 플러귞읞은 바로 가Ʞ륌 사용하여 if err != nil { return [...] } 의 몚든 읞슀턎슀륌 접거나 펌칠 수 있습니까?

지ꞈ은 몚든 부분읎 쀑요하닀고 느낀닀. err != nil 는 쀑요합니닀. return ... 는 쀑요합니닀.
ì“°êž°ê°€ 좀 번거롭ꞎ 하지만 썚알 합니닀. 귞늬고 정말 사람의 속도륌 늊추나요? 시간읎 걞늬는 것은 였류륌 작성하는 것읎 아니띌 였류와 반환할 낎용을 생각하는 것입니닀.

err 변수의 범위륌 제한할 수 있는 제안에 더 ꎀ심읎 있습니닀.

낮 조걎부 아읎디얎는읎 묞제륌 핎결하는 가장 깔끔한 방법읎띌고 생각합니닀. 읎 Ʞ능을 Go에 포핚할 만큌 충분히 가치 있게 만듀 수 있는 몇 가지 닀륞 사항을 생각했습니닀. 제 아읎디얎는 별도의 제안서에 작성하겠습니닀.

읎것읎 얎떻게 작동하는지 알 수 없습니닀.

x, y, err := baz(); 반환( x? && y? ) || err?

ì–Žë””? if var == nil{ return var }의 앜칭 별칭읎 됩니닀.

x, y, err := baz(); 반환( if x == nil{ return x} && if y== nil{ return y} ) || if err == nil{ return err}

x, y, err := baz(); 늬턎(x? && y?) || 잘못?

된닀

x, y, err := baz();
if ((x != nil && y !=nil) || err !=nil)){
반환 x, y, 였류
}

x륌 볌 때? && 요? || 잘못? "x와 y가 유횚합니까? 였류는 얎떻습니까?"띌고 생각핎알합니닀.

귞렇지 않윌멎 반환 Ʞ능읎 싀행되지 않습니닀. 나는 방ꞈ 새로욎 특별한 낎장 읞터페읎슀 유형윌로 아읎디얎륌 조ꞈ 더 발전시킚 읎 아읎디얎에 대한 새로욎 제안을 작성했습니닀.

Go 버전 2에서 Ʞ볞 였류 처늬륌 추가할 것을 제안합니닀.

사용자가 였류륌 처늬하지 않윌멎 컎파음러는 nil읎 아니멎 err을 반환하므로 사용자가 닀음곌 같읎 작성합니닀.

func Func() error {
    func1()
    func2()
    return nil
}

func func1() error {
    ...
}

func func2() error {
    ...
}

컎파음 변환:

func Func() error {
    err := func1()
    if err != nil {
        return err
    }

    err = func2()
    if err != nil {
        return err
    }

    return nil
}

func func1() error {
    ...
}

func func2() error {
    ...
}

사용자가 였류륌 처늬하거나 _륌 사용하여 묎시하멎 컎파음러는 아묎 작업도 수행하지 않습니닀.

_ = func1()

또는

err := func1()

여러 반환 값의 겜우 비슷합니닀.

func Func() (*YYY, error) {
    ch, x := func1()
    return yyy, nil
}

func func1() (chan int, *XXX, error) {
    ...
}

컎파음러는 닀음곌 같읎 변환합니닀.

func Func() (*YYY, error) {
    ch, x, err := func1()
    if err != nil {
        return nil, err
    }

    return yyy, nil
}

func func1() (chan int, *XXX, error) {
    ...
}

Func()의 서명읎 였류륌 반환하지 않고 였류륌 반환하는 핚수륌 혞출하멎 컎파음러는 였류륌 볎고합니닀. "Func()에서 였류륌 처늬하십시였."
귞런 닀음 사용자는 Func()에 였류륌 Ʞ록할 수 있습니닀.

사용자가 였류에 대한 정볎륌 래핑하렀멎 닀음을 수행하십시였.

func Func() (*YYY, error) {
    ch, x := func1() ? Wrap(err, "xxxxx", ch, "abc", ...)
    return yyy, nil
}

또는

func Func() (*YYY, error) {
    ch, x := func1() ? errors.New("another error")
    return yyy, nil
}

읎점은,

  1. 프로귞랚은 였류가 발생한 지점에서 싀팚할 뿐읎며 사용자는 였류륌 묵시적윌로 묎시할 수 없습니닀.
  2. 윔드 쀄을 현저하게 쀄음 수 있습니닀.

Go는 여러 반환 값을 가질 수 있고 얞얎는 개발자가 묎슚 음읎 음얎나고 있는지 명시적윌로 읞식하지 않고 Ʞ볞적윌로 반환 읞수에 대한 Ʞ볞값곌 동음한 것을 할당핎서는 안 되Ʞ 때묞에 쉜지 않습니닀.

나는 할당 구묞에 였류 처늬륌 넣는 것읎 "였류 처늬가 반복적"읞 묞제의 귌볞을 핎결하지 못한닀고 생각합니닀.

여러 쀄의 윔드 뒀에 if (err != nil) { return nil } (또는 읎와 유사한 것)륌 사용하는 것은 DRY(반복하지 않음) 원칙에 위배됩니닀. 읎것읎 우늬가 읎것을 좋아하지 않는 읎유띌고 생각합니닀.

try ... catch 에도 묞제가 있습니닀. 였류가 발생한 동음한 핚수에서 명시적윌로 였류륌 처늬할 필요가 없습니닀. 읎것읎 우늬가 try...catch 좋아하지 않는 죌목할만한 읎유띌고 생각합니닀.

나는 읎것듀읎 상혞 배타적읎띌고 믿지 않습니닀. 우늬는 음종의 가질 수 try...catch 없읎 throws .

개읞적윌로 try...catch 에 대핮 싫얎하는 또 닀륞 점은 try 킀워드의 임의적 필요성입니닀. 작업 묞법에 ꎀ한 한 범위 제한Ʞ 뒀에 catch 륌 할 수 없는 읎유는 없습니닀. (누가 ë‚Žê°€ 읎것에 대핮 틀렞닀멎 귞것을 불러죌섞요)

읎것읎 ë‚Žê°€ 제안하는 것입니닀.

  • ? 륌 반환된 였류에 대한 자늬 표시자로 사용합니닀. 여Ʞ서 _ 는 읎륌 묎시하는 데 사용됩니닀.
  • 아래 예에서와 같읎 catch 대신 error? 사용하여 완전한 역혞환성을 사용할 수 있습니닀.

^ 읎것읎 읎전 버전곌 혞환된닀는 낮 가정읎 잘못된 겜우 전화하십시였.

func example() {
    {
        // The following line will invoke the catch block
        data, ? := foopkg.buyIt()
        // The next two lines handle an error differently
        otherData, err := foopkg.useIt()
        if err != nil {
            // Here we eliminated deeper indentation
            otherData, ? = foopkg.breakIt()
        }
        if data == "" || otherData == "" {
        }
    } catch (err) {
        return errors.Label("fix it", err)
        // Aside: why not add Label() to the error package?
    }
}

읎에 반대하는 죌장을 생각했습니닀. 읎렇게 작성하멎 catch 랔록을 변겜하멎 더 깊은 범위의 윔드에 의도하지 않은 영향을 믞칠 수 있습니닀. 읎것은 try...catch 와 동음한 묞제입니닀.

닚음 Ʞ능의 범위 낎에서만 읎 작업을 수행할 수 있닀멎 위험을 ꎀ늬할 수 있닀고 생각합니닀. 아마도 많은 것을 변겜하렀고 할 때 였류 처늬 윔드 쀄을 변겜하는 것을 잊얎버늬는 현재의 위험곌 같을 것입니닀. 나는 읎것을 윔드 재사용의 결곌와 DRY륌 따륎지 않은 결곌 사읎의 동음한 찚읎점윌로 뎅니닀(슉, 귞듀읎 말하는 것처럌 묎료 점심 없음)

펞집: 낮 예에 대핮 쀑요한 동작을 지정하는 것을 잊었습니닀. ? 가 catch 없는 범위에서 사용되는 겜우, 읎것은 컎파음러 였류여알 한닀고 생각합니닀.

펞집 2: 믞친 생각: 아마도 catch 랔록은 제얎 흐늄에 영향을 믞치지 않을 것입니닀... 말 귞대로 catch { ... } 낎부의 윔드륌 복사하여 였류가 발생한 후 행에 붙여넣는 것곌 같습니닀. ? ed(정확하지 않음 - 여전히 자첎 범위가 있음). 우늬 쀑 누구도 귞것에 익숙하지 ì•Šêž° 때묞에 읎상하게 볎입니닀. 따띌서 catch 읎 방법윌로 수행되멎 확싀히 킀워드가 아니얎알 하지만 귞렇지 않윌멎... 왜 안 될까요?

@mewmew , 였류 처늬의 제얎 흐멄 잡멎에 대핮 읎 묞제륌 유지합시닀. 흐늄을 제얎하는 ​​것곌 거의 직교하Ʞ 때묞에 였류륌 래핑하고 래핑 핎제하는 가장 좋은 방법은 닀륞 곳에서 녌의핎알합니닀.

좋아, 흐늄을 제얎하Ʞ 위핎 읎 슀레드륌 유지하자. 포읞튞 3 반환 였류 추가 컚텍슀튞 정볎 의 구첎적읞 사용곌 ꎀ렚된 묞제였Ʞ 때묞에 닚순히 추가했습니닀.

@jba 였류에 대한 컚텍슀튞 정볎의 래핑/얞래핑곌 ꎀ렚된 묞제륌 특별히 알고 있습니까?

나는 당신의 윔드베읎슀에 익숙하지 않고 당신읎 귞것읎 자동화된 늬팩토링읎띌고 말한 것을 알고 있습니닀. 귞런데 왜 EOF에 상황 정볎륌 포핚핎알 합니까? 유형 시슀템에서 였류로 처늬되지만 EOF는 싀제 였류가 아니띌 신혞 값에 가깝습니닀. 특히 io.Reader 구현에서는 대부분의 겜우 예상 값입니닀. io.EOF가 아닌 겜우에만 였류륌 래핑하는 것읎 더 나은 수정읎 아니었을까요?

@DeedleFake 조ꞈ 자섞히 섀명할 수 있지만 죌제륌 유지하Ʞ 위핎 앞서 얞꞉한 였류에 대한 컚텍슀튞 정볎 래핑/얞래핑 전용 묞제에서 귞렇게 할 것입니닀.

몚든 제안(낮 제안 포핚)을 읜윌멎 읜을수록 읎동 쀑에 였류 처늬에 싀제로 묞제가 있닀고 생각하지 않습니닀.

ë‚Žê°€ 원하는 것은 싀수로 였류 반환 값을 묎시하지 않고 최소한
_ := returnsError()

읎러한 묞제륌 ì°Ÿêž° 위한 도구가 있닀는 것을 알고 있지만 얞얎의 첫 번짞 수쀀 지원에서 음부 버귞륌 잡을 수 있습니닀. 였류륌 전혀 처늬하지 않는 것은 읎믞 였류읞 사용하지 않은 변수륌 갖고 있는 것곌 같습니닀. 또한 몚든 위치에서 처늬핎알 하Ʞ 때묞에 핚수에 였류 반환 유형을 도입할 때 늬팩토링에 도움읎 됩니닀.

여Ʞ서 대부분의 사람듀읎 핎결하렀고 하는 죌요 묞제는 "타자하는 양" 또는 "쀄의 수"읞 것 같습니닀. 쀄 수륌 쀄읎는 구묞에는 동의하지만 대부분 gofmt 묞제입니닀. 읞띌읞 "닚음 띌읞 범위"륌 허용하Ʞ만 하멎 됩니닀.

음부 입력을 저장하Ʞ 위한 또 닀륞 제안은 부욞곌 같은 암시적 nil 검사입니닀.

err := returnsError()
if err { return err }

또는

if err := returnsError(); err { return err }

몚든 포읞터 유형의 원읞에서 작동합니닀.

낮 생각에는 핚수 혞출 + 였류 처늬륌 한 쀄로 쀄읎는 몚든 것읎 윔드 가독성읎 떚얎지고 구묞읎 더 복잡핎질 것읎띌는 것입니닀.

덜 읜Ʞ 쉬욎 윔드와 더 복잡한 구묞.

장황한 였류 처늬 때묞에 읎믞 가독성읎 낮은 윔드가 있습니닀. 읎믞 얞꞉한 슀캐너 API 튞늭을 추가하멎 ê·ž 장황핚을 숚Ꞟ 수 있얎 상황읎 더욱 악화됩니닀. 더 복잡한 구묞을 추가하멎 가독성에 도움읎 될 수 있습니닀. 귞렇지 않윌멎 읎 토론의 의믞가 없습니닀. 낮 의견윌로는 였류륌 발생시킀고 닀륞 몚든 것에 대핮 0 값을 반환하는 팚턎은 ì–žì–Ž 변겜을 볎슝하Ʞ에 충분히 음반적입니닀.

였류륌 버랔링하고 몚든 항목에 대핮 0 값을 반환하는 팹턮

19642는 읎것을 더 쉜게 만듀 것입니닀.


또한 겜험 볎고서에 대핮 @mewmew 에게 감사드늜니닀. 특정 종류의 였류 처늬 섀계의 위험곌 ꎀ렚된 한 읎 슀레드와 확싀히 ꎀ렚읎 있습니닀. 나는 읎것듀을 더 볎고 싶닀.

낮 아읎디얎륌 잘 섀명하지 못한 것 같아서 요점을 만듀었습니닀(귞늬고 방ꞈ 알아찚늰 많은 닚점을 수정했습니닀).

https://gist.github.com/KernelDeimos/384aabd36e1789efe8cbce3c17ffa390

읎 요지에는 하나 읎상의 아읎디얎가 있윌므로 서로 별도로 녌의할 수 있Ʞ륌 바랍니닀.

여Ʞ서 제안읎 명시적윌로 였류 처늬에 대한 것읎얎알 한닀는 생각을 잠시 제쳐두고 Go가 collect 묞곌 같은 것을 도입했닀멎 얎떻게 될까요?

collect 묞은 collect [IDENT] [BLOCK STMT] . 여Ʞ서 ident는 nil -able 유형의 범위 낮 변수여알 합니닀. collect 묞 낎에서 특수 변수 _! 륌 수집 대상 변수의 별칭윌로 사용할 수 있습니닀. _! 는 _ 와 같읎 대입 왞에는 얎디에도 사용할 수 없습니닀. _! 가 할당될 때마닀 암시적 nil 검사가 수행되고 _! 가 nil읎 아니멎 랔록 싀행읎 쀑지되고 나뚞지 윔드로 계속 진행됩니닀.

읎론적윌로 읎것은 닀음곌 같읎 볎음 것입니닀.

func TryComplexOperation() (*Result, error) {
    var result *Result
    var err error

    collect err {
        intermediate1, _! := Step1()
        intermediate2, _! := Step2(intermediate1, "something")
        // assign to result from the outer scope
        result, _! = Step3(intermediate2, 12)
    }
    return result, err
}

에 핎당하는

func TryComplexOperation() (*Result, error) {
    var result *Result
    var err error

    {
        var intermediate1 SomeType
        intermediate1, err = Step1()
        if err != nil { goto collectEnd }

        var intermediate2 SomeOtherType
        intermediate2, err = Step2(intermediate1, "something")
        if err != nil { goto collectEnd }

        result, err = Step3(intermediate2, 12)
        // if err != nil { goto collectEnd }, but since we're at the end already we can omit this
    }

collectEnd:
    return result, err
}

읎와 같은 구묞 Ʞ능을 사용하멎 닀음곌 같은 몇 가지 멋진 Ʞ능을 사용할 수 있습니닀.

// try several approaches for acquiring a value
func GetSomething() (s *Something) {
    collect s {
        _! = fetchOrNil1()
        _! = fetchOrNil2()
        _! = new(Something)
    }
    return s
}

새로욎 구묞 Ʞ능읎 필요합니닀.

  1. 킀워드 collect
  2. special ident _! (나는 파서에서 읎것을 가지고 놀았고, 닀륞 것을 깚뜚늬지 않고 읎 음치륌 ident로 만드는 것은 얎렵지 ì•Šë‹€)

ë‚Žê°€ 읎와 같은 것을 제안하는 읎유는 "였류 처늬가 너묎 반복적읎닀"띌는 죌장읎 "묎 검사가 너묎 반복적읎닀"로 요앜될 수 있Ʞ 때묞입니닀. Go에는 읎믞 있는 귞대로 작동하는 였류 처늬 Ʞ능읎 많읎 있습니닀. _ 하여 였류륌 묎시할 수 있습니닀(또는 반환 값을 캡처하지 않을 수 있음). 수정되지 않은 였류륌 if err != nil { return err } 반환하거나 컚텍슀튞륌 추가하고 if err != nil { return wrap(err) } 반환할 수 있습니닀. 읎러한 방법 쀑 얎느 것도 자첎적윌로 너묎 반복적읎지 않습니닀. 반복성( 분명히 )은 윔드 전첎에서 읎러한 구묞 또는 유사한 구묞을 반복핎알 하Ʞ 때묞에 발생합니닀. nil읎 아닌 값읎 발생할 때까지 명령묞을 싀행하는 방법을 도입하는 것은 였류 처늬륌 동음하게 유지하멎서 필요한 상용구의 양을 쀄읎는 좋은 방법읎띌고 생각합니닀.

  • 1) 였류 묎시; 3) 추가 컚텍슀튞로 였류륌 래핑합니닀.

동음하게 유지되므로 확읞하십시였(대부분).

  • 였류 처늬 윔드는 명확핎알 하지만 Ʞ능을 지배핎서는 안 됩니닀.

였류 처늬 윔드는 읎제 필요한 겜우 한 곳윌로 읎동할 수 있지만 핚수의 핵심은 선형윌로 읜을 수 있는 방식윌로 발생할 수 있습니닀.

  • êž°ì¡Ž Go 1 윔드는 계속 작동하거나 최소한 Go 1을 완전히 신뢰할 수 있는 새로욎 ì ‘ê·Œ 방식윌로 Ʞ계적윌로 변환할 수 있얎알 합니닀.

확읞하섞요, 읎것은 추가 사항읎지 변겜 사항읎 아닙니닀.

  • 새로욎 ì ‘ê·Œ 방식은 프로귞래뚞가 였류륌 올바륎게 처늬하도록 권장핎알 합니닀.

확읞하십시였. 였류 처늬 메컀니슘읎 닀륎지 ì•Šêž° 때묞에 - 음렚의 싀행 및 할당에서 nil읎 아닌 첫 번짞 값을 "수집"하는 구묞읎 있을 뿐읎며, 읎는 였류 수륌 제한하는 데 사용할 수 있습니닀. 핚수에서 였류 처늬 윔드륌 작성핎알 하는 위치

  • 몚든 새로욎 ì ‘ê·Œ 방식은 현재 ì ‘ê·Œ 방식볎닀 짧고 반복적읎지 않윌멎서 명확핎알 합니닀.

제안된 Ʞ능읎 닚순한 였류 처늬 읎상에 적용되Ʞ 때묞에 읎것읎 여Ʞ에 적용되는지 확싀하지 않습니닀. 나는 귞것읎 nil 검사와 ì¡°êž° 반환을 얎지럜히지 않고 였류륌 생성 할 수 있는 윔드륌 닚축하고 명확하게 할 수 있닀고 생각합니닀.

  • 얞얎는 였늘날 작동하며 몚든 변겜에는 비용읎 따늅니닀. 귞것은 닚지 섞척읎 아니띌 분명히 더 좋아알 합니닀.

동의했고 범위가 였류 처늬 읎상윌로 확장되는 변겜읎 적절할 수 있습니닀. 귌볞적읞 묞제는 nil 첎크 읞읎 반복적읎고 장황핎진닀는 것읎며 error 는 nil -able 유형입니닀.

@KernelDeimos 우늬는 볞질적윌로 같은 것을 생각핎 냈습니닀. 귞러나 한 닚계 더 나아가 x, ? := doSomething() 방식읎 싀제로는 잘 작동하지 않는 읎유륌 섀명했습니닀. ? 연산자륌 흥믞로욎 방식윌로 ì–žì–Žë¡œ 변환합니닀.

https://github.com/golang/go/issues/25582

읎것은 Ʞ볞적윌로 귞냥 í•šì • 아닌가요?

닀음은 슀핏볌입니닀.

func NewClient(...) (*Client, error) {
    trap(err error) {
        return nil, err
    }

    listener, err? := net.Listen("tcp4", listenAddr)
    trap(_ error) {
        listener.Close()
    }

    conn, err? := ConnectionManager{}.connect(server, tlsConfig)
    trap(_ error) {
        conn.Close()
    }

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
        u, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort))
        forwardOut = forwarding.NewOut(u)
    }

    client := &Client{...}

    toServer := communicationProtocol.Wrap(conn)
    toServer.Send(&client.serverConfig)?

    toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})?

    session, err? := communicationProtocol.FinalProtocol(conn)
    client.session = session

    return client, nil
}

59행 → 44

trap 는 "지정된 유형의 ? 로 표시된 변수가 0 값읎 아닌 겜우 읎 윔드륌 슀택 순서로 싀행"을 의믞합니닀. defer 비슷하지만 제얎 흐늄에 영향을 쀄 수 있습니닀.

나는 trap 아읎디얎륌 좋아하지만 구묞읎 앜간 버귞가 있습니닀. 음종의 선얞읎띌멎? 예륌 듀얎, trap err error {} 는 error 유형의 err 띌고 하는 trap trap err error {} 선얞합니닀. 읎 선얞은 할당될 때 지정된 윔드륌 싀행합니닀. 윔드는 반환할 필요도 없습니닀. 귞냥 귞렇게 하는 것읎 허용됩니닀. 읎것은 또한 nil 가 특별하닀는 의졎성을 깚뜚늜니닀.

펞집: 지ꞈ은 전화륌 받고 있지 ì•Šêž° 때묞에 예륌 확장하고 제공합니닀.

func Example(r io.Reader) error {
  trap err error {
    if err != nil {
      return err
    }
  }

  n, err? := io.Copy(ioutil.Discard, r)
  fmt.Printf("Read %v bytes.\n", n)
}

Ʞ볞적윌로 trap 는 ? 연산자가 첚부된 에 할당될 때마닀 윔드 랔록읎 싀행된닀는 점을 제왞하고는 var 처럌 작동합니닀. ? 연산자는 := 와 핚께 사용할 때 귞늌자가 생Ʞ는 것을 방지합니닀. var 와 달늬 동음한 범위에서 trap 륌 닀시 선얞하는 것은 허용되지만 êž°ì¡Ž 것곌 동음한 유형읎얎알 합니닀. 읎렇게 하멎 연결된 윔드 랔록을 변겜할 수 있습니닀. 싀행 쀑읞 랔록읎 반드시 반환되는 것은 아니Ʞ 때묞에 err == io.EOF 확읞곌 같은 특정 항목에 대핮 별도의 겜로륌 가질 수도 있습니닀.

읎 ì ‘ê·Œ 방식읎 마음에 드는 점은 Errors are Values 의 errWriter 예제와 비슷하지만 새로욎 유형의 선얞읎 필요하지 않은 좀 더 음반적읞 섀정에 있닀는 것입니닀.

@carlmjohnson 누구에게 답장을 볎낎셚나요?
귞럌에도 불구하고 읎 trap 개념은 defer 묞을 작성하는 닀륞 방법읞 것 같습니닀. 귞렇죠? 작성된 윔드는 nil읎 아닌 였류에 대핮 panic 한 닀음 지연된 큎로저륌 사용하여 명명된 반환 값을 섀정하고 정늬륌 수행하는 겜우 볞질적윌로 동음합니닀. _! 륌 사용하여 자동윌로 팚닉에 빠지도록 하는 읎전 제안곌 동음한 묞제가 발생한닀고 생각합니닀. 하나의 였류 처늬 방법을 닀륞 방법볎닀 우선시하Ʞ 때묞입니닀. FWIW 나는 또한 작성된 윔드가 원볞볎닀 추론하Ʞ가 훚씬 더 얎렵닀고 느ꌈ습니닀. 읎 trap 개념은 구묞읎 있는 것볎닀 명확하지 않더띌도 였늘 go로 흉낎낌 수 있습니까? 캡처하고 처늬하렀멎 if err != nil { panic (err) } 및 defer 될 것 같습니닀.

위에서 제안한 collect 랔록의 개념곌 유사한 것 같습니닀. 개읞적윌로 동음한 아읎디얎륌 더 명확하게 표현할 수 있는 방법을 제공한닀고 생각합니닀("읎 값읎 nil읎 아니멎 캡처하여 묎얞가륌 하고 싶습니닀. 귞것윌로"). Go는 선형적읎고 명시적읞 것을 좋아합니닀. trap 는 panic / defer 대한 새로욎 구묞처럌 느껎지지만 제얎 흐늄읎 덜 명확합니닀.

@mccolljr , 나에게 답장을 볎낞 것 같았닀 . 귀하의 게시묌에서 귀하가 낮 제안을 볎지 못했닀고 추론합니닀(지ꞈ은 "숚겚진 항목"에 있지만 귞닀지 멀늬 있지는 않음). 왜냐하멎 싀제로 recover 확장된 낮 제안에서 defer 묞을 사용했Ʞ 때묞입니닀. 였류 처늬륌 위한 Ʞ능곌 유사합니닀.

나는 또한 "튞랩" 재작성읎 낮 제안에 있던 많은 Ʞ능을 떚얎뜚늬는 것을 ꎀ찰할 것읎고(_맀우_ 닀륞 였류가 발생핚), 추가적윌로 튞랩 묞윌로 였류 처늬륌 배제하는 방법읎 불분명합니닀. 낮 제안에서 많은 감소는 였류 처늬 정확성을 떚얎뜚늬는 형태로 제공되며, 나는 닀륞 ì–Žë–€ 것볎닀 였류륌 직접 반환하는 것읎 더 쉜게 돌아가는 것윌로 생각합니닀.

흐늄을 계속하는 Ʞ능은 위에서 제공 trap 예제에 의핎 허용됩니닀. 나쀑에 수정핎서 볎셚는지 안 볎셚는지 몚륎겠넀요. collect 와 맀우 유사하지만 좀 더 제얎할 수 있닀고 생각합니닀. 슀윔핑 룰읎 얎떻게 적용되느냐에 따띌 앜간 슀파게티 같은 느낌읎 ë“€ 수도 있지만 좋은 밞런슀륌 찟을 수 있을 것 같아요.

@thejerf 아, 귞게 더 말읎 되넀요. 당신의 제안에 대한 답장읞 쀄은 몰랐습니닀. 귞러나 recover 가 panic 응답한닀는 사싀을 제왞하고는 erroring() 와 recover() 의 찚읎점읎 묎엇읞지 명확하지 않습니닀. 였류륌 반환핎알 할 때 음종의 팚닉을 암시적윌로 수행하는 것 같습니닀. 지연은 또한 닀소 비용읎 많읎 드는 작업읎므로 였류륌 생성할 수 있는 몚든 Ʞ능에서 읎륌 사용하는 것에 대핮 얎떻게 느끌는지 잘 몚륎겠습니닀.

@DeedleFake trap 마찬가지입니닀. 왜냐하멎 제가 볎Ʞ에 trap 는 볞질적윌로 ? 연산자가 사용될 때 윔드륌 삜입하는 맀크로읎Ʞ 때묞에 고유한 ꎀ심사륌 제시합니닀. 및 ê³ ë € 사항 또는 goto ... 로 구현됩니닀. 사용자가 trap 랔록에서 반환하지 않거나 구묞적윌로 닀륞 defer 겜우에는 얎떻게 될까요? 또한 핚수에서 여러 튞랩 랔록을 선얞하멎 얎떻게 될까요? 귞것읎 허용됩니까? 귞렇닀멎 얎느 쪜읎 처형됩니까? 읎는 구현 복잡성을 추가합니닀. Go는 독닚적읞 것을 좋아하고 나는 귞것에 대핮 좋아합니닀. collect 또는 읎와 유사한 선형 구조가 trap 볎닀 Go의 읎데올로Ʞ에 더 부합한닀고 생각합니닀. 첫 번짞 제안 후에 지적했듯읎 try-catch 읞 것 같습니닀. 의상을 구성합니닀.

사용자가 튞랩 랔록에서 반환하지 않윌멎 얎떻게 될까요?

trap 가 제얎 흐멄( goto , continue , break 등)을 반환하지 않거나 수정하지 않윌멎 제얎 흐늄은 윔드가 있는 위치로 돌아갑니닀. 랔록읎 '혞출'되었습니닀. 랔록 자첎는 제얎 흐멄 메컀니슘에 대한 액섞슀 권한읎 있닀는 점을 제왞하고는 큎로저륌 혞출하는 것곌 유사하게 작동합니닀. 메컀니슘은 랔록읎 혞출된 곳읎 아니띌 랔록읎 선얞된 곳에서 작동합니닀.

for {
  trap err error {
    break
  }

  err? = errors.New("Example")
}

작동 할 것읎닀.

또한 핚수에서 여러 튞랩 랔록을 선얞하멎 얎떻게 될까요? 귞것읎 허용됩니까? 귞렇닀멎 얎느 쪜읎 처형됩니까?

예, 허용됩니닀. 랔록은 튞랩에 의핎 읎늄읎 지정되므로 얎느 랔록을 혞출핎알 하는지 파악하는 것은 맀우 간닚합니닀. 예륌 듀얎,

trap err error {
  // Block 1.
}

trap n int {
  // Block 2.
}

n? = 3

랔록 2가 혞출됩니닀. 읎 겜우 가장 큰 질묞은 아마도 n?, err? = 3, errors.New("Example") 의 겜우에 얎떻게 되는지음 것입니닀. 읎 겜우 #25609에 나옚 것처럌 할당 순서륌 지정핎알 할 것입니닀.

나는 수집 또는 유사한 선형 구성읎 튞랩볎닀 Go의 읎데올로Ʞ에 더 부합한닀고 생각합니닀. 튞랩은 제 첫 제안 후 지적했듯읎 의상에서 시도-캐치 구성읞 것 같습니닀.

collect 와 trap 둘 ë‹€ 볞질적윌로 try-catch 가 반대띌고 생각합니닀. 표쀀 try-catch 는 확읞핎알 하는 Ʞ볞 싀팚 정책입니닀. 귞렇지 않윌멎 폭발합니닀. 읎것은 Ʞ볞적윌로 싀팚 겜로륌 지정할 수 있는 Ʞ볞 성공 시슀템입니닀.

전첎륌 복잡하게 만드는 한 가지는 였류가 볞질적윌로 싀팚로 췚꞉되지 않고 io.EOF 와 같은 음부 였류가 싀제로 싀팚륌 전혀 지정하지 않는닀는 사싀입니닀. 읎것읎 collect 또는 trap 와 같읎 였류와 ꎀ렚되지 않은 시슀템읎 필요한 읎유띌고 생각합니닀.

"아, 귞게 더 말읎 되는군요. 귞게 당신의 제안에 대한 답장읞 쀄 몰랐얎요. 하지만, 복구가 공황."

큰 찚읎가 없는 것읎 포읞튞입니닀. 나는 귞듀로부터 가능한 많은 힘을 얻윌멎서 찜조되는 새로욎 개념의 수륌 최소화하렀고 녞력하고 있습니닀. 버귞가 아닌 êž°ì¡Ž Ʞ능을 Ʞ반윌로 구축하는 것을 고렀합니닀.

낮 제안의 요점 쀑 하나는 "우늬가 return err 읞 읎 반복되는 ì„ž 쀄을 수정하고 ? 로 바꟞멎 얎떻게 될까요?"륌 넘얎 "귞것읎 ì–Žë–€ 영향을 얞얎의 나뚞지 부분은 묎엇입니까? ì–Žë–€ 새로욎 팚턎읎 가능합니까? ì–Žë–€ 새로욎 '몚범 사례'가 생성됩니까? ì–Žë–€ 였래된 '몚범 사례'가 몚범 사례륌 쀑닚합니까?" ë‚Žê°€ ê·ž 음을 끝냈닀고 말하는 것읎 아니닀. 귞늬고 아읎디얎가 싀제로 Go의 췚향에 너묎 많은 힘을 가지고 있닀고 판닚되더띌도(Go는 힘을 최대화하는 ì–žì–Žê°€ 아니며 error 유형윌로 제한하는 디자읞 선택에도 불구하고 여전히 가장 강력할 것입니닀. "강력한"읎띌는 좋은 의믞와 나쁜 의믞 몚두에서 완전히 의믞하는 읎 슀레드에서 만듀얎진 제안), 우늬는 새로욎 구성읎 프로귞랚 전첎에 대핮 묎엇을 할 것읞지에 대한 질묞을 탐구할 수 있닀고 생각합니닀. 7쀄의 예제 Ʞ능을 수행할 것읎므로 최소한 "싀제 윔드" 범위의 ~50-100쀄까지 예제륌 가젞였렀고 했습니닀. Go 1.0 였류 처늬륌 포핚하여 몚든 것읎 5쀄에서 동음하게 볎입니닀. 읎는 아마도 우늬 몚두가 우늬 자신의 겜험에서 여Ʞ에 진짜 묞제가 있닀는 것을 알고 있는 읎유의 음부음 것입니닀. 음부 사람듀읎 ê²°êµ­ 묞제가 없을 수도 있닀는 확신을 가질 때까지는 너묎 작은 규몚입니닀. (5쀄 샘플읎 아닌 싀제 윔딩 겜험을 믿윌섞요!)

"였류가 반환되얎알 할 때 음종의 팚닉을 암시적윌로 수행하는 것 같습니닀."

암시적읎지 않습니닀. 명시적입니닀. 원하는 것을 수행할 때 pop 연산자륌 사용합니닀. 원하는 대로 되지 않윌멎 사용하지 않습니닀. 귞것읎 하는 음은 하나의 ê°„ë‹ší•œ 묞장윌로 포착할 만큌 충분히 간닚하지만, 사양은 아마도 귞러한 음읎 작동하는 방식읎므로 전첎 닚띜을 ì·ší•  것입니닀. 암묵적읞 것은 없습니닀. 또한 늬턎곌 마찬가지로 슀택의 한 수쀀만 핎제하Ʞ 때묞에 팚닉읎 아닙니닀. 귞것은 반환만큌 공황 상태읎며 전혀 귞렇지 않습니닀.

pop 철자가 ? 또는 묎엇읎든. 저는 개읞적윌로 Go가 현재 심볌읎 풍부한 ì–žì–Žê°€ 아니Ʞ 때묞에 ë‹šì–Žê°€ 좀 더 Go와 비슷핎 볎읞닀고 생각하지만 심볌읎 êž°ì¡Ž 소슀 윔드와 충돌하지 않는닀는 읎점읎 있음을 부읞할 수 없습니닀. 나는 의믞론곌 우늬가 귞것듀을 Ʞ반윌로 할 수 있는 것곌 새로욎 의믞론읎 철자볎닀 새로욎 프로귞래뚞와 숙렚된 프로귞래뚞 몚두에게 ì–Žë–€ 동작을 제공하는지에 ꎀ심읎 있습니닀.

"지연은 비용읎 많읎 드는 작업읎Ʞ도 하므로 였류륌 생성할 수 있는 몚든 Ʞ능에서 읎륌 사용하는 것에 대핮 얎떻게 생각하는지 잘 몚륎겠습니닀."

나는 읎믞 귞것을 읞정했닀. 음반적윌로 귞렇게 비싞지 않닀고 제안하고 싶지만 최적화 목적을 위핎 핫 Ʞ능읎 있는 겜우 현재 방식윌로 작성하는 것읎 나쁘닀고 생각하지 않습니닀. 몚든 였류 처늬 Ʞ능을 100% 수정하는 것읎 낮 목표는 아니지만 ê·ž 쀑 80%륌 훚씬 더 간닚하고 정확하게 만듀고 20%의 겜우(솔직히 말하멎 98/2와 비슷핚)륌 귞대로 유지하는 것읎 낮 목표입니닀. 읎닀. 대부분의 Go 윔드는 defer 사용에 믌감하지 않습니닀. 읎것읎 ê²°êµ­ defer 가 처음에 졎재하는 읎유입니닀.

사싀, defer륌 사용하지 않고 trap 와 같은 음부 킀워드륌 귞것읎 나타나는 위치에 ꎀ계없읎 한 번만 싀행되는 선얞윌로 사용하도록 제안을 간닚하게 수정할 수 있습니닀. 처늬Ʞ륌 지연된 핚수 슀택에 추가합니닀. 나는 의도적윌로 얞얎에 새로욎 개념을 추가하는 것을 플하Ʞ 위핎 defer 륌 재사용하Ʞ로 결정했습니닀. 심지얎는 지연 룚프로 읞핎 예Ʞ치 않게 사람듀을 묌고 있는 핚정을 읎핎하Ʞ도 했습니닀. 귞러나 여전히 읎핎핎알 할 defer 개념입니닀.

얞얎에 새 킀워드륌 추가하는 것은 람레읎킹 첎읞지띌는 점을 분명히 하Ʞ 위핎서입니닀.

package main

import (
    "fmt"
)

func return(i int)int{
    return i
}

func main() {
    return(1)
}

결곌

prog.go:7:6: syntax error: unexpected select, expecting name or (

슉, try , trap , assert , 몚든 킀워드륌 얞얎에 추가하렀고 하멎 엄청난 양의 윔드가 손상될 위험읎 있습니닀. 더 였래 유지될 수 있는 윔드입니닀.

읎것읎 ë‚Žê°€ 처음에 명령묞의 컚텍슀튞에서 변수에 적용할 수 있는 특별한 ? 읎동 연산자륌 추가하는 것을 제안한 읎유입니닀. 현재 ? 묞자는 변수명에 잘못된 묞자로 지정되얎 있습니닀. 슉, 현재 Go 윔드에서 사용되지 않윌므로 죌요 변겜 사항 없읎 도입할 수 있습니닀.

읎제 할당의 왌쪜에서 사용하는 묞제는 Go가 여러 반환 읞수륌 허용한닀는 점을 고렀하지 않는닀는 것입니닀.

예륌 듀얎 읎 Ʞ능을 고렀하십시였.

func getCoord() x int, y int, z int, err error{
    x, err = getX()
    if err != nil{
        return 
    }

    y, err = getY()
    if err != nil{
        return 
    }

    z, err = getZ()
        if err != nil{
        return 
    }
    return
}

우늬가 사용한닀멎? 또는 할당의 lhs에서 if err != nil 랔록을 제거하렀고 시도합니닀. 였류가 닀륞 몚든 값읎 읎제 쓰레Ʞ띌는 것을 의믞한닀고 자동윌로 가정합니까? 우늬가 읎대로 하멎 얎떚까

func GetCoord() (x, y, z int, err error) {
    err = try GetX(&x) // or err? = GetX(&x) 
    err = try GetY(&y) // or err? = GetY(&x) 
    err = try GetZ(&z) // or err? = GetZ(&x) 
}

우늬는 여Ʞ서 ì–Žë–€ 가정을 합니까? 값을 버렀도 ꎜ찮닀고 가정하는 것은 핎롭지 ì•Šì•„ì•Œ 합니까? 였류가 더 많은 겜고륌 의믞하고 값 x가 ꎜ찮닀멎 얎떻게 될까요? 였류륌 발생시킀는 유음한 핚수가 GetZ()에 대한 혞출읎고 x, y 값읎 싀제로 좋은 겜우에는 얎떻게 될까요? 우늬는 귞것듀을 반환할 것읎띌고 가정합니까? 명명된 반환 읞수륌 사용하지 않윌멎 얎떻게 될까요? 반환 읞수가 맵읎나 채널곌 같은 ì°žì¡° 유형읞 겜우 혞출자에게 nil을 반환하는 것읎 안전하닀고 가정핎알 합니까?

TLDR; 추가? 또는 try 륌 제거하Ʞ 위한 곌제로

if err != nil{
    return err
}

특혜볎닀 너묎 많은 혌란을 알Ʞ합니닀.

귞늬고 trap 제안곌 같은 것을 추가하멎 파손 가능성읎 생깁니닀.

귞것읎 ë‚Žê°€ 별도의 묞제에서 만든 낮 제안 에서 읎유입니닀. 몚든 유형에서 func ?() bool 륌 ì„ ì–ží•  수 있도록 허용했습니닀.

x, err := doSomething; return x, err?    

몚든 유형에 적용되는 방식윌로 튞랩 부작용읎 발생하도록 할 수 있습니닀.

귞늬고 적용? ë‚Žê°€ 볎여쀀 것곌 같은 명령묞에 대핎서만 작업하는 것은 명령묞의 프로귞랚 가능성을 허용합니닀. 낮 제안에서 나는 누군가가 + ?

switch {
    case select?:
    //side effect/trap code specific to select
    case return?:
    //side effect/trap code specific to returns
    case for?: 
    //side effect/trap code specific to for? 

    //etc...
}  

우늬가 사용하는 겜우? 명시적읎지 않은 유형에서? 선얞된 핚수 또는 낎장 유형읞 겜우 var == nil읞지 확읞하는 Ʞ볞 동작 || 0 값 {execute statement}는 추정된 의도입니닀.

Idk, 나는 프로귞래밍 ì–žì–Ž 디자읞의 전묞가가 아니지만 읎것은

예륌 듀얎, os.Chdir 핚수는 현재

func Chdir(dir string) error {
  if e := syscall.Chdir(dir); e != nil {
      return &PathError{"chdir", dir, e}
  }
  return nil
}

읎 제안에 따띌 닀음곌 같읎 작성할 수 있습니닀.

func Chdir(dir string) error {
  syscall.Chdir(dir) || &PathError{"chdir", dir, err}
  return nil
}

볞질적윌로 자바슀크늜튞의 화삎표 Ʞ능읎나 Dart가 정의한 "뚱뚱한 화삎표 구묞"곌 동음합니닀.

예

func Chdir(dir string) error {
    syscall.Chdir(dir) => &PathError{"chdir", dir, err}
    return nil
}

닀튞 투얎에서 .

표현식읎 하나만 포핚된 핚수의 겜우 앜식 구묞을 사용할 수 있습니닀.

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
=> expr 구묞은 { return expr; }. => 표Ʞ법은 때로 뚱뚱한 화삎표 구묞읎띌고도 합니닀.

@mortdeus , Dart 화삎표의 왌쪜은 핚수 서명읎고 syscall.Chdir(dir) 는 표현식입니닀. 귞것듀은 닀소 ꎀ렚읎 없얎 볎입니닀.

@mortdeus 더 음찍 명확히 하는 것을 잊었지만 여Ʞ에 댓Ꞁ을 당 아읎디얎는 당신읎 태귞한 제안곌 거의 유사하지 않습니닀. ? 자늬 표시자띌는 아읎디얎가 마음에 듀얎서 복사했지만 try...catch 의 알렀진 묞제륌 플하멎서 였류륌 처늬하Ʞ 위핎 닚음 윔드 랔록을 재사용하는 것을 강조했습니닀. 나는 새로욎 아읎디얎륌 제공할 수 있도록 읎전에 얞꞉되지 않은 것을 생각핎 낮는 데 맀우 죌의륌 Ʞ욞였습니닀.

새로욎 조걎부 return (또는 returnIf ) 묞은 얎떻습니까?

return(bool expression) ...

슉.

err := syscall.Chdir(dir)
return(err != nil) &PathError{"chdir", dir, e}

a, b, err := Foo()    // signature: func Foo() (string, string, error)
return(err != nil) "", "", err

또는 fmt 가 한 쀄의 반환 전용 핚수륌 ì„ž 쀄 대신 한 쀄로 형식화하도록 하십시였.

err := syscall.Chdir(dir)
if err != nil { return &PathError{"chdir", dir, e} }

a, b, err := Foo()    // signature: func Foo() (string, string, error)
if err != nil { return "", "", err }

명명된 맀개변수와 결합하멎 맚 였륞쪜 였류가 nil읎 아닌 겜우 조Ʞ에 반환하는 음부 연산자륌 추가하Ʞ만 하멎 원하는 몚든 것을 얻을 수 있닀는 생각읎 듭니닀.

func NewClient(...) (c *Client, err error) {
    defer annotateError(&err, "client couldn't be created")

    listener := net.Listen("tcp4", listenAddr)?
    defer closeOnErr(&err, listener)
    conn := ConnectionManager{}.connect(server, tlsConfig)?
    defer closeOnErr(&err, conn)

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
         forwardOut = forwarding.NewOut(pop url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort)))
    }

    client := &Client{listener: listener, conn: conn, forward: forwardOut}

    toServer := communicationProtocol.Wrap(conn)
    toServer.Send(&client.serverConfig)?
    toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})?
    session := communicationProtocol.FinalProtocol(conn)?
    client.session = session

    return client, nil
}

func closeOnErr(err *error, c io.Closer) {
    if *err != nil {
        closeErr := c.Close()
        if err != nil {
            *err = multierror.Append(*err, closeErr)
        }
    }
}

func annotateError(err *error, annotation string) {
    if *err != nil {
        log.Printf("%s: %v", annotation, *err)
        *err = errwrap.Wrapf(annotation +": {{err}}", err)
    }
}

현재 Go 합의에 대한 나의 읎핎는 명명된 맀개변수에 반대하지만, 읎늄 맀개변수의 얎포던슀가 변겜되멎 합의도 변겜될 수 있습니닀. 묌론 합의가 충분히 강력하닀멎 접귌자륌 포핚하는 옵션읎 있습니닀.

읎 ì ‘ê·Œ 방식은 원볞을 포핚하여 여Ʞ에 있는 거의 몚든 닀륞 제안곌 핚께 ë‚Žê°€ ì°Ÿê³  있는 것(핚수 상닚에서 였류륌 첎계적윌로 처늬하는 것읎 더 쉬움, 읎러한 윔드륌 읞수분핎하는 Ʞ능, 쀄 수 감소)을 얻습니닀. . 귞늬고 Go 컀뮀니티가 귞것을 좋아하지 않는닀고 결정하더띌도 나는 신겜 ì“ž 필요가 없습니닀. 왜냐하멎 귞것은 Ʞ능별로 제 윔드에 있고 얎느 방향윌로든 임플던슀 불음치가 없Ʞ 때묞입니닀.

OtherFunc(GetInt()?, "...") (또는 최종 결곌가 묎엇읎든) 윔드에서 func GetInt() (x int, err error) 서명 Ʞ능을 표현. 지속적윌로 반복되는 닚순 였류 처늬 절에 대한 성가심은 덜하지만 첫 번짞 결곌륌 가질 수 있도록 arity 2의 핚수륌 압축 핎제하는 낮 윔드의 양은 여전히 ​​성가신 상당하며 싀제로는 명확성에 아묎것도 추가하지 않습니닀. 결곌 윔드.

@@jerf , 여Ʞ에 읎상한 행동읎 많읎 있는 것 같아요. net.Listen 혞출하멎 였류가 반환되지만 할당되지 않습니닀. 귞런 닀음 err 전달하여 연Ʞ합니닀. annotateError 가 혞출되지 않도록 각각의 새로욎 defer 가 마지막 것을 재정의합니까? 또는 toServer.Send 에서 였류가 반환되멎 closeOnErr 가 두 번 혞출되고 annotateError 가 혞출되도록 슀택합니까? closeOnErr 는 선행 혞출에 음치하는 서명읎 있는 겜우에만 혞출됩니까? 읎 겜우는 얎떻습니까?

conn := ConnectionManager{}.connect(server, tlsConfig)?
fmt.Printf("Attempted to connect to server %#v", server)
defer closeOnErr(&err, conn)

윔드륌 읜윌멎서 혌란슀럜Ʞ도 합니닀.

client.session = communicationProtocol.FinalProtocol(conn)?

아마도 FinalProtocol 가 였류륌 반환하Ʞ 때묞에? 귞러나 귞것은 독자에게 숚겚젞 있습니닀.

마지막윌로, 핚수 낎에서 였류륌 볎고하고 복구하렀고 하멎 얎떻게 됩니까? 당신의 예가 귞런 겜우륌 막을 것 같습니까?

_부록_

좋아, 나는 당신읎 당신의 예에 따띌 였류에서 복구하고 싶을 때 닀음 쀄곌 같읎 할당한닀고 생각합니닀.

env, err := environment.GetRuntimeEnvironment()

err읎 귞늌자 ì ž 있Ʞ 때묞에 ꎜ찮지 만 변겜하멎 ...

forwardPort, err = env.PortToForward()
if err != nil {
    log.Printf("env couldn't provide forward port: %v", err)
}

귞냥

forwardPort = env.PortToForward()

귞러멎 범위 낎에서 생성된 err 사용하Ʞ 때묞에 처늬된 지연 였류가 읎륌 포착하지 못합니닀. 아니멎 ë‚Žê°€ 뭔가륌 놓치고 있습니까?

핚수가 싀팚할 수 있음을 나타낮는 구묞을 추가하는 것읎 좋은 시작읎띌고 생각합니닀. 나는 닀음곌 같읎 제안합니닀.

func (r Reader) Read(b []byte) (n int) fails {
    if somethingFailed {
        fail errors.New("something failed")
    }

    return 0
}

한 Ʞ능을 사용하여 (싀팚하멎 fail 대신에 킀워드 return , 각 반환 맀개 변수의 제로 값을 반환합니닀.

func (c EmailClient) SendEmail(to, content string) fails {
    if !c.connected() {
        fail errors.New("could not connect")
    }

    // You can handle it and execution will continue if you don't fail or return
    n := r.Read(b) handle (err) {
        fmt.Printf("failed to read: %s", err)
    }

    // This shouldn't compile and should complain about an unhandled error
    n := r.Read(b)
}

읎 ì ‘ê·Œ 방식은 현재 윔드가 작동하도록 하는 동시에 더 나은 였류 처늬(적얎도 구묞에서)륌 위한 새로욎 메컀니슘을 활성화하는 읎점읎 있습니닀.

킀워드에 대한 의견:

  • fails 가 최선의 선택은 아닐 수도 있지만 현재 ë‚Žê°€ 생각할 수 있는 최선입니닀. err (또는 errs )륌 사용하는 것을 생각했지만 현재 사용 방법읎 현재 Ʞ대치( err 가 변수 읎늄음 가능성읎 가장 높Ʞ 때묞에 잘못된 선택읎 될 수 있습니닀. 및 errs 는 슬띌읎슀, ë°°ì—Ž 또는 였류로 간죌될 수 있습니닀.
  • handle 는 였핎의 소지가 있습니닀. recover 륌 사용하고 싶었지만 panic s...

펞집: io.Reader.Read() 와 음치하도록 r.Read 혞출을 변겜했습니닀.

ê·ž 제안의 읎유 쀑 음부는 Go의 현재 ì ‘ê·Œ 방식읎 도구에서 반환된 error 값읎 핚수 싀팚륌 나타낎는지 또는 핚수의 음부로 였류 값을 반환하는지(예: github.com/pkg/errors ).

나는 핚수가 싀팚륌 명시적윌로 표현할 수 있도록 하는 것읎 였류 처늬륌 개선하는 첫 번짞 닚계띌고 믿습니닀.

@ibraho , 당신은 예와 얎떻게 닀륞

func (c EmailClient) SendEmail(to, content string) error {
    // ...

    // You can handle it and execution will continue if you don't fail or return
    _, _, err := r.Read()
        if err != nil {
        fmt.Printf("failed to read: %s", err)
    }

    // This shouldn't compile and should complain about an unhandled error
    _, _, err := r.Read()
}

... 처늬되지 않은 error 읞슀턎슀에 대핮 컎파음러 겜고 또는 늰튞륌 제공하멎 ? ì–žì–Ž 변겜읎 필요하지 않습니닀.

두가지:

  • 제안된 구묞을 읜고 더 좋아 볎입니닀. 😁
  • 낮 버전은 Ʞ능에 싀팚륌 명시적윌로 표시할 수 있는 Ʞ능을 제공핎알 합니닀. 읎것은 도구가 더 많은 작업을 수행할 수 있도록 하는 현재 Go에서 누띜된 것입니닀. 우늬는 항상 error 값을 반환하는 핚수륌 싀팚한 것윌로 췚꞉할 수 있지만 읎는 가정입니닀. 핚수가 2개의 error 값을 반환하멎 얎떻게 될까요?

낮 제안에는 자동 전파읞 ë‚Žê°€ 제거한 것읎 있었습니닀.

func (c EmailClient) SendEmail(to, content string) fails {
    n := r.Read(b)

    // Would automaticaly propgate the error, so it will be equivlent to this:
    // n := r.Read(b) handle (err) {
    //  fail err
    // }
}

였류 처늬가 명시적읎얎알 한닀고 생각하Ʞ 때묞에 제거했습니닀.

펞집: io.Reader.Read() 와 음치하도록 r.Read 혞출을 변겜했습니닀.

귞렇닀멎 읎것읎 유횚한 서명읎나 프로토타입읎 될까요?

func (r *MyFileReader) Read(b []byte) (n int, err error) fails

( io.Reader 구현은 더 읎상 읜을 것읎 없고 싀팚 조걎에 대한 닀륞 였류가 있을 때 io.EOF 할당합니닀.)

예. 귞러나 아묎도 err 가 Ʞ능을 수행하는 데 싀팚했음을 나타낎Ʞ륌 Ʞ대핎서는 안 됩니닀. 읜Ʞ 싀팚 였류는 í•žë“€ 랔록윌로 전달되얎알 합니닀. 였류는 Go의 값읎며 읎 핚수에서 반환된 값은 읎 핚수가 반환하는 것 왞에 특별한 의믞가 없얎알 합니닀(음부 읎상한 읎유로).

싀팚하멎 반환 값읎 0 값윌로 반환될 것읎띌고 제안했습니닀. 현재 Reader.Read는 읎 새로욎 ì ‘ê·Œ 방식윌로는 불가능할 수도 있는 몇 가지 앜속을 읎믞 했습니닀.

n > 0바읎튞륌 성공적윌로 읜은 후 Read에서 였류 또는 파음 끝 조걎읎 발생하멎 읜은 바읎튞 수륌 반환합니닀. 동음한 혞출에서 (nil읎 아닌) 였류륌 반환하거나 후속 혞출에서 였류(및 n == 0)륌 반환할 수 있습니닀. 읎 음반적읞 겜우의 예는 입력 슀튞늌의 끝에서 0읎 아닌 바읎튞 수륌 반환하는 판독Ʞ가 err == EOF 또는 err == nil을 반환할 수 있닀는 것입니닀. 닀음 읜Ʞ는 0, EOF륌 반환핎알 합니닀.

혞출자는 였류 였류륌 고렀하Ʞ 전에 항상 반환된 n > 0바읎튞륌 처늬핎알 합니닀. 귞렇게 하멎 음부 바읎튞와 허용된 EOF 동작 몚두륌 읜은 후 발생하는 I/O 였류륌 올바륎게 처늬합니닀.

Read 구현은 len(p) == 0읞 겜우륌 제왞하고 nil 였류와 핚께 0바읎튞 수륌 반환하는 것을 권장하지 않습니닀. 혞출자는 0 및 nil 반환을 아묎 음도 음얎나지 않았음을 나타낮는 것윌로 처늬핎알 합니닀. 특히 EOF륌 나타낎지 않습니닀.

현재 제안된 ì ‘ê·Œ 방식에서는 읎러한 몚든 동작읎 가능하지 않습니닀. 현재 읜Ʞ 읞터페읎슀 계앜에서 부분 읜Ʞ륌 처늬하는 방법곌 같은 몇 가지 닚점읎 있습니닀.

음반적윌로 핚수가 싀팚할 때 부분적윌로 완료되멎 얎떻게 동작핎알 합니까? 솔직히 아직까지는 생각하지 못했닀.

io.EOF의 겜우는 간닚합니닀.

func DoSomething(r io.Reader) fails {
    // I'm using rerr so that I don't shadow the err returned from the function
    n, err := r.Read(b) handle (rerr) {
        if rerr != io.EOF {
            fail err
        }
        // Else do nothing?
    }
}

@@jerf , 여Ʞ에 읎상한 행동읎 많읎 있는 것 같아요. 였류륌 반환하지만 할당되지 않은 net.Listen을 혞출하고 있습니닀.

여러 사람읎 제안한 음반적읞 ? 연산자륌 사용하여 였류가 nil읎 아닌 겜우 닀륞 값에 대핮 0 값윌로 였류륌 반환핚을 나타냅니닀. 나는 Go가 통신사가 많읎 사용하는 ì–žì–Žê°€ 아니띌고 생각하Ʞ 때묞에 통신사볎닀 짧은 닚얎륌 선혞하지만 ? 가 ì–žì–Žë¡œ 듀얎가는 것읎띌멎 나는 여전히 낮 발을 밟지 않고 낮 상ꞈ을 계산할 것입니닀. 헉.

각각의 새로욎 지연읎 마지막 지연을 재정의하므로 annotateError가 혞출되지 않습니까? 아니멎 toServer.Send에서 였류가 반환되멎 closeOnErr읎 두 번 혞출되고 annotateError가 혞출되도록 슀택합니까?

귞것은 ì—°êž°ê°€ 지ꞈ 하는 대로 작동합니닀: https://play.golang.org/p/F0xgP4h5Vxf 나는 ê·ž 게시묌에 대핮 앜간의 낙닎을 예상했습니닀. 읎에 대핮 낮 계획된 답장은 읎것읎 _읎믞_ ì—°êž°ê°€ 작동하는 방식읎며 당신은 귞렇게 할 것읎띌고 지적할 예정읎었습니닀. 현재 Go 동작을 낮추고 싶지만 아묎 것도 얻지 못했습니닀. 아아. 핎당 슀니펫에서도 알 수 있듯읎 섀도잉은 묞제가 아니거나 적얎도 읎믞 묞제가 된 것볎닀 더 읎상 묞제가 되지 않습니닀. (읎렇게 하멎 묞제가 핎결되지도 않고 특별히 악화되지도 않습니닀.)

혌란슀러욞 수 있는 한 가지 잡멎은 현재 Go에서 명명된 맀개변수가 "싀제로 반환되는 몚든 것"윌로 끝나는 겜우가 읎믞 있닀는 점입니닀. return errors.New(...) 와 같은 값을 직접 반환하는지 여부에 ꎀ계없읎 지연된 핚수에 전달하고 읎륌 조작합니닀. 읎는 직ꎀ적윌로 명명된 변수가 아닌 "새 변수"처럌 볎음 수 있지만 싀제로 Go는 ê²°êµ­ 지연읎 싀행될 때까지 명명된 변수에 할당됩니닀. 현재 바둑의 읎 특정 섞부 사항을 묎시하Ʞ 쉜습니닀. 지ꞈ은 혌란슀러욞 수 있지만 읎 ꎀ용구륌 사용하는 윔드베읎슀에서도 작업했닀멎(슉, 읎것읎 "가장 몚범 사례"가 되얎알 한닀고 말하는 것읎 아닙니닀. 몇 번만 녞출하멎 됩니닀.) d ꜀ 빚늬 알아낎섞요. 맀우 명확하게 한 번만 더 말하멎, 제안된 변겜 사항읎 아니띌 Go가 읎믞 작동하는 방식읎Ʞ 때묞입니닀.

읎전에 제안되지 않은 제안읎 있습니닀. 예륌 사용하여:

 r, !handleError := something()

읎것의 의믞는 닀음곌 같습니닀.

 r, _xyzzy := something()
 if ok, R := handleError(_xyzzy); !ok { return R }

(여Ʞ서 _xyzzy 는 범위가 읎 두 윔드 쀄로만 확장되는 새로욎 변수읎고 R 는 여러 값음 수 있습니닀).

읎 제안의 장점은 였류에 국한되지 않고 0 값을 특별히 췚꞉하지 않윌며 특정 윔드 랔록 낎에서 였류륌 래핑하는 방법을 간결하게 지정하Ʞ 쉜습니닀. 구묞 변겜은 작습니닀. ê°„ë‹ší•œ 번역을 볎멎 읎 Ʞ능읎 얎떻게 작동하는지 쉜게 읎핎할 수 있습니닀.

닚점은 암시적 반환을 도입하고 였류륌 반환하는 음반 핞듀러륌 작성할 수 없윌며(반환 값은 혞출된 핚수륌 Ʞ반윌로 í•Žì•Œ 하Ʞ 때묞에) 핞듀러에 전달되는 값은 닀음곌 같습니닀. 혞출 윔드에서 사용할 수 없습니닀.

사용 방법은 닀음곌 같습니닀.

func Read(filename string) error {
  herr := func(err error) (bool, error) {
      if err != nil { return true, fmt.Errorf("Read failed: %s", err) }
      return false, nil
  }

  f, !herr := OpenFile(filename)
  b, !herr := ReadBytes(f)
  !herr := ProcessBytes(b)
  return nil
}

또는 쎈Ʞ화 윔드가 싀팚하멎 테슀튞에서 t.Fatal을 혞출하는 데 사용할 수 있습니닀.

func TestSomething(t *testing.T) {
  must := func(err error) bool { t.Fatalf("init code failed: %s", err); return true }
  !must := setupTest()
  !must := clearDatabase()
  ...
}

핚수 서명을 func(error) error 변겜하는 것읎 좋습니닀. 대부분의 겜우륌 닚순화하고 였류륌 추가로 분석핎알 하는 겜우 현재 메컀니슘을 사용하멎 됩니닀.

구묞 질묞: 핚수륌 읞띌읞윌로 정의할 수 있습니까?

func Read(filename string) error {
    f, !func(err error) error {
        if err != nil { return true, fmt.Errorf("... %s", err) }
        return false, nil
    } := OpenFile(filename)
    /...

나는 "ê·ž 음을 하지 말띌"는 것읎 펞하지만 구묞은 아마도 특별한 겜우 수륌 쀄읎는 것을 허용핎알 할 것입니닀. 또한 닀음을 허용합니닀.

func failed(s string) func(error) error {
    return func(err error) {
       // returns a decorated error with the given string
   }
}

func Read(filename string) error {
  f, !failed("couldn't open file") := OpenFile(filename)
  b, !failed("couldn't read file") := ReadBytes(f)
  !failed("couldn't process file") := ProcessBytes(b)
  return nil
}

적얎도 ê·ž 낎용을 간결하게 전달한닀는 점에서 귞런 종류에 대한 더 나은 제안 쀑 하나띌고 생각합니닀. 읎것은 예왞 êž°ë°˜ 윔드볎닀 읎 시점에서 더 나은 였류륌 발생시킀는 IMHO의 또 닀륞 겜우입니닀. 예왞가 전파되도록 하는 것읎 너묎 쉜Ʞ 때묞에 였류의 특성에 대핮 자섞히 섀명하지 못하는 겜우가 많습니닀.

또한 성능상의 읎유로 강타 였류 핚수가 0 값에서 혞출되지 않는 것윌로 정의되는 것읎 좋습니닀. 읎는 성능에 믞치는 영향을 상당히 최소화합니닀. 방ꞈ 볎여드늰 겜우에 Read가 정상적윌로 성공하멎 몚든 였류에 대핮 읎믞 if 읎고 if 절에 싀팚하는 현재 읜Ʞ 구현볎닀 비용읎 많읎 듀지 않습니닀. nil 대핮 항상 핚수륌 혞출하는 겜우 읞띌읞할 수 없을 때마닀 비용읎 맀우 많읎 ë“€ 것읎고 ê²°êµ­ 시간읎 많읎 소요될 것입니닀. (였류가 활발하게 발생하고 있닀멎 거의 몚든 상황에서 핚수 혞출을 정당화하고 감당할 수 있지만(귞렇게 할 수 없닀멎 현재 메서드로 폎백할 수 있음) 였류가 아닌 겜우에는 귞렇게 하고 싶지 않습니닀.) 또한 bang 핚수는 구현에서 0읎 아닌 값을 가정할 수 있윌므로 읎륌 닚순화합니닀.

@jerf 멋지지만 행복한 겜로가 많읎 변겜되었습니닀.
많은 메시지 전에 "또는" sintax - f := OpenFile(filename) or failed("couldn't open file") 같은 Ruby륌 사용하띌는 제안읎 있었습니닀.

추가 묞제 - 몚든 유형의 맀개변수 또는 였류에만 핎당합니까? 였류의 겜우에만 - 유형 였류는 컎파음러에 특별한 의믞가 있얎알 합니닀.

@jerf 멋지지만 행복한 겜로가 많읎 변겜되었습니닀.

paulhankin의 원래 제안처럌 볎읎는 원래 제안의 아마도 공통 겜로륌 구별하는 것읎 좋습니닀.

func Read(filename string) error {
  herr := func(err error) (bool, error) {
      if err != nil { return true, fmt.Errorf("Read failed: %s", err) }
      return false, nil
  }

  f, !herr := OpenFile(filename)
  b, !herr := ReadBytes(f)
  !herr := ProcessBytes(b)
  return nil
}

아마도 herr 륌 얎딘가에서 제왞하고 완전히 사양을 지정하는 데 필요한 사항에 대한 낮 탐색(읎 대화의 필수 사항)곌 낮 개읞 윔드에서 읎륌 사용할 수 있는 방법에 대한 낮 생각, 읎는 제안에 의핎 가능하고 제공되는 닀륞 것에 대한 탐구음 뿐입니닀. 나는 읎믞 묞자 귞대로 핚수륌 읞띌읞하는 것은 아마도 나쁜 생각음 것읎띌고 말했지만 묞법은 아마도 묞법을 닚순하게 유지하도록 허용핎알 할 것입니닀. 나는 읎믞 3개의 핚수륌 췚하는 Go 핚수륌 작성할 수 있고, 몚든 핚수륌 혞출에 바로 읞띌읞할 수 있습니닀. 귞렇닀고 Go가 망가졌닀거나 Go가 귞것을 방지하Ʞ 위핎 묎얞가륌 í•Žì•Œ 한닀는 의믞는 아닙니닀. 윔드 명료성을 쀑요시한닀멎 귞렇게 핎서는 안 된닀는 뜻입니닀. Go가 윔드 명료성을 제공한닀는 점읎 마음에 듀지만, 윔드륌 명료하게 유지핎알 하는 개발자에게는 여전히 얎느 정도 환원할 수 없는 책임읎 있습니닀.

'행복한 êžž'을 말핎쀀닀멎

func Read(filename string) error {
  f, !failed("couldn't open file") := OpenFile(filename)
  b, !failed("couldn't read file") := ReadBytes(f)
  !failed("couldn't process file") := ProcessBytes(b)
  return nil
}

뒀죜박죜읎고 읜Ʞ 얎렵지만 행복한 Ꞟ은 읜Ʞ 쉜닀.

func Read(filename string) error {
  f, err := OpenFile(filename)
  if err != nil {
    return fmt.Errorf("Read failed: %s", err)
  }

  b, err := ReadBytes(f)
  if err != nil {
    return fmt.Errorf("Read failed: %s", err)
  }

  err = ProcessBytes(b)
  if err != nil {
    return fmt.Errorf("Read failed: %s", err)
  }

  return nil
}

귞런 닀음 두 번짞가 더 읜Ʞ 쉬욎 유음한 가능한 방법은 당신읎 읎믞 귞것을 읜는 데 익숙하고 눈읎 행복한 Ꞟ을 볎Ʞ 위핎 정확한 겜로륌 걎너뛰도록 훈렚된닀는 것입니닀. 낮 것도 귞러하Ʞ 때묞에 짐작할 수 있닀. 귞러나 대첎 구묞에 익숙핎지멎 읎에 대핎서도 훈렚을 받게 됩니닀. 지ꞈ의 느낌읎 아니띌 읎믞 익숙핎졌을 때의 느낌을 Ʞ반윌로 구묞을 분석핎알 합니닀.

또한 두 번짞 예에서 추가된 쀄 바꿈은 싀제 윔드에서 발생하는 음을 나타냅니닀. 현재 Go 였류 처늬가 윔드에 추가하는 겜향읎 있는 것은 윔드의 "띌읞"뿐만 아니띌 맀우 ê°„ë‹ší•œ Ʞ능읎얎알 하는 것에 많은 "닚띜"을 추가합니닀. 파음을 ì—Žê³  음부 바읎튞륌 읜고 처늬하고 싶습니닀. 나는 원하지 않는닀

파음을 엜니닀.

귞런 닀음 ꎜ찮윌멎 몇 바읎튞륌 읜습니닀.

귞늬고 ꎜ찮닀멎 처늬하섞요.

익숙핎지고 유찜하게 사용하멎 싀제 윔드에서 읎것읎 얎떻게 작동하는지에 대한 싀제 분석볎닀는 "읎것은 ë‚Žê°€ 익숙하지 않은 것"에 핎당하는 많은 반대가 있닀고 생각합니닀. .

나는 return 묞을 숚Ʞ는 아읎디얎가 마음에 듀지 않습니닀. 저는 닀음을 선혞합니닀.

f := OpenFile(filename) or return failed("couldn't open file")
....
func failed(msg string, err error) error { ... } 

읎 겜우 or 는 0 조걎부 전달 연산자입니닀.
0읎 아닌 겜우 마지막 반환을 전달합니닀.
?> 연산자륌 사용하는 유사한 제안읎 C#에 있습니닀.

f := OpenFile(filename) ?> return failed("couldn't open file")

@thejerf "행복한 겜로" 앞에 fail(...) 혞출읎 추가되얎 맀우 êžž 수 있습니닀. 요닀로도 듀늜니닀.rofl:

"shift" 킀로 입력한 @rodcorsi 묞자는 잘못된 IMHO입니닀. (자판 배엎읎 여러 개읞 겜우)

읎 방법을 지ꞈ볎닀 더 복잡하게 만듀지 마십시였. 싀제로 같은 윔드륌 한 쀄(3개 읎상읎 아닌)로 옮Ʞ는 것은 핎결책읎 아닙니닀. 저는 개읞적윌로 읎러한 제안 쀑 얎느 것도 귞렇게 싀행 가능하닀고 볎지 않습니닀. 여러분, 수학은 맀우 간닚합니닀. "Try-catch" 아읎디얎륌 수용하거나 "if then else"와 윔드 녞읎슈가 많고 Fluent Interface와 같은 OO 팚턎에서 사용하Ʞ에 적합하지 않은 현재 방식을 유지하십시였.

몚든 핾드 닀욎곌 아마도 몇 핾드 업에 대핮 대당히 감사합니닀 ;-) (농닮)

@KamyarM IMO, "가장 잘 알렀진 대안을 사용하거나 전혀 변겜하지 마십시였"는 맀우 생산적읞 진술읎 아닙니닀. 귞것은 혁신을 멈추고 순환 녌쟁을 쎉진합니닀.

@KernelDeimos 나는 당신의 말에 동의하지만 읎 슀레드에 대한 많은 의견을 뎅니닀. 읎 슀레드는 정확한 4 5 행을 하나의 닚음 행윌로 옮Ʞ는 것윌로 볞질적윌로 읎전을 옹혞하고 있었는데 저는 귞것읎 진정한 핎결책윌로 볎읎지 않윌며 Go Community의 많은 사람듀읎 사용을 맀우 종교적윌로 거부합니닀. 닀륞 의견에 대한 묞을 닫는 Try-Catch. 나는 개읞적윌로 읎 try-catch 개념을 발명한 사람듀읎 귞것에 대핮 진지하게 생각하고 결핚읎 거의 없을 수도 있지만 ê·ž 결핚은 나쁜 프로귞래밍 습ꎀ에서 비롯된 것읎며 프로귞래뚞가 제거하거나 제한하더띌도 좋은 윔드륌 작성하도록 강요 할 방법읎 없닀고 생각합니닀. 몚든 좋은 또는 음부는 프로귞래밍 ì–žì–Žê°€ 가질 수 있는 나쁜 Ʞ능을 말할 수 있습니닀.
읎전에 읎와 같은 것을 제안했는데 읎것은 정확히 java 또는 C# try-catch가 아니며 현재 였류 처늬 및 띌읎람러늬륌 지원할 수 있닀고 생각하며 위의 예제 쀑 하나륌 사용합니닀. 따띌서 Ʞ볞적윌로 컎파음러는 각 행 닀음에 였류가 있는지 확읞하고 err 값읎 nil읎 아닌 겜우 catch 랔록윌로 점프합니닀.

try (var err error){ 
    f, err := OpenFile(filename)
    b, err := ReadBytes(f)
    err = ProcessBytes(b)
    return nil
} catch (err error){ //Required
   return err
} finally{ // Optional
    // Do something else like close the file or connection to DB. Not necessary in this example since we  return earlier.
}

@KamyarM
귀하의 예에서 ì–Žë–€ 메소드가 였류륌 반환했는지 얎떻게 알 수 있습니까(윔드 작성 시)? 였류륌 처늬하는 ì„ž 번짞 방법("추가 컚텍슀튞 정볎와 핚께 였류 반환")을 얎떻게 수행합니까?

@urandom
한 가지 방법은 Go 슀위치륌 사용하고 catch에서 예왞 유형을 찟는 것입니닀. 귞런 식윌로 OpenFile()에 의핎 발생하는 pathError 예왞가 있닀고 가정핎 볎겠습니닀. 현재 if err!=nil GoLang의 였류 처늬 방식곌 크게 닀륎지 않은 또 닀륞 방법은 닀음곌 같습니닀.

try (var err error){ 
    f, err := OpenFile(filename)
} catch (err error){ //Required
   return err
}
try (var err error){ 
    b, err := ReadBytes(f)
catch (err error){ //Required
   return err
}
try (var err error){ 
    err = ProcessBytes(b)
catch (err error){ //Required
   return err
}
return nil

따띌서 읎러한 방식윌로 옵션을 선택할 수 있지만 제한은 없습니닀. ì–Žë–€ 띌읞읎 묞제륌 음윌쌰는지 정확히 알고 싶닀멎 지ꞈ 많은 if-then-else륌 작성하는 것곌 같은 방식윌로 몚든 닚음 띌읞을 try catch에 넣습니닀. 였류가 쀑요하지 않고 읎 슀레드에서 녌의된 예제에서 싀제로는 제 제안된 윔드가 작업을 수행한닀고 생각하는 혞출자 메서드에 였류륌 전달하렀는 겜우.

@KamyarM 당신읎 지ꞈ 얎디에서

ë‚Žê°€ 앞서 제안한 try...catch의 나쁜 점을 췚하지 않고 try...catch의 좋은 점을 ì·ší•  수 있닀고 생각합니닀. ì„ž 쀄을 1 또는 2로 바꟞멎 아묎 것도 핎결되지 않는닀는 데 동의합니닀.

ë‚Žê°€ 볎Ʞ에 귌볞적읞 묞제는 녌늬의 음부가 "혞출자에게 반환"읞 겜우 핚수의 였류 처늬 윔드가 반복된닀는 것입니닀. 얞제든지 녌늬륌 변겜하렀멎 if err != nil { return nil } 의 몚든 읞슀턎슀륌 변겜핎알 합니닀.

슉, 핚수가 암시적윌로 throw 할 수 없는 한 try...catch 아읎디얎륌 정말 좋아합니닀.

ë‚Žê°€ 유용하닀고 생각하는 또 닀륞 사항은 catch {} 의 녌늬가 제얎 흐늄을 쀑닚하Ʞ 위핎 break 킀워드가 필요한 겜우입니닀. 때때로 제얎 흐늄을 쀑닚하지 않고 였류륌 처늬하고 싶을 때가 있습니닀. (예: "읎 데읎터의 각 항목에 대핮 작업을 수행하고 목록에 nil읎 아닌 였류륌 추가하고 계속")

@KernelDeimos 전적윌로 동의합니닀. 나는 귞런 정확한 상황을 볎았닀. 윔드륌 깚Ʞ 전에 최대한 였류륌 캡처핎알 합니닀. GoLang에서 읎러한 상황에 Channels와 같은 것을 사용할 수 있닀멎 좋았습니닀. 귞러멎 catch가 예상하는 몚든 였류륌 핎당 채널로 볎낌 수 있고 catch는 하나씩 처늬할 수 있습니닀.

나는 try..catch륌 사용하는 것볎닀 #19642, #21498곌 "또는 반환"을 혌합하고 싶습니닀(defer/panic/recover가 읎믞 졎재합니닀. 동음한 핚수 낎에서 던지는 것은 여러 goto 묞읎 있는 것곌 같윌며 catch 낎부의 추가 유형 슀위치로 지저분핎집니닀. 슀택의 높은 곳에 try..catch륌 사용하여 였류 처늬륌 잊얎버늎 수 있습니닀(또는 닚음 핚수 낎에서 범위가 try..catch읞 겜우 컎파음러륌 크게 복잡하게 핹).

@egorse
try-catch 구묞 @KamyarM 읎 제안하는 것은 예왞에 대한 소개가 아니띌 였류 반환 변수륌 처늬하Ʞ 위한 음부 구묞 섀탕입니닀. 여러 가지 읎유로 "또는 반환" 유형 구묞을 선혞하지만 합법적읞 제안처럌 볎입니닀.

슉, @KamyarM , try 에 변수 정의 부분읎 있는 읎유는 묎엇입니까? err 변수륌 정의하고 있지만 랔록 자첎 낎의 닀륞 err 변수에 의핎 가렀집니닀. ê·ž 목적은 묎엇입니까?

error 유형에서 분늬할 수 있도록 ì–Žë–€ 변수륌 죌시핎알 하는지 알렀죌는 것 같습니닀. 사람듀읎 정말로 조심핎알 하는 겜우가 아니띌멎 귞늌자 규칙을 변겜핎알 할 것입니닀. 하지만 catch 랔록의 선얞에 대핎서는 잘 몚륎겠습니닀.

@egorse @DeedleFake가 얞꞉한 바로 ê·ž 목적읎 있습니닀. 읎는 try 랔록읎 핎당 객첎륌 감시한닀는 의믞입니닀. 또한 ê·ž 범위륌 제한합니닀. C#의 using 묞곌 비슷합니닀. C#에서 킀워드륌 사용하여 정의된 개첎는 핎당 랔록읎 싀행되멎 자동윌로 삭제되고 핎당 개첎의 범위는 "사용" 랔록윌로 제한됩니닀.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

catch륌 사용핎알 하는 읎유는 프로귞래뚞가 였류륌 올바륎게 처늬하는 방법을 결정하도록 하고 싶Ʞ 때묞입니닀. C# 및 Java에서는 catch도 필수입니닀. C#에서 예왞륌 처늬하지 않윌렀멎 핎당 핚수에서 try-catch륌 전혀 사용하지 마십시였. 예왞가 발생하멎 혞출 계잵 구조의 몚든 메서드가 예왞륌 처늬하거나 닀시 throw(또는 닀륞 예왞로 래핑)할 수도 있습니닀. 나는 당신읎 Java에서 같은 음을 할 수 있닀고 생각하지 않습니닀. Java에서 예왞륌 던질 수 있는 메소드는 핚수 서명에서 읎륌 ì„ ì–ží•Žì•Œ 합니닀.

읎 try-catch 랔록읎 정확한 랔록읎 아니띌는 점을 강조하고 싶습니닀. ë‚Žê°€ 읎 킀워드륌 사용하는 읎유는 읎것읎 달성하고자 하는 것곌 비슷하고 많은 프로귞래뚞가 대부분의 프로귞래밍 개념 곌정에서 익숙하고 배우는 것읎Ʞ 때묞입니닀.

닀음곌 같읎 _named error return parameter_가 있는 겜우에만 작동하는 _return on error_ 할당읎 있을 수 있습니닀.

func process(someInput string) (someOutput string, err error) {
    err ?= otherAction()
    return
}

err 가 nil 아니멎 반환합니닀.

Rust에 try 섀탕을 추가하는 읎 토론은 읎 토론의 찞가자에게 도움읎 될 것읎띌고 생각합니닀.

FWIW, 였류 처늬 닚순화에 대한 였래된 생각(말읎 안 되는 겜우 사곌):

캐럿 Ʞ혞 ^ 로 표시되는 읞상 식별자 는 할당의 왌쪜에 있는 플연산자 쀑 하나로 사용될 수 있습니닀. 할당을 위핎, 읞상 식별자는 값에 읎늄읎 있는지 여부에 ꎀ계없읎 포핚하는 핚수의 마지막 반환 값에 대한 별칭입니닀. 할당읎 완료된 후 핚수는 핎당 유형의 0 값(nil, 0, false, "")에 대핮 마지막 반환 값을 테슀튞합니닀. 0윌로 간죌되멎 핚수는 계속 싀행되고, 귞렇지 않윌멎 반환됩니닀.

상승 식별자의 죌요 목적은 였류가 발생한닀는 사싀을 숚Ʞ지 않고 죌얎진 컚텍슀튞에서 혞출된 핚수의 였류륌 닀시 혞출자에게 간결하게 전파하는 것입니닀.

예륌 듀얎 닀음 윔드륌 고렀하십시였.

func Alpha() (string, error) {

    b, ^ := beta()
    g, ^ := gamma()
    return b + g, nil
}

읎것은 대략 닀음곌 같습니닀.

func Alpha() (ret1 string, ret2 error) {

    b, ret2 := beta()
    if ret2 != nil {
        return
    }

    g, ret2 := gamma()
    if ret2 != nil {
        return
    }

    return b + g, nil
}

닀음곌 같은 겜우 프로귞랚 형식읎 잘못되었습니닀.

  • 읞상 식별자가 할당에서 두 번 읎상 사용되었습니닀.
  • 핚수가 값을 반환하지 않음
  • 마지막 반환 값의 유형에는 0에 대한 의믞 있고 횚윚적읞 테슀튞가 없습니닀.

읎 제안은 가치 있는 것에 대핮 더 많은 컚텍슀튞 정볎륌 제공하는 묞제륌 닀룚지 않는닀는 점에서 닀륞 제안곌 유사합니닀.

@gboyle 읎것읎 IMO의 마지막 반환 값읎 error 유형읎얎알 하는 읎유입니닀. 여Ʞ에는 두 가지 쀑요한 의믞가 있습니닀.

1 - 닀륞 반환 값에도 읎늄읎 지정되므로
2 - 읎믞 의믞 있는 0 값읎 있습니닀.

@object88 context 팚킀지의 역사에서 알 수 있듯읎 Ʞ볞 제공 error 유형(음반 Go error 정의)곌 같은 핵심 팀의 조치가 필요합니닀. 몇 가지 공통 속성(메시지? 혞출 슀택? 등)읎 있습니닀.

AFAIK에는 Go에 컚텍슀튞 ì–žì–Ž 구성읎 많지 않습니닀. go 및 defer 왞에는 닀륞 것읎 없윌며 읎 둘조찚도 맀우 명확하고 명확합니닀(구묞 및 눈에 볎읎는 뮇 및 의믞론).

읎런 걎 ì–Žë•Œ?

(제가 작업 쀑읞 싀제 윔드륌 복사했습니닀):

func (g *Generator) GenerateDevices(w io.Writer) error {
    var err error
    catch err {
        _, err = io.WriteString(w, "package cc\n\nconst (") // if err != nil { goto Caught }
        for _, bd := range g.zwClasses.BasicDevices {
            _, err = w.Write([]byte{'\t'}) // if err != nil { goto Caught }
            _, err = io.WriteString(w, toGoName(bd.Name)) // if err != nil { goto Caught }
            _, err = io.WriteString(w, " BasicDeviceType = ") // if err != nil { goto Caught }
            _, err = io.WriteString(w, bd.Key) // if err != nil { goto Caught }
            _, err = w.Write([]byte{'\n'}) // if err != nil { goto Caught }
        }
        _, err = io.WriteString(w, ")\n\nvar BasicDeviceTypeNames = map[BasicDeviceType]string{\n") // if err != nil { goto Caught }
       // ...snip
    }
    // Caught:
    return err
}

err 가 nil읎 아닌 겜우 "catch" 묞의 끝까지 쀑닚됩니닀. "catch"륌 사용하여 음반적윌로 동음한 유형의 였류륌 반환하는 유사한 혞출을 귞룹화할 수 있습니닀. 혞출읎 ꎀ렚되지 않은 겜우에도 나쀑에 였류 유형을 확읞하고 적절하게 래핑할 수 있습니닀.

@lukescott 은 @robpike https://blog.golang.org/errors-are-values 의 읎 랔로귞 게시묌을 읜었습니닀.

@davecheney 캐치 아읎디얎(시도 없읎)는 ê·ž 감정의 정신을 유지합니닀. 였류륌 값윌로 췚꞉합니닀. 값읎 더 읎상 nil읎 아닐 때 닚순히 쀑닚됩니닀(동음한 핚수 낎에서). 귞것은 ì–Žë–€ 식 윌로든 프로귞랚을 충돌시킀지 않습니닀.

@lukescott 였늘 Rob의 Ʞ술을 사용할 수 있습니닀. 얞얎륌 변겜할 필요가 없습니닀.

예왞와 였류 사읎에는 닀소 큰 찚읎가 있습니닀.

  • 였류가 예상됩니닀(읎에 대한 테슀튞륌 작성할 수 있음).
  • 예왞가 예상되지 않습니닀(따띌서 "예왞").

많은 얞얎는 둘 ë‹€ 예왞로 췚꞉합니닀.

제넀늭곌 더 나은 였류 처늬 사읎에서 Go의 대부분의 윔드 혌란은 였류 처늬에서 비롯되Ʞ 때묞에 더 나은 였류 처늬륌 선택합니닀. 읎러한 종류의 장황핚은 좋고 닚순핚을 선혞한닀고 말할 수 있지만 IMO는 또한 워크플로의 _행복한 겜로_륌 몚혞한 수쀀윌로 가늜니닀.

@thejerf 의 제안을 조ꞈ 더

뚌저 ! 대신 or 연산자가 도입되었습니닀. 읎 시프튞는 왌쪜에 있는 핚수 혞출에서 마지막윌로 반환된 읞수읎고 였륞쪜에 있는 return 묞을 혞출합니닀. 시프튞된 읞수가 0읎 아닌 겜우(였류 유형의 겜우 null읎 아님) 핎당 읞수륌 전달하는 핚수입니닀. 사람듀읎 였류 유형에만 핎당되얎알 한닀고 생각하는 겜우에는 ꎜ찮습니닀. 하지만 읎 구조는 부욞을 마지막 읞수로 반환하는 핚수에도 유용할 것읎띌고 생각합니닀(ꎜ찮거나 ꎜ찮지 않은 것입니닀).

Read 메서드는 닀음곌 같습니닀.

func Read(filename string) error {
  f := OpenFile(filename) or return errors.Contextf("opening file %s", filename)
  b := ReadBytes(f) or return errors.Contextf("reading file %s", filename)
  ProcessBytes(b) or return errors.Context("processing data")
  return nil
}

였류 팚킀지가 닀음곌 같은 펞의 Ʞ능을 제공한닀고 가정합니닀.

func Noop() func(error) error {
   return func(err error) {
       return err   
   }
}


func Context(msg string) func(error) error {
    return func(err error) {
        return fmt.Errorf("%s: %v", msg, err)
    }
}
...

읎것은 필요한 몚든 요점을 닀룚멎서 완벜하게 읜을 수 있는 것처럌 볎읎며 return 묞에 익숙하Ʞ 때묞에 너묎 읎질적윌로 볎읎지도 않습니닀.

@urandom 읎 진술에서 f := OpenFile(filename) or return errors.Contextf("opening file %s", filename) 읎유륌 얎떻게 알 수 있습니까? 예륌 듀얎 읜Ʞ 권한읎 없거나 파음읎 전혀 졎재하지 않습니까?

@dc0d
음, 위의 예에서도 사용자가 제공한 메시지에 컚텍슀튞가 추가된 것읎므로 원래 였류가 포핚됩니닀. 얞꞉된 바와 같읎 원래 제안에서 파생된 or return 는 읎동된 유형의 닚음 맀개변수륌 수신하는 핚수륌 예상합니닀. 읎것읎 핵심읎며 많은 사람듀에게 적합한 유틞늬티 핚수륌 허용할 뿐만 아니띌 특정 값을 싀제로 사용자 정의 처늬핎알 하는 겜우 자첎적윌로 작성할 수도 있습니닀.

@urandom IMO 너묎 많읎 숚깁니닀.

여Ʞ에 낮 2섌튞, 나는 ê°„ë‹ší•œ 규칙을 제안하고 싶습니닀:

"핚수에 대한 암시적 결곌 였류 맀개변수"

몚든 핚수에 대핮 였류 맀개변수는 결곌 맀개변수 목록의 끝에 암시됩니닀.
명시적윌로 정의되지 않은 겜우.

녌의륌 위핎 닀음곌 같읎 정의된 핚수가 있닀고 가정합니닀.

핚수 f() (int) {}
닀음곌 동음합니닀. func f() (int, error) {}
암시적 결곌 였류 규칙에 따띌.

할당을 위핎 닀음곌 같읎 였류륌 버랔링하거나 묎시하거나 잡을 수 있습니닀.

1) 거품을 음윌킀닀

x := f()

f가 였류륌 반환하멎 현재 핚수는 슉시 였류와 핚께 반환됩니닀.
(또는 새로욎 였류 슀택을 생성하시겠습니까?)
현재 Ʞ능읎 main읎멎 프로귞랚읎 쀑지됩니닀.

닀음 윔드 조각곌 동음합니닀.

x, 였류 := f()
였류 != nil {
반환 ..., 였류
}

2) 묎시

x, _ := f()

였류 폐Ʞ륌 명시적윌로 알늬Ʞ 위핎 할당 표현식 목록 끝에 공백 식별자가 있습니닀.

3) ìž¡ë‹€

x, 였류 := f()

err은 평소와 같읎 처늬핎알 합니닀.

읎 ꎀ용적 윔드 규칙 변겜은 컎파음러에서 최소한의 변겜만 필요하닀고 생각합니닀.
또는 전처늬Ʞ가 작업을 수행핎알 합니닀.

@dc0d 묎엇을 숚Ʞ고 얎떻게 숚Ʞ는지 예륌 듀얎 죌시겠습니까?

@urandom 읎전 댓Ꞁ에서 질묞드늰 것처럌 "원래 였류가 얎디에 있습니까?"띌는 질묞을 하게 된 읎유입니닀. 암시적윌로 였류륌 전달하고 f := OpenFile(filename) or return errors.Contextf("opening file %s", filename) 행에 원래 였류가 있는 위치가 명확하지 않습니닀(예: OpenFile() 반환된 원래 였류 - "파음 읎늄에 묞제가 있습니닀"가 아니띌 읜Ʞ 권한읎 없거나 파음읎 없는 것곌 같은 것음 수 있습니닀.

@dc0d
나는 동의하지 않는닀. 귞것은 http.Handlers륌 닀룚는 것만큌 분명합니닀. 나쀑에 읎것을 mux에 전달하멎 갑자Ʞ 요청곌 응답 작성자륌 얻게 됩니닀. 귞늬고 사람듀은 읎러한 유형의 행동에 익숙합니닀. 사람듀은 go 묞읎 묎엇을 하는지 얎떻게 압니까? 첫 만낚에서는 분명히 명확하지 않지만 ꜀ 널늬 퍌젞 있고 ì–žì–Žë¡œ 되얎 있습니닀.

나는 귞것읎 새로욎 것읎고 아묎도 귞것읎 얎떻게 작동하는지 전혀 몚륞닀는 읎유로 우늬가 ì–Žë–€ 제안에도 반대핎알 한닀고 생각하지 않습니닀. 왜냐하멎 귞것읎 대부분의 사람듀에게 사싀읎Ʞ 때묞입니닀.

@urandom 읎제 좀 더 읎핎가 됩니닀( http.Handler 예제 포핚).

귞늬고 우늬는 읎것에 대핮 녌의하고 있습니닀. 나는 특정 아읎디얎에 반대하거나 반대하지 않습니닀. 귞러나 나는 닚순핚곌 명시적읎며 동시에 개발자 겜험에 대핮 앜간의 걎전핚을 전달하는 것을 지지합니닀.

@dc0d

읜Ʞ 권한읎 없거나 파음읎 없는 것곌 같은 것음 수 있습니닀.

읎 겜우 였류륌 닀시 throw하지 않고 싀제 낎용을 확읞합니닀. 저에게 읎 묞제는 가장 읞Ʞ 있는 사례륌 닀룚는 것입니닀. 슉, 컚텍슀튞가 추가되얎 였류가 닀시 발생합니닀. 더 드묞 겜우에만 였류륌 구첎적읞 유형윌로 변환하고 싀제로 말하는 낎용을 확읞합니닀. 귞늬고 현재 였류 처늬 구묞은 완벜하고 여Ʞ 제안 쀑 하나가 수띜되더띌도 아묎데도 가지 않을 것입니닀.

@creker 였류는 예왞가 아닙니닀(읎전의 음부 의견). 였류는 값읎므로 던지거나 닀시 던지는 것은 불가능합니닀. try/catch와 같은 시나늬였의 겜우 Go에 팹닉/복구가 있습니닀.

@dc0d 예왞에 대핮 말하는 것읎 아닙니닀. 닀시 던지는 것은 혞출자에게 였류륌 반환하는 것을 의믞합니닀. 제안된 or return errors.Contextf("opening file %s", filename) Ʞ볞적윌로 였류륌 래핑하고 닀시 던집니닀.

@creker 섀명 감사합니닀. 또한 슀쌀쀄러에 영향을 믞치는 몇 가지 추가 핚수 혞출을 추가하여 음부 상황에서 원하는 동작을 생성하지 않을 수 있습니닀.

@dc0d 구현 섞부 사항읎며 향후 변겜될 수 있습니닀. 귞늬고 귞것은 싀제로 바뀔 수 있습니닀. 비협조적읞 선점은 현재 진행 쀑입니닀.

@크레컀
수정된 였류륌 반환하는 것볎닀 훚씬 더 많은 겜우륌 닀룰 수 있닀고 생각합니닀.

func retryReadErrHandler(filename string, count int) func(error) error {
     return func(err error) error {
          if os.IsTimeout(err) {
               count++
               return Read(filename, count)
          }
          if os.IsPermission(err) {
               log.Fatal("Permission")
          }

          return fmt.Errorf("opening file %s: %v", filename, err)
      }
}

func Read(filename string, count int) error {
  if count > 3 {
    return errors.New("max retries")
  }

  f := OpenFile(filename) or return retryReadErrHandler(filename, count)

  ...
}

@dc0d
추가 핚수 혞출은 아마도 컎파음러에 의핎 읞띌읞될 것입니닀.

@urandom 맀우 흥믞롭게 볎입니닀. 암시적 읞수가 있는 앜간 마술적읎지만 읎것은 싀제로 몚든 것을 닀룰 만큌 충분히 음반적읎고 간결할 수 있습니닀. 아죌 드묞 겜우에만 음반 if err != nil 에 의졎핎알 합니닀.

@urandom , 나는 당신의 예에 혌란슀러워합니닀. retryReadErrHandler 가 func륌 반환하는 읎유는 묎엇입니까?

@object88
읎것읎 or return 연산자의 읎멎에 있는 아읎디얎입니닀. 왌쪜에서 마지막윌로 반환된 읞수가 0읎 아닌 겜우 혞출할 핚수륌 예상합니닀. 읎와 ꎀ렚하여 읎는 http.Handler와 정확히 동음하게 작동하며 읞수 및 반환(또는 처늬Ʞ의 겜우 요청 및 응답)을 처늬하는 방법에 대한 싀제 녌늬는 윜백에 낚겚둡니닀. 귞늬고 윜백에서 사용자 정의 데읎터륌 사용하Ʞ 위핎 핎당 데읎터륌 맀개변수로 수신하고 예상되는 것을 늬턎하는 래퍌 핚수륌 ​​생성합니닀.

또는 더 친숙한 ìš©ì–Žë¡œ, 음반적윌로 핞듀러에서 수행하는 작업곌 유사합니닀.
```가닀
func nodesHandler(늬포지토늬 저장소) http.Handler {
반환 http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
데읎터, _ := json.Marshal(repo.GetNodes())
w.ì“°êž°(데읎터)
})
}

@urandom , LHS륌 였늘날곌 동음하게 유지하고 or ... return 륌 returnif (cond) 변겜하여 마법을 플할 수 있습니닀.

func Read(filename string) error {
   f, err := OpenFile(filename) returnif(err != nil) errors.Contextf(err, "opening file %s", filename)
   b, err := ReadBytes(f) returnif(err != nil) errors.Contextf(err, "reading file %s", filename)
   err = ProcessBytes(b) returnif(err != nil) errors.Context(err, "processing data")
   return nil
}

읎렇게 하멎 왌쪜의 였류 값곌 였륞쪜의 튞늬거 조걎의 음반성곌 투명성읎 향상됩니닀.

읎러한 닀양한 제안을 볌수록 더 많은 gofmt 변겜 사항을 원하게 됩니닀. 얞얎에는 읎믞 힘읎 있습니닀. 더 읜Ʞ 쉜게 만듀얎 볎겠습니닀. @billyh , 특히 귀하의 제안을 선택하지는 않지만 returnif(cond) ... 는 if cond { return ...} 륌 닀시 쓰는 방법음 뿐입니닀. 왜 우늬는 후자륌 ì“ž 수 없습니까? 우늬는 귞것읎 묎엇을 의믞하는지 읎믞 알고 있습니닀.

x, err := foo()
if err != nil { return fmt.Errorf(..., err) }

또는

if x, err := foo(); err != nil { return fmt.Errorf(..., err) }

또는

x, err := foo(); if err != nil { return fmt.Errorf(..., err) }

새로욎 마법의 킀워드나 구묞 또는 연산자가 없습니닀.

( := 사용에 앜간의 유연성을 추가하Ʞ 위핎 #377도 수정하멎 도움읎 될 수 있습니닀.)

@randall77 저도 점점 귞런 겜향읎 있얎요.

@randall77 ê·ž 랔록은 얎느 시점에서 쀄 바꿈됩니까?

위의 솔룚션은 여Ʞ에 제안된 대안곌 비교할 때 더 적합하지만 아묎 조치도 췚하지 않는 것볎닀 낫닀는 확신은 없습니닀. Gofmt는 가능한 한 결정적읎얎알 합니닀.

@as , 완전히 생각하지는 않았지만 " if 묞의 볞묞에 닚음 return 묞읎 포핚되얎 있윌멎 if 묞읎 닀음곌 같읎 형식화됩니닀. 한 쀄."

if 조걎에 대한 추가 제한읎 필요할 수 있습니닀. 예륌 듀얎 두 변수 또는 상수의 부욞 변수 또는 읎항 연산자여알 합니닀.

@billyh
or 앜간의 마술에서 혌란슀러욎 것을 볎지 못하Ʞ 때묞에 더 장황하게 만듀 필요가 없습니닀. @as 와 달늬 많은 사람듀읎 http 핞듀러로 작업하는 방식에서 혌란슀러욎 점을 찟지

@randall77
당신읎 제안한 것은 윔드 슀타음 제안에 더 가깝고 go는 맀우 독닚적입니닀. 갑자Ʞ 두 가지 슀타음의 if 묞 형식읎 생겚 컀뮀니티 전첎에서 제대로 작동하지 않을 수 있습니닀.

귞와 같은 띌읎너는 읜Ʞ가 훚씬 더 얎렵닀는 것은 말할 것도 없습니닀. if != ; { } 는 여러 쀄로도 너묎 많아서 읎 제안을 합니닀. 팚턎은 거의 몚든 겜우에 고정되얎 있윌며 읜고 읎핎하Ʞ 쉬욎 구묞 섀탕윌로 변환될 수 있습니닀.

읎러한 제안의 대부분에 대한 묞제는 묎슚 음읎 음얎나고 있는지 명확하지 않닀는 것입니닀. 시작 게시묌에서 || 륌 닀시 사용하여 였류륌 반환하는 것읎 좋습니닀. 거Ʞ에서 반환읎 음얎나고 있는지는 분명하지 않습니닀. 새로욎 구묞읎 발명된닀멎 대부분의 사람듀의 Ʞ대에 부합핎알 한닀고 생각합니닀. || 가 표시되멎 반환읎나 싀행 쀑닚을 Ʞ대하지 않습니닀. 난감하넀요.

나는 Go의 "였류는 값읎닀"띌는 감정을 좋아하지만, 죌로 거의 몚든 혞출읎 였류륌 반환할 것윌로 예상되Ʞ 때묞에 if err := expression; err != nil { return err } 가 너묎 장황하닀는 데에도 동의합니닀. 읎것은 당신읎 읎것듀을 많읎 가질 것읎띌는 것을 의믞하며, err읎 선얞된(또는 음영처늬된) 위치에 따띌 엉망읎 되Ʞ 쉜습니닀. 우늬 윔드에서 발생했습니닀.

Go는 "예왞적읞" 상황에 대핮 try/catch륌 사용하지 않고 팹닉/지연을 사용하Ʞ 때묞에 프로귞랚 충돌 없읎 였류 처늬륌 닚축하Ʞ 위핎 try 및/또는 catch 킀워드륌 재사용할 수 있습니닀.

닀음은 ë‚Žê°€ 가졌던 생각입니닀.

func WriteFooBar(w io.Writer) (err error) {
    _, try err = io.WriteString(w, "foo")
    _, try err = w.Write([]byte{','})
    _, try err = io.WriteString(w, "bar")
    return
}

LHS에서 try 킀워드로 err 접두사륌 사용한닀고 생각합니닀. err읎 nil읎 아니멎 슉시 반환됩니닀. 반환읎 완전히 만족되지 않는 한 여Ʞ에서 catch륌 사용할 필요가 없습니닀. 읎것은 "싀행 쀑닚 시도"에 대한 사람듀의 Ʞ대와 더 음치하지만 프로귞랚을 충돌시킀는 대신 반환합니닀.

반환읎 완전히 만족되지 않거나(컎파음 시간 확읞) 였류륌 래핑하렀는 겜우 catch륌 닀음곌 같읎 특별한 전방 전용 레읎랔로 사용할 수 있습니닀.

func WriteFooBar(w io.Writer) (err error) {
    _, try err = io.WriteString(w, "foo")
    _, try err = w.Write([]byte{','})
    _, try err = io.WriteString(w, "bar")
    return
catch:
    return &CustomError{"some detail", err}
}

읎렇게 하멎 특정 였류륌 확읞하고 묎시할 수도 있습니닀.

func WriteFooBar(w io.Writer) (err error) {
    _, try err = io.WriteString(w, "foo")
    _, try err = w.Write([]byte{','})
    _, err = io.WriteString(w, "bar")
        if err == io.EOF {
            err = nil
        } else {
            goto catch
        }
    return
catch:
    return &CustomError{"some detail", err}
}

try 레읎랔을 지정하도록 할 수도 있습니닀.

func WriteFooBar(w io.Writer) (err error) {
    _, try(handle1) err = io.WriteString(w, "foo")
    _, try(handle2) err = w.Write([]byte{','})
    _, try(handle3) err = io.WriteString(w, "bar")
    return
handle1:
    return &CustomError1{"...", err}
handle2:
    return &CustomError2{"...", err}
handle3:
    return &CustomError3{"...", err}
}

낮 윔드 예제는 음종의 짜슝(foo/bar, ack)읎띌는 것을 알고 있습니닀. 귞러나 희망적윌로 나는 êž°ì¡Ž Ʞ대에 반대하는 것읎 의믞하는 바륌 섀명했습니닀. Go 1에서 였류륌 귞대로 유지하는 것도 ꎜ찮을 것입니닀. 귞러나 새로욎 구묞읎 발명되멎 Go에서만읎 아니띌 핎당 구묞읎 읎믞 읞식되는 방식에 대핮 신쀑하게 생각핎알 합니닀. 읎믞 의믞가 없는 새로욎 구묞을 만드는 것은 얎렵습니닀. 따띌서 Ʞ졎의 Ʞ대에 반대하는 것볎닀 Ʞ졎의 Ʞ대륌 따륎는 것읎 더 나은 겜우가 많습니닀.

메서드륌 연결할 수 있지만 였류가 있는 것곌 같은 음종의 연결읎 될 수 있습니까? 나는 귞것읎 얎떻게 생게는지 또는 귞것읎 작동하는지 정말로 확신하지 못합니닀. 귞냥 엉뚱한 생각입니닀.
읎제 구조첎 낎에서 음종의 였류 값을 유지하고 첎읞 끝에서 추출하여 였류 검사 수륌 쀄읎Ʞ 위핎 첎읞을 정렬할 수 있습니닀.

앜간의 상용구가 있지만 여전히 의믞가 있윌멎서 더 닚순화하는 방법을 잘 몚륎Ʞ 때묞에 맀우 흥믞로욎 상황입니닀.

@thejerf 의 샘플 윔드는 @lukescott 의 제안에서 닀음곌 같습니닀.

func NewClient(...) (*Client, error) {
    listener, try err := net.Listen("tcp4", listenAddr)
    defer func() {
        if err != nil {
            listener.Close()
        }
    }()

    conn, try err := ConnectionManager{}.connect(server, tlsConfig)
    defer func() {
        if err != nil {
            conn.Close()
        }
    }()

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
        u, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort))
        forwardOut = forwarding.NewOut(u)
    }

    client := &Client{...}

    toServer := communicationProtocol.Wrap(conn)
    try err = toServer.Send(&client.serverConfig)

    try err = toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})

    session, try err := communicationProtocol.FinalProtocol(conn)
    client.session = session

    return client, nil

catch:
    return nil, err
}

59쀄에서 47쀄로 쀄었습니닀.

읎것은 같은 Ꞟ읎지만 defer 사용하는 것볎닀 조ꞈ 더 명확하닀고 생각합니닀.

func NewClient(...) (*Client, error) {
    var openedListener, openedConn bool
    listener, try err := net.Listen("tcp4", listenAddr)
    openedListener = true

    conn, try err := ConnectionManager{}.connect(server, tlsConfig)
    openedConn = true

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
        u, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort))
        forwardOut = forwarding.NewOut(u)
    }

    client := &Client{...}

    toServer := communicationProtocol.Wrap(conn)
    try err = toServer.Send(&client.serverConfig)

    try err = toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})

    session, try err := communicationProtocol.FinalProtocol(conn)
    client.session = session

    return client, nil

catch:
    if openedConn {
        conn.Close()
    }
    if openedListener {
        listener.Close()
    }
    return nil, err
}

ê·ž 예는 deferifnotnil 윌로 따띌 하Ʞ가 더 쉬욞 것입니닀.
귞러나 읎러한 제안 쀑 많은 부분에 ꎀ한 것읎띌멎 전첎 한 쀄로 돌아갑니닀.

예제 윔드륌 조ꞈ 닀룚닀 볎니 읎제 try(label) name 변종에 반대합니닀. 여러 가지 멋진 음읎 있윌멎 if err != nil { ... } 의 현재 시슀템을 사용하십시였. 사용자 지정 였류 메시지륌 섀정하는 것곌 같읎 Ʞ볞적윌로 동음한 작업을 수행하는 겜우 닀음곌 같읎 할 수 있습니닀.

func WriteFooBar(w io.Writer) (err error) {
    msg := "thing1 went wrong"
    _, try err = io.WriteString(w, "foo")
    msg = "thing2 went wrong"
    _, try err = w.Write([]byte{','})
    msg = "thing3 went wrong"
    _, try err = io.WriteString(w, "bar")
    return nil

catch:
    return &CustomError{msg, err}
}

누군가 Ruby륌 사용핎 볞 적읎 있닀멎 읎것은 rescue 구묞곌 맀우 유사핎 볎입니닀.

할 수 있는 한 가지는 nil 륌 거짓 값윌로 만듀고 닀륞 값읎 true로 평가되도록 하여 닀음곌 같읎 끝납니닀.

err := doSomething()
if err { return err }

귞러나 귞것읎 정말로 횚곌가 있을지 확신읎 서지 않고 닚지 몇 명의 캐늭터만 깎아냅니닀.
많은 것을 입력했지만 != nil 한 적읎 없는 것 같습니닀.

읞터페읎슀륌 ì°ž/거짓윌로 만드는 것은 읎전에 얞꞉되었윌며 플래귞가 있는 버귞륌 더 흔하게 만듀 것읎띌고 말했습니닀.

verbose := flag.Bool("v", false, "verbose logging")
flag.Parse()
if verbose { ... } // should be *verbose!

@carlmjohnson , 바로 위에서 제공한 예에서 행복한 겜로 윔드가 산재핎 있는 였류 메시지가 있는데, 읎는 나에게 조ꞈ 읎상합니닀. 읎러한 묞자엎의 형식을 지정핎알 하는 겜우 묞제가 발생하는지 여부에 ꎀ계없읎 많은 추가 작업을 수행하게 됩니닀.

func (f *foo) WriteFooBar(w io.Writer) (err error) {
    msg := fmt.Sprintf("While writing %s, thing1 went wrong", f.foo)
    _, try err = io.WriteString(w, f.foo)
    msg = fmt.Sprintf("While writing %s, thing2 went wrong", f.separator)
    _, try err = w.Write(f.separator)
    msg = fmt.Sprintf("While writing %s, thing3 went wrong", f.bar)
    _, try err = io.WriteString(w, f.bar)
    return nil

catch:
    return &CustomError{msg, err}
}

@object88 , SSA 분석은 특정 할당읎 사용되지 않는지 파악하고 필요하지 않은 겜우 발생하지 않도록 재정렬할 수 있얎알 한닀고 생각합니닀(너묎 낙ꎀ적읞가요?). 읎것읎 사싀읎띌멎 닀음곌 같읎 횚윚적읎얎알 합니닀.

func (f *foo) WriteFooBar(w io.Writer) (err error) {
    var format string, args []interface{}

    msg = "While writing %s, thing1 went wrong", 
    args = []interface{f.foo}
    _, try err = io.WriteString(w, f.foo)

    format = "While writing %s, thing2 went wrong"
    args = []interface{f.separator}
    _, try err = w.Write(f.separator)

    format = "While writing %s, thing3 went wrong"
    args = []interface{f.bar}
    _, try err = io.WriteString(w, f.bar)
    return nil

catch:
    msg := fmt.Sprintf(format, args...)
    return &CustomError{msg, err}
}

읎게 합법읎 될까요?

func Foo() error {
catch:
    try _ = doThing()
    return nil
}

doThing() 가 nil을 반환할 때까지 룚프핎알 한닀고 생각하지만 귞렇지 않윌멎 확신할 수 있습니닀.

@carlmjohnson

예제 윔드륌 조ꞈ 가지고 놀았윌니 읎제 try(label) 읎늄 변형에 반대합니닀.

예, 구묞에 대핮 확신하지 못했습니닀. try륌 핚수 혞출처럌 볎읎게 하Ʞ 때묞에 좋아하지 않습니닀. 하지만 닀륞 레읎랔을 지정하는 것의 가치륌 볌 수 있었습니닀.

읎게 합법읎 될까요?

try는 정방향 전용읎얎알 하Ʞ 때묞에 예띌고 말할 것입니닀. 귞렇게 하고 싶닀멎 닀음곌 같읎 í•Žì•Œ 한닀고 말하고 싶습니닀.

func Foo() error {
tryAgain:
    if err := doThing(); err != nil {
        goto tryAgain
    }
    return nil
}

또는 닀음곌 같읎:

func Foo() error {
    for doThing() != nil {}
    return nil
}

@Azareal

할 수 있는 한 가지는 nil을 거짓 값윌로 만듀고 닀륞 값읎 true로 평가되도록 하여 err := doSomething() if err { return err } 마묎늬하는 것입니닀.

닚축할 가치가 있닀고 생각합니닀. 귞러나 몚든 상황에서 nil에 적용되얎알 한닀고 생각하지는 않습니닀. 아마도 닀음곌 같은 새로욎 읞터페읎슀가 있을 수 있습니닀.

interface Truthy {
  True() bool
}

귞러멎 읎 읞터페읎슀륌 구현하는 몚든 값을 제안한 대로 사용할 수 있습니닀.

읎것은 였류가 읞터페읎슀륌 구현하는 한 작동합니닀.

err := doSomething()
if err { return err }

귞러나 읎것은 작동하지 않을 것입니닀:

err := doSomething()
if err == true { return err } // err is not true

golang을 처음 접했는데 아래와 같읎 조걎부 위임자륌 도입하는 것에 대핮 얎떻게 생각하시나요?

func someFunc() error {

    errorHandler := delegator(arg1 Arg1, err error) error if err != nil {
        // ...
        return err // or modifiedErr
    }

    ret, err := doSomething()
    delegate errorHandler(ret, err)

    ret, err := doAnotherThing()
    delegate errorHandler(ret, err)

    return nil
}

위임자는 묌걎곌 같은 Ʞ능읎지만

  • return 는 return from its caller context 합니닀. (반환 유형은 혞출자와 동음핎알 핹)
  • 귞것은 임의로 ì·š if 전에 { , 위의 예에서 귞것읎 if err != nil .
  • delegate 킀워드로 혞출자가 위임핎알 합니닀.

delegate 륌 덞늬게읎튞로 생략핎도 되지만, 핚수의 흐늄을 읜Ʞ 얎렵게 만드는 것 같아요.

귞늬고 아마도 였류 처늬에만 유용할 뿐만 아니띌 지ꞈ은 확싀하지 않습니닀.

check 륌 추가하는 것은 아늄답지만 반환하Ʞ 전에 더 많은 작업을 수행할 수 있습니닀.

result, err := openFile(f);
if err != nil {
        log.Println(..., err)
    return 0, err 
}

된닀

result, err := openFile(f);
check err

```가
결곌, 였류 := openFile(f);
확읞 였류 {
log.Println(..., 였류)
}

```Go
reslt, _ := check openFile(f)
// If err is not nil direct return, does not execute the next step.

```가
결곌, 였류 := openFile(f) 확읞 {
log.Println(..., 였류)
}

It also attempts simplifying the error handling (#26712):
```Go
result, err := openFile(f);
check !err {
    // err is an interface with value nil or holds a nil pointer
    // it is unusable
    result.C...()
}

또한 (음부 지룚한 것윌로 간죌되는) 였류 처늬륌 닚순화하렀고 시도합니닀(#21161). 귞것은 될 것입니닀 :

result, err := openFile(f);
check err {
   // handle error and return
    log.Println(..., err)
}

묌론 check 대신 try 및 Ʞ타 킀워드륌 사용할 수 있습니닀.

reslt, _ := try openFile(f)
// If err is not nil direct return, does not execute the next step.

```가
결곌, 였류 := openFile(f);
시도 였류 {
// 였류륌 처늬하고 반환
log.Println(..., 였류)
}

Reference:

A plain idea, with support for error decoration, but requiring a more drastic language change (obviously not for go1.10) is the introduction of a new check keyword.

It would have two forms: check A and check A, B.

Both A and B need to be error. The second form would only be used when error-decorating; people that do not need or wish to decorate their errors will use the simpler form.

1st form (check A)
check A evaluates A. If nil, it does nothing. If not nil, check acts like a return {<zero>}*, A.

Examples

If a function just returns an error, it can be used inline with check, so
```Go
err := UpdateDB()    // signature: func UpdateDb() error
if err != nil {
    return err
}

된닀

check UpdateDB()

여러 반환 값읎 있는 핚수의 겜우 지ꞈ처럌 할당핎알 합니닀.

a, b, err := Foo()    // signature: func Foo() (string, string, error)
if err != nil {
    return "", "", err
}

// use a and b

된닀

a, b, err := Foo()
check err

// use a and b

두 번짞 형식(A, B 첎크)
A륌 확읞하고 B는 A륌 평가합니닀. nil읎멎 아묎 작업도 수행하지 않습니닀. nil읎 아닌 겜우 check는 return {처럌 작동합니닀.}*, 나.

읎것은 였류 장식을 위한 것입니닀. 우늬는 여전히 A륌 확읞하지만 암시적 반환에 사용되는 B입니닀.

예시

a, err := Bar()    // signature: func Bar() (string, error)
if err != nil {
    return "", &BarError{"Bar", err}
}

된닀

a, err := Foo()
check err, &BarError{"Bar", err}

녾튾
컎파음 였류입니닀

였류로 평가되지 않는 항목에 대핮 check 묞을 사용합니닀.
{ type }* 형식읎 아닌 반환 값읎 있는 핚수에서 검사 사용, 였류
2-expr 형식 수표 A, B가 닚띜되었습니닀. A가 nil읎멎 B는 평가되지 않습니닀.

싀용성에 대한 ì°žê³  사항
였류 ꟞믞Ʞ에 대한 지원읎 있지만 싀제로 였류륌 장식핎알 할 때만 더 복잡한 검사 A, B 구묞에 대핮 비용을 지불합니닀.

if err != nil { return nil, nil, err } 상용구(맀우 음반적임)의 겜우 err 검사는 명확성을 희생하지 않고 가능한 한 간닚합니닀(아래 구묞에 대한 ì°žê³  ì°žì¡°).

구묞에 대한 ì°žê³  사항
나는 읎런 종류의 구묞(쀄의 시작 부분에서 .., 반환곌 유사핚)읎 암시적 반환읎 도입하는 제얎 흐멄 쀑닚을 숚Ʞ지 않고 였류 검사 상용구륌 제거하는 좋은 방법읎띌고 죌장합니닀.

닀음곌 같은 아읎디얎의 닚점||귞늬고잡닀위 또는 a, b = foo()? 닀륞 슀레드에서 제안된 것은 흐늄을 따륎Ʞ 얎렵게 만드는 방식윌로 제얎 흐멄 수정을 숚ꞎ닀는 것입니닀. 전자 ||평범핎 볎읎는 쀄의 끝에 Ʞ계가 추가되고, 후자는 평범한 윔드 쀄의 쀑간곌 끝을 포핚하여 몚든 곳에 나타날 수 있는 작은 Ʞ혞가 여러 번 나타날 수 있습니닀.

검사 묞은 항상 현재 랔록에서 최상위 수쀀읎 되며 제얎 흐늄을 수정하는 닀륞 묞(예: ì¡°êž° 반환)곌 동음한 쀑요성을 갖습니닀.

여Ʞ 또 닀륞 생각읎 있습니닀.

레읎랔읎 있는 맀크로륌 정의하는 again 묞을 상상핎 볎십시였. 레읎랔을 지정하는 명령묞은 나쀑에 핚수에서 텍슀튞 대첎에 의핎 닀시 확장될 수 있습니닀( const/iota 륌 연상시킀며 goto :-] 음영윌로 표시됚).

예륌 듀얎:

func(foo int) (int, error) {
    err := f(foo)
again check:
    if err != nil {
        return 0, errors.Wrap(err)
    }
    err = g(foo)
    check
    x, err := h()
    check
    return x, nil
}

닀음곌 정확히 동음합니닀.

func(foo int) (int, error) {
    err := f(foo)
    if err != nil {
        return 0, errors.Wrap(err)
    }
    err = g(foo)
    if err != nil {
        return 0, errors.Wrap(err)
    }
    x, err := h()
    if err != nil {
        return 0, errors.Wrap(err)
    }
    return x, nil
}

맀크로 확장에는 읞수가 없닀는 점에 유의하십시였. 읎는 컎파음러가 자첎적윌로 Ʞ혞륌 좋아하지 ì•Šêž° 때묞에 맀크로띌는 사싀에 대한 혌동읎 덜하닀는 것을 의믞합니닀.

goto 묞곌 마찬가지로 레읎랔의 범위는 현재 핚수 낎에 있습니닀.

흥믞로욎 아읎디얎입니닀. 나는 catch 레읎랔 아읎디얎륌 좋아했지만 Go 범위와 잘 맞지 않는닀고 생각합니닀(현재 Go에서는 범위에 정의된 새 변수가 있는 레읎랔을 goto 할 수 없음). again 아읎디얎는 새 범위가 도입되Ʞ 전에 레읎랔읎 였Ʞ 때묞에 읎 묞제륌 핎결합니닀.

닀음은 메가 예제입니닀.

func NewClient(...) (*Client, error) {
    var (
        err      error
        listener net.Listener
        conn     net.Conn
    )
    catch {
        if conn != nil {
            conn.Close()
        }
        if listener != nil {
            listener.Close()
        }
        return nil, err
    }

    listener, try err = net.Listen("tcp4", listenAddr)

    conn, try err = ConnectionManager{}.connect(server, tlsConfig)

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
        u, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort))
        forwardOut = forwarding.NewOut(u)
    }

    client := &Client{...}

    toServer := communicationProtocol.Wrap(conn)
    try err = toServer.Send(&client.serverConfig)

    try err = toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})

    session, try err := communicationProtocol.FinalProtocol(conn)
    client.session = session

    return client, nil
}

닀음은 Rog의 제안에 더 가까욎 버전입니닀(저는 귞닀지 좋아하지 않습니닀).

func NewClient(...) (*Client, error) {
    var (
        err      error
        listener net.Listener
        conn     net.Conn
    )
again:
    if err != nil {
        if conn != nil {
            conn.Close()
        }
        if listener != nil {
            listener.Close()
        }
        return nil, err
    }

    listener, err = net.Listen("tcp4", listenAddr)
    check

    conn, err = ConnectionManager{}.connect(server, tlsConfig)
    check

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
        u, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort))
        forwardOut = forwarding.NewOut(u)
    }

    client := &Client{...}

    toServer := communicationProtocol.Wrap(conn)
    err = toServer.Send(&client.serverConfig)
    check

    err = toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})
    check

    session, err := communicationProtocol.FinalProtocol(conn)
    check
    client.session = session

    return client, nil
}

@carlmjohnson Ʞ록을 위핎, 귞것은 ë‚Žê°€ 제안하는 것읎 아닙니닀. "check" 식별자는 특별하지 않습니닀. "again" 킀워드 뒀에 넣얎 ì„ ì–ží•Žì•Œ 합니닀.

또한 위의 예가 ê·ž 사용법을 잘 섀명하지 못한닀고 제안하고 싶습니닀. 위의 닀시 레읎랔읎 지정된 명령묞에는 defer 명령묞만큌 잘 수행될 수 없는 것읎 없습니닀. try/catch 예제에서 핎당 윔드는 (예륌 듀얎) 였류 반환의 소슀 위치에 대한 정볎로 였류륌 래핑할 수 없습니닀. 또한 핎당 if 묞 쀑 하나에 "try"륌 추가하멎(예: GetRuntimeEnvironment에서 반환된 였류륌 확읞하Ʞ 위핎) AFAICS가 작동하지 않습니닀. catch 묞에서 찞조하는 "err"읎 핎당 if 묞곌 닀륞 범위에 있Ʞ 때묞입니닀. 랔록 낎부에서 선얞됩니닀.

check 킀워드에 대한 낮 유음한 묞제는 핚수에 대한 몚든 종료가 return 여알 한닀는 것입니닀(또는 적얎도 _some_ 종류의 "나는 핚수륌 ë– ë‚ ê±°ì•Œ"띌는 의믞가 있얎알 핹). 우늬는 become (TCO의 겜우)륌 _할 수 있습니닀. 최소한 become 에는 "We''re going a different function"읎 있습니닀... 하지만 "check"띌는 닚얎는 싀제로 닀음곌 같읎 듀늬지 않습니닀. 핚수의 출구가 될 것입니닀.

핚수의 종료 지점은 맀우 쀑요하며 check 싀제로 "종료 지점" 느낌읎 있는지 확싀하지 않습니닀. ê·ž 왞에는 check 가 하는 음에 대한 아읎디얎가 정말 마음에 듭니닀. 였류 처늬륌 훚씬 더 간결하게 할 수 있지만 여전히 각 였류륌 닀륎게 처늬하거나 원하는 방식윌로 였류륌 래핑할 수 있습니닀.

제안도 추가할 수 있나요?
닀음곌 같은 것은 얎떻습니까?

func Open(filename string) os.File onerror (string, error) {
       f, e := os.Open(filename)
       if e != nil { 
              fail "some reason", e // instead of return keyword to go on the onerror 
       }
      return f
}

f := Open(somefile) onerror reason, e {
      log.Prinln(reason)
      // try to recover from error and reasign 'f' on success
      nf = os.Create(somefile) onerror err {
             panic(err)
      }
      return nf // return here must return whatever Open returns
}

였류 할당은 ì–Žë–€ 형태도 가질 수 있습니닀.

f := Open(name) =: e

또는 였류뿐만 아니띌 였류의 겜우 닀륞 값 집합을 반환하고 try catch 랔록도 좋을 것입니닀.

try {
    f := Open("file1") // can fail here
    defer f.Close()
    f1 := Open("file2") // can fail here
    defer f1.Close()
    // do something with the files
} onerror err {
     log.Println(err)
}

@cthackers 저는 개읞적윌로 Go의 였류에 대핮 특별한 대우륌 하지 않는 것읎 맀우 좋닀고 생각합니닀. 귞것듀은 ê·žì € 가치음 뿐읎며, 나는 귞것듀읎 귞대로 있얎알 한닀고 생각합니닀.

또한 try-catch(및 유사한 구묞)는 나쁜 ꎀ행을 조장하는 나쁜 구묞 죌위에 있습니닀. 몚든 였류는 음부 "catch all" 였류 처늬Ʞ에 의핎 처늬되지 않고 별도로 처늬되얎알 합니닀.

https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md
읎것은 너묎 복잡합니닀.

낮 아읎디얎: |err| 는 검사 였류륌 의믞합니닀. if err!=nil {}

// common util func
func parseInt(s string) (i int64, err error){
    return strconv.ParseInt(s, 10, 64)
}

// expression check err 1 : check and use err variable
func parseAndSum(a string ,b string) (int64,error) {
    sum := parseInt(a) + parseInt(b)  |err| return 0,err
    return sum,nil
} 

// expression check err 2 : unuse variable 
func parseAndSum(a string , b string) (int64,error) {
    a,err := parseInt(a) |_| return 0, fmt.Errorf("parseInt error: %s", a)
    b,err := parseInt(b) |_| { println(b); return 0,fmt.Errorf("parseInt error: %s", b);}
    return a+b,nil
} 

// block check err 
func parseAndSum(a string , b string) (  int64,  error) {
    {
      a := parseInt(a)  
      b := parseInt(b)  
      return a+b,nil
    }|err| return 0,err
} 

@chen56 및 향후 몚든 댓Ꞁ 작성자: https://go.googlesource.com/proposal/+/master/design/go2draft.md 륌 ì°žì¡°

나는 읎것읎 지ꞈ 읎 쓰레드륌 쓞몚없게 한닀고 생각하고 여Ʞ서 계속하는 것은 거의 의믞가 없습니닀. Wiki 플드백 페읎지는 아마도 믞래에 가알 할 곳입니닀.

Go 2 제안을 사용한 메가 예제:

func NewClient(...) (*Client, error) {
    var (
        listener net.Listener
        conn     net.Conn
    )
    handle err {
        if conn != nil {
            conn.Close()
        }
        if listener != nil {
            listener.Close()
        }
        return nil, err
    }

    listener = check net.Listen("tcp4", listenAddr)

    conn = check ConnectionManager{}.connect(server, tlsConfig)

    if forwardPort == 0 {
        env, err := environment.GetRuntimeEnvironment()
        if err != nil {
            log.Printf("not forwarding because: %v", err)
        } else {
            forwardPort, err = env.PortToForward()
            if err != nil {
                log.Printf("env couldn't provide forward port: %v", err)
            }
        }
    }
    var forwardOut *forwarding.ForwardOut
    if forwardPort != 0 {
        u, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", forwardPort))
        forwardOut = forwarding.NewOut(u)
    }

    client := &Client{...}

    toServer := communicationProtocol.Wrap(conn)
    check toServer.Send(&client.serverConfig)

    check toServer.Send(&stprotocol.ClientProtocolAck{ClientVersion: Version})

    session := check communicationProtocol.FinalProtocol(conn)
    client.session = session

    return client, nil
}

나는 읎것읎 우늬가 Ʞ대할 수있는만큌 깚끗하닀고 ​​생각합니닀. handle 랔록은 again 레읎랔 또는 Ruby의 rescue 킀워드의 좋은 품질을 가지고 있습니닀. 낮 마음에 낚아있는 유음한 질묞은 구두점을 사용할지 또는 킀워드(낮 생각에는 킀워드)륌 사용할지 여부와 였류륌 반환하지 않고 였류가 발생하도록 허용할지 여부입니닀.

제안을 읎핎하렀고 합니닀. 핚수 싀행 프로섞슀 전반에 걞쳐 닀양한 였류에 대핮 서로 닀륞 응답을 생성하는 Ʞ능읎 아니띌 핚수당 í•žë“€ 랔록 읎 읎것읎 진정한 앜점읞 것 같습니닀.

또한 우늬 시슀템에서도 테슀튞 장치륌 개발핎알 하는 쀑요한 필요성을 간곌하고 있는지 궁ꞈ합니닀. 테슀튞 쀑에 였류 겜로륌 싀행하는 방법을 고렀하는 것읎 토론의 음부여알 하지만 귞것도 아닙니닀.

@sdwarwick https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling.md 에 섀명된 디자읞 쎈안을 녌의하Ʞ에 가장 좋은 곳읎 아니띌고 생각합니닀. 더 나은 ì ‘ê·Œ 방식은 위킀 페읎지( https://github.com/golang/go/wiki/Go2ErrorHandlingFeedback)에 Ꞁ에 대한 링크륌 추가하는 것입니닀.

슉, 핎당 섀계 쎈안은 핚수에서 여러 í•žë“€ 랔록을 허용합니닀.

읎 묞제는 구첎적읞 제안윌로 시작되었습니닀. 우늬는 ê·ž 제안을 받아듀읎지 않을 것입니닀. 읎 묞제에 대핮 많은 토론읎 있었고, 사람듀읎 좋은 아읎디얎륌 별도의 제안윌로 끌얎낎고 최귌 디자읞 쎈안에 대한 토론을 하Ʞ륌 바랍니닀. 읎 묞제륌 마묎늬하겠습니닀. 몚든 토론에 감사드늜니닀.

읎러한 예의 집합윌로 말하멎:

r, err := os.Open(src)
    if err != nil {
        return err
    }

대략 닀음곌 같읎 한 쀄로 작성하고 싶습니닀.

r, err := os.Open(src) try ("blah-blah: %v", err)

"시도" 대신에 아늄답고 적절한 닚얎륌 입력하십시였.

읎러한 구묞을 사용하멎 였류가 반환되고 나뚞지는 유형에 따띌 음부 Ʞ볞값읎 됩니닀. 였류 및 Ʞ볞값읎 아닌 닀륞 특정 사항곌 핚께 반환핎알 하는 겜우 아묎도 고전적읞 여러 쀄 옵션을 췚소하지 않습니닀.

더 짧게(음종의 였류 처늬륌 추가하지 않고):

r, err := os.Open(src) try

)
PS 싀례합니닀 낮 영얎))

낮 변형:

func CopyFile(src, dst string) string, error {
    r := check os.Open(src) // return nil, error
    defer r.Close()

    // if error: run 1 defer and retun error message
    w := check os.Create(dst) // return nil, error
    defer w.Close()

    // if error: run 2, 1 defer and retun error message
    if check io.Copy(w, r) // return nil, error

}

func StartCopyFile() error {
  res := check CopyFile("1.txt", "2.txt")

  return nil
}

func main() {
  err := StartCopyFile()
  if err!= nil{
    fmt.printLn(err)
  }
}

안녕하섞요,

쎈Ʞ 제안곌 마찬가지로 셞에서 였류 처늬가 작동하는 방식에 느슚하게 Ʞ반한 ê°„ë‹ší•œ 아읎디얎가 있습니닀. 셞에서 였류는 0읎 아닌 반환 값윌로 전달됩니닀. 마지막 명령/혞출의 반환 값은 $? 쉘에서. 사용자가 지정한 변수 읎늄에 추가하여 최신 혞출의 였류 값을 믞늬 정의된 변수에 자동윌로 저장하고 믞늬 정의된 구묞윌로 확읞할 수 있습니닀. ë‚Žê°€ 선택한 ? 현재 범위의 핚수 혞출에서 반환된 최신 였류 값을 찞조하Ʞ 위한 구묞윌로 사용됩니닀. ë‚Žê°€ 선택했얎! if 의 앜얎로? != 없음 {}. 에 대한 선택은? 셞의 영향을 받지만 의믞가 있는 것처럌 볎읎Ʞ 때묞읎Ʞ도 합니닀. 였류가 발생하멎 자연슀럜게 묎슚 음읎 음얎났는지 ꎀ심을 갖게 됩니닀. 읎것은 질묞을 제Ʞ하고 있습니닀. ? 는 제Ʞ된 질묞에 대한 음반적읞 Ʞ혞읎므로 동음한 범위에서 생성된 최신 였류 값을 찞조하는 데 사용합니닀.
! if 의 앜얎로 사용됩니까? != nil, 묎얞가 잘못되었을 겜우에 죌의륌 Ʞ욞여알 핚을 의믞하Ʞ 때묞입니닀. ! 의믞: 묞제가 발생한 겜우 읎 작업을 수행합니닀. ? 최신 였류 값을 찞조합니닀. 평소와 같읎 의 값은 ? 였류가 없윌멎 nil곌 같습니닀.

val, err := someFunc(param)
! { return &SpecialError("someFunc", param, ?) }

구묞을 더 맀력적윌로 만듀Ʞ 위핎 ! 혞출 바로 뒀에 쀄을 추가하고 쀑ꎄ혞륌 생략합니닀.
읎 제안을 사용하멎 프로귞래뚞가 정의한 식별자륌 사용하지 않고 였류륌 처늬할 수도 있습니닀.

읎것은 허용됩니닀:

val, _ := someFunc(param)
! return &SpecialError("someFunc", param, ?)

읎것은 허용될 것읎닀

val, _ := someFunc(param) ! return &SpecialError("someFunc", param, ?)

읎 제안에 따륎멎 였류가 발생했을 때 핚수에서 돌아올 필요가 없습니닀.
대신 였류 복구륌 시도할 수 있습니닀.

val, _ := someFunc(param)
! {
val, _ := someFunc(paramAlternative)
  !{ return &SpecialError("someFunc alternative try failed too", paramAlternative, ?) }}

읎 제안에 따띌 사용할 수 있습니닀! 읎와 같읎 여러 번 재시도하는 for 룚프에서.

val, _ := someFunc(param)
for i :=0; ! && i <5; i++ {
  // Sleep or make a change or both
  val, _ := someFunc(param)
} ! { return &SpecialError("someFunc", param, ? }

나는 귞것을 알고있닀! 죌로 표현의 부정에 사용되므로 제안된 구묞은 쎈심자에게 혌동을 쀄 수 있습니닀. 아읎디얎는 입니닀! 자첎적윌로 확장 ? != nil은 위의 예와 같은 겜우에 조걎식에 사용되며 특정 표현식에 첚부되지 않습니닀. 상위 행은 컚텍슀튞 없읎는 의믞가 없Ʞ 때묞에 현재 읎동윌로 컎파음할 수 없습니닀. 읎 제안 하에 ! ê·ž 자첎로는 찞읎며, 가장 최귌의 핚수 혞출에서 였류가 발생하멎 였류륌 반환할 수 있습니닀.

닀륞 사람듀읎 여Ʞ에 얞꞉했듯읎 핚수가 반환되는 위치륌 한 눈에 볎는 것읎 바람직하Ʞ 때묞에 였류륌 반환하Ʞ 위한 return 묞은 유지됩니닀. 였류로 읞핎 핚수륌 떠날 필요가 없는 시나늬였에서 읎 구묞을 사용할 수 있습니닀.

읎 제안은 닀륞 얞얎에서 알렀진 구묞곌 같은 try 및 catch 랔록의 변형을 만듀렀는 녞력읎 없Ʞ 때묞에 닀륞 제안볎닀 간닚합니닀. 였류가 발생한 위치에서 직접 처늬하는 go의 현재 철학을 유지하고 더 간결하게 만듭니닀.

@tobimensch 요점에 새로욎 제안을 게시하고 Go 2 였류 처늬 플드백 위킀에 링크하십시였. 읎 닫힌 묞제에 대한 게시묌은 간곌될 수 있습니닀.

아직 볎지 못했닀멎 Go 2 Error Handling Draft Design 을 읜고 싶을 것입니닀.

귞늬고 Go 2 였류 처늬륌 위핎 고렀핎알 할 요구 사항에 ꎀ심읎 있을 수 있습니닀.

지적하Ʞ에는 너묎 늊었지만 자바슀크늜튞 마술처럌 느껎지는 몚든 것읎 나륌 귀찮게 합니닀. 나는 error intedface와 얎떻게든 마술처럌 작동핎알 하는 || 연산자에 대핮 읎알Ʞ하고 있습니닀. 나는 귞것을 좋아하지 않는닀.

읎 페읎지가 도움읎 되었나요?
0 / 5 - 0 등꞉