Goìì ì€ë¥ ì²ëŠ¬ë¥Œ ëšìííë ë°©ë²ì ëí ë§ì ì ììŽ ìììµëë€. 몚ë Go ìœëì íìŽ ë묎 ë§ìŽ í¬íšëìŽ ìë€ë ìŒë°ì ìž ë¶ë§ì êž°ë°ìŒë¡ í©ëë€.
if err != nil {
return err
}
ì¬êž°ì íŽê²°íŽìŒ í 묞ì ê° ìëì§ ì ëªšë¥Žê² ì§ë§ ê³ìíŽì 묞ì ê° ë°ìíêž° ë묞ì ìŽ ììŽëìŽë¥Œ ëŽëìµëë€.
ì€ë¥ ì²ëŠ¬ë¥Œ ëšìííêž° ìí ëë¶ë¶ì ì ìì íµì¬ 묞ì ì€ íëë ì€ë¥ë¥Œ ì²ëŠ¬íë ë ê°ì§ ë°©ë²ë§ ëšìííì§ë§ ì€ì ë¡ë ìž ê°ì§ê° ìë€ë ê²ì ëë€.
ì€ë¥ë¥Œ 묎ìíë ê²ì ìŽë¯ž ìœìµëë€(ìë§ë ë묎 ìœìµëë€)(#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 ì€ë¥ ì²ëŠ¬ë¥Œ ëšìííë €ë ì¬ëë€ìŽ ìì ëì§ ìì ì€ë¥ë¥Œ ë°ííë ê²ìŽ ìëëŒ ì€ë¥ 죌ìì 컚í ì€ížë¥Œ ìœê² ê°ì ì ìë ë°©ë²ì ëíŽ ìê°íëë¡ ê¶ì¥íêž° ìíŽ ìŽ ì ìì ìì±í©ëë€.
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
ì¬ìŒ í©ëë€. ë ë²ì§ž íìì ì€ë¥ë¥Œ ì¥ìí ëë§ ì¬ì©ë©ëë€. ìì ì ì€ë¥ë¥Œ ì¥ìí íìê° ìê±°ë êŸžë¯žê³ ì¶ì§ ìì ì¬ëë€ì ë ê°ëší íìì ì¬ì©í©ëë€.
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
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 ì룚ì ìŒ ì ììµëë€.
ì€ë¥ ì²ëŠ¬ë¥Œ ìí í©ëŠ¬ì ìž ë°ë¡ ê°êž° 구묞ìë ìž ê°ì§ ìì±ìŽ ìë€ê³ ì ìíê³ ì¶ìµëë€.
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} }
ê·žë¬ë ì°ëŠ¬ê° ëë¶ë¶ ëª ë ¹ì ìž ìœë륌 ìì±íê³ ìë€ë ì¬ì€ì ìì ì ìŒë¶ê° ì¡°êž°ì ë°íí ì ìë€ë ê²ìŽêž° ë묞ì ë ë²ì§ž ìì¹ì íšì륌 ì¬ì© íì§ ìììŒ íë€ë ê²ì ì구í©ëë€.
ìŽì ì ë 몚ë ì¢ ë¥ì êŽë šìŽ ìë ìž ê°ì§ êŽì°°ì ëíŽ ìê°íê³ ììµëë€.
ì€ë¥ ì²ëŠ¬ë íšì 구ì±ê³Œ ë¹ì·íì§ë§ Goìì ìì ì ìííë ë°©ìì Haskellì Error 몚ëë ì ì ë°ëì ëë€. ì°ëŠ¬ë ëë¶ë¶ ìì°š ìœë ëì ëª ë ¹í ìœë륌 ìì±íêž° ë묞ì
(x, y, error)
륌 ë°ííë Go íšìë ìŒë°ì ìŒë¡ (x, y) | error
ì í©ì§í©(#19412)곌 ê°ì ê²ì ì믞í©ëë€.
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ê°ì§ 겜ì°ê° ììµëë€.
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
}
ìŽ ìœëì 믞ë¬íšì ë€ì곌 ê°ìµëë€.
íší€ì§ 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 : ëŽë¶ì ìŒë¡ë ë ë¹ì©ìŽ ë§ìŽ ë€ì§ë§ ëšìŒ ì°êž°ë¡ 구íë©ëë€.
ìë ìœëìž ê²œì°:
êž°í ê°ì ë¹:
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 }
ì¬êž°ì ëììŽ ëë ë ê°ì§ ë²ì ì§ì ê°ì ì¬íìŽ ììµëë€.
err
(ìŽì Get
ížì¶ìì)ë return
ëžë¡ì ë²ììë§ ììŒë¯ë¡ íì ê²ì¬ìì ì€ìë¡ ì¬ì©í ì ììµëë€.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 : ê·íì ëšìíì êŽë šíì¬ : ê·íê° ëëµ ë§ìµëë€.
@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 ì =?
/ =!
/ :=?
/ :=!
ì ììŽ ë ì¢ìµëë€. ëª ê°ì§ ì¢ì ìì±ìŽ ììµëë€.
=?
ëŽìì =?
ëžë¡)ê·žê²ì ëí ëŽê° ë©ì§ë€ê³ ìê°íì§ ìë ëª ê°ì§ ìì±ì ê°ì§ê³ ììµëë€.
컎í¬ì§ì
ë¥ì§. ë°ë³µ ì¬ì©ì ê³ìíŽì ì€ë¥žìªœìŒë¡ ê°ìë¡ ë€ì¬ì°êž°ê° ë©ëë€. ê·žê²ìŽ ë°ëì ê·ž ìì²Žë¡ ëì ê²ì ìëì§ë§, ì€ë¥ë¥Œ ìŒìŒí€ë ì€ë¥ë¥Œ ì²ëŠ¬íŽìŒ íë ë§€ì° ë³µì¡í ì€ë¥ ì²ëŠ¬ê° ìë ìí©ììë ì²ëŠ¬í ìœëê° íì¬ ìíë³Žë€ íšì¬ ë ëª
ííŽì§ ê²ìŽëŒê³ ììí©ëë€. ìŽë¬í ìí© íëìì ì¬ì©í ììë =?
ë°ê¹¥ 쪜 ì€ë¥ ë° 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ìì ííí ìœê°ì ê°ë
ì± ë¬žì 륌 몚ëíí©ëë€. ë ê°ì§ ê°ì¥ í° ë¬žì ë
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ì íìŒì 컀ë°í ì ììµëë€.
ë€ì 죌ì¥ì ë€ì곌 ê°ìµëë€. ë²ê·žê° ìë ìœë륌 ìì±íì§ ë§ììì€. íì§ë§:
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ì ì€ë¥ ì²ëŠ¬ ê°ì ì ìí ë€ì 목í륌 ì ìí©ëë€.
ìŽ ì ì íê°:
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
- ë€ë¥ž ì¬ëë€ìŽ ë§íë¯ìŽ ì€ë¥ ê° íìž ë° í ë¹ì ë¶í¬ëª íê³ ìŽë¡ì ì ëë€. 귞늬ê³
ì¢ ë 구첎ì ìŒë¡ ë§ìíŽ ì£Œììì€. "ë¶í¬ëª íê³ í¹ìŽí" ê²ì ì§ê·¹í 죌êŽì ì ëë€. ì ììŽ íŒëë ì ìë€ê³ ìê°ëë ìœëì ëª ê°ì§ ì륌 ì ìí ì ììµëê¹?
- =? 구묞ë ë¹ì ìì ì ëë€. [âŠ]
IMO ê·ž êž°ë¥ì ëë€. ëêµ°ê° ë¹ì ìì ìž ì°ì°ì륌 볞ë€ë©Ž ì íí ìë ìê³ ì ííì§ ìì ìë ìë 묎ìžê°ë¥Œ ê°ì íë ëì ê·ž ì°ì°ìê° ìííë ìì ì ì°Ÿë 겜í¥ìŽ ë í¬ë€ê³ ìê°í©ëë€.
- ì€ë¥ì íšê» ì íší ê°ì ë°ííë ê²ì 몚ë ì ì룚ì ììë íŽë¹ ì¬ë¡ë¥Œ ì²ëŠ¬íŽìŒ í ë§íŒ ìŒë°ì ì ëë€.
ê·žë ìµëë€?
ì ìì 죌ì ê¹ê² ìœìŒììì€. =?
ë 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ì€ë¡ ëìŽë©ëë€.
ëžë¡ì 목ì ì ë ê°ì§ì ëë€.
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ë ë€ì곌 ê°ì ìŽì ë¡ ìœêž°ê° íšì¬ ìœê³ ë¹ ëŠ ëë€.
ëìê² ìŽ ì ìì ë¶ìì íŽ ë³ŽìŽê³ ë묎 ë§ì ë§ë²ì ê°ì§ê³ ììµëë€. ??
ì°ì°ìë ìŽë»ê² ì ìë©ëê¹? "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ë ë€ì곌 ê°ì ìŽì ë¡ ìœêž°ê° íšì¬ ìœê³ ë¹ ëŠ ëë€.
- ìì§ ê³µê°ì ë ëë¹
- ìŒìªœì íë³µí êžžì 빚늬 ìœêž° ìœìµëë€.
- ì€ë¥žìªœì ì€ë¥ 조걎ì ë¹ ë¥Žê² ìœêž° ìœìµëë€.
- íšìì ë¡ì»¬ ë€ìì€íìŽì€ë¥Œ ì€ìŒìí€ë ì€ë¥ ë³ìê° ììµëë€.
â
ë¹ì ìŽ ëêžì ë¬ìêž° ë묞ì ìŽê²ì ë°ë ê²ì ëë€.
ìŽ ìŽë©ìŒì ì§ì ëµì¥íê±°ë 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
}
ë°ëì ì§ë¶í íí곌 ê°ìµëë€. ìœê³ ì¶ì§ ìê³ ê·žë¥ ê±Žëë°ê³ ì¶ì ë¿ì ëë€.
ì§êžê¹ì§ ìŽ í ë¡ ìì 볞 ê²ì ë€ì곌 ê°ì ì¡°í©ì ëë€.
ìŽê²ì ë ê°ì§ ìž¡ë©Žì 몚ë ìžêží @ianlancetaylor ì ìë 묞ì ì€ëª 곌
ížì§/íì¥ë ìŽíë¡ ì¬êž°ì ë³Žê³ íë ìë íìììë @gladkikhartem ì ììŽëìŽê° ëëë€ .
result, ^ := someAction()
funcì 맥ëœìì:
func getOddResult() (int, error) {
result, ^ := someResult()
if result % 2 == 0 {
return result + 1, nil
}
return result, nil
}
ìŽ ì§§ì 구묞 ëë @gladkikhartem ìŽ err^
ë¡ ì ìí íìì 묞ì (1)ì 구묞 ììžë ë¶ë¶ì ì²ëŠ¬í©ëë€.
ë ë²ì§ž ë¶ë¶ì ê²œì° ì»ší
ì€ížë¥Œ ë ì¶ê°íë©Ž ì§êžì ìì í ììŽë²ëŠŽ ìë ìê³ ëì€ì í¹ë³í 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ê° ëë ëª ê°ì ì¶ê° íëª©ë§ í¬íšíë Ʞ볞 짧ì ì€íì ê°ì§ ê°ë¥ì±ì ììíìµëë€. ê°ë°ìë ìŒë°ì ìŒë¡ ê°ë°/ëë²ê·ž ë²ì ìì ì 첎 ì¶ì ì íì±ííê³ ê·žë ì§ ììŒë©Ž Ʞ볞ê°(짧ì ì€í ì¶ì )ì ê·žëë¡ ë¡ëë€.
ì í êž°ì :
ê·žë¥ ìê°ììí ìì.
@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 볞ì§ì ìŒë¡
ìì?
with
묞 ëŽë¶ì ííìì ì var륌 ì ìží ì ììŒë¯ë¡ ìëê° ëžë¡ ìžë¶ ë³ì륌 íê°íë ê²ìì ëª
ìì ìŒë¡ ëíë
ëë€.with
ëŽë¶ì ëª
ë ¹ë¬žì try
ë° catch
ëžë¡ ëŽë¶ì²ëŒ ìëí©ëë€. ì€ì ë¡ ìµì
ì ìë늬ì€ìì with
ì 조걎ì íê°íŽìŒ íë ê° ë€ì ëª
ë ¹ìì ìëê° ëë €ì§ ê²ì
ëë€.if
륌 ì ê±°íê³ ížë€ë¬ê° íì ë¡ì»¬ìŽêž° ë묞ì ììž ížë€ë¬ë¥Œ ìì±íì§ ìë ê²ì
ëë€( with
ì ííì ë° else
ëžë¡).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 ìê° ìŽê³Œ ë° ë¡ê·ž ë€í ì²ëŠ¬ì ëí ìœê° êŽë š ìë ê°ì ëì ìŽ êž°ë¥ì ì¬ì©íì¬ ìŽì ì ì»ì ì ìë ì€ì ìíížìšìŽì ì륌 ì íží©ëë€.
ì€í ì¶ì ìŽ ë ë늌
ì€í ì¶ì ìŽ ì€ë¥ 겜ë¡ìì ìì±ëë€ë ì ì ê°ìí ë ìëê° ìŒë§ë ë늰ì§ë ì묎ë ì 겜 ì°ì§ ììµëë€. ìíížìšìŽì ì ìì ìž ìëìŽ ìŽë¯ž ì€ëšëììµëë€.
볎ììì ìŽì ë¡ ì¥ëê° íë¡ì íž ìžë¶ìì ì¬ì©íêž°ì ë¶ì í©
ì§êžê¹ì§ ëšìŒ íë¡ëì ìì€í ìŽ "볎ììì ìŽì " ëë ê·ž 묞ì ë¡ ìžíŽ ì€í ì¶ì ì ëë ê²ì ìì§ ë³Žì§ ëª»íìµëë€. ë°ë©Žì ìœëê° ì€ë¥ë¥Œ ìì±íë ë° ê±žëŠ° 겜ë¡ë¥Œ ë¹ ë¥Žê² ìë³í ì ìë€ë ê²ì ë§€ì° ì ì©íìµëë€. ê·žëŠ¬ê³ ìŽê²ì ìœë êž°ë°ìì ìì íë ì¬ë¬ í곌 ì 첎 ìì€í ì ëí ìì í ì§ììŽ ìë ëê·ëªš íë¡ì ížë¥Œ ìí ê²ì ëë€.
볎ìŽì§ ìë ê²ì ì¬ì í ââíìŽíëŒìžì ì²ëŠ¬ëì ì íìí¬ ì ììµëë€.
ìë, ì ë§ ê·žë ì§ ììµëë€. ìì ë§íë¯ìŽ ì€í ì¶ì ì ì€ë¥ì ëíŽ ìì±ë©ëë€. ìíížìšìŽìì ì§ìì ìŒë¡ ìŽë¬í 묞ì ê° ë°ìíì§ ìë í ì²ëŠ¬ëì ì¡°êžë ìí¥ì ë°ì§ ììµëë€.
ì€í ì¶ì ìŽ ì€ë¥ 겜ë¡ìì ìì±ëë€ë ì ì ê°ìí ë ìëê° ìŒë§ë ë늰ì§ë ì묎ë ì 겜 ì°ì§ ììµëë€. ìíížìšìŽì ì ìì ìž ìëìŽ ìŽë¯ž ì€ëšëììµëë€.
ì¬ë°ë¥Žì§ ìì.
@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 , ëìê² ìŽê²ìŽ ê°ì¥ ì¢ì 볎ìŽì§ë§ ì§ë¶êžìŽ ê·žë ê² ì¢ìì§ íì íì§ ëª»í©ëë€.
?
ì°ì°ì륌 ì€ë¥ê° ìë ê°ì ì ì©í ì ììµëê¹? (!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ë ì€ë¥ ì²ëŠ¬ë¥Œ ê°ì íì§ ìì§ë§ 늰í°ë ìíí©ëë€. (ìë§ ì°ëŠ¬ë ìŽê²ì ìíŽ ëŠ°í°ë¥Œ ìì±íŽìŒ í ê¹ì? )
ì¢ì, ì°ëŠ¬ê° íŽê²°ì± ì ì ìí ì ìê³ ëªšëê° ìì ì ë°©ììŒë¡ ì ìì ìŽíŽíë€ë©Ž - ì°ëŠ¬ê° íìë¡ íë ê²ì ëí ëª ê°ì§ ì구 ì¬íì ì§ì íì§ ìê² ìµëê¹? 뚌ì ì구 ì¬íì ëìíê³ ì룚ì ì ê°ë°íë ê²ìŽ íšì¬ ì¬ìŽ ìì ìŽ ë ê²ì ëë€.
ì륌 ë€ìŽ:
@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ì ë€ì곌 ê°ìŽ ìê°íê³ ìë ê² ê°ìµëë€.
@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ì ë¶íìíê² ë§ë€ê³ ê·žê²ì ëí ìì í ì í ìì ì±ì ì»ìµëë€.
ê·žëŠ¬ê³ ê·žê²ìŽ ë°ë¡ 묞ì ì ëë€. ì€ë¥ê° ì íëê³ ì ìŽ íëŠìŽ ë³ê²œë ê²ìŽëŒë ëª ìì ìž íì ììŽ ë³ê²œë©ëë€.
ìŽê²ì ëìê² ì¬ì€ë¡ ë€ëŠ°ë€. ë€ë¥ž íší€ì§ë¥Œ ì¬ì©íë ìŒë¶ íší€ì§ë¥Œ ê°ë°íê³ íŽë¹ íší€ì§ìì ììžê° ë°ìíë ê²œì° ìŽì _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 ì íì ëìŽìë ì€ë¥ ë³í© ë° íŽë¹ ìì ì ê¶ì¥ëìŽìë ì ë©ëë€. ëìê² ìŽê²ì êŽë šëì§ ìì ë€ë¥ž ìì ìì ë°ìíë ì€ë¥ ì¬ìŽì ì€ë¥ 컚í ì€ížë¥Œ ëííê±°ë ì¶ê°íë €ë ë žë ¥ìŽ ë¶ì¡±íšì ëíë ëë€.
ì€ìºë ì ê·Œ ë°©ìì "ì€ë¥ë ê°ì¹ë€"ëŒë ë§ížëŒì 맥ëœìì ëŽê° ìœì ìµì ì ê² ì€ íëì ëë€.
겜ì°ì ë°ëŒ 컎íší 늬ìì€ê° ëë¹ë©ëë€.
ë²€ì¹ë§í¬? "컎íší 늬ìì€"ë ì íí 묎ìì ëê¹?
ì€ë¥ê° ë°ìí ì íí ìì¹ë¥Œ ìšê¹ëë€.
ìëì€, ê·žë ì§ ììµëë€. 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' íìë³Žë€ í ëì ìì볎Ʞ ìœë€ê³ ìê°í©ëë€. í í°ì ì ë¬/ìŽíŽíêž° ìíŽ ìì±/ìœêž°íŽìŒ íë ìœëì ìì í¬ê² ì€ìŒ ì ììµëë€.
몚ë 구묞 êž°ë¥ê³Œ ë§ì°¬ê°ì§ë¡ ëšì©ì ê°ë¥ì±ìŽ ììµëë€. ìŽ ê²œì° go 컀뮀ëí°ìë ìŽë¯ž íšëì ë€ë£šë ëªšë² ì¬ë¡ê° ììµëë€. ìŽ êµ¬ë¬ž ì¶ê°ë íšëì ëí 구묞 ì€íìŽë¯ë¡ íŽë¹ ëªšë² ì¬ë¡ ì§í©ì ì¬ì©ì ì ì©í ì ììµëë€.
íšëì ëí ìì© ê°ë¥í ì¬ì© ì¬ë¡ë¥Œ ëšìííë ê² ìžìë ë¹ ë¥ž íë¡í íìŽíì ë ìœê² ë§ëëë€. ìœëì êž°ë¡íê³ ì¶ì ììŽëìŽê° ìê³ ì¥ëì ì¹ë ëì ì€ë¥ë¡ ìžíŽ íë¡ê·žëšìŽ ì€ëšëꞰ륌 ìíë ê²œì° "if-error-panic" íì ëì ìŽ êµ¬ë¬ž ì¶ê°ë¥Œ ì¬ì©í ì ììµëë€. ê°ë° ìŽêž° ëšê³ìì ë ì ì ì€ë¡ ë륌 ííí ì ìë€ë©Ž ë 빚늬 ëŽ ììŽëìŽë¥Œ ìœëë¡ êµ¬íí ì ììµëë€. ìœëì ëí ìì í ììŽëìŽê° ììŒë©Ž ëìê°ì ì ì í 겜ê³ìì ì€ë¥ë¥Œ ë°ííëë¡ ìœë륌 늬í©í ë§í©ëë€. ëë íë¡ëì ìœëì ë¬Žë£ íšëì ëšêž°ì§ ìê² ì§ë§ ê°ë ¥í ê°ë° ëêµ¬ê° ë ì ììµëë€.
íšëì ë€ë¥ž ìŽëŠì ììžìŒ ë¿ìŽê³ , ëŽê° Goì ëíŽ ì¢ìíë í ê°ì§ë ììžê° ììžì ìŽëŒë ê²ì ëë€. ëë ê·žë€ìê² êµ¬ë¬žìì ì€íì ì£ŒìŽ ë ë§ì ììžë¥Œ ì¡°ì¥íê³ ì¶ì§ ììµëë€.
@carlmjohnson ë ê°ì§ ì€ íëê° ì¬ì€ìŽìŽìŒ í©ëë€.
ëë ëëµìŽ 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 ìœëìì íšëìŽ ì¬ì©ëë ë°©ìì ìëë©° ì€ë¥ë¥Œ ì ííë 겜ì°ë¥Œ ìíŽ í¹ë³í ì°ì°ì륌 ì¶ê°íë ê²ìŽ ìëëŒê³ ìê°í©ëë€. íšëì íµíŽ ížì¶ ì€íì ì¬ëŠ¬ë©Ž ì¬ëë€ìŽ íšëì ì¬ì©íë ë°©ììŽ ë°ë ê²ì ëë€. ê·žë€ì ìŽìšë ê³µí©ì ì¬ì©íê³ ììµëë€. ìŽ êµ¬ë¬ž íì¥ì ìì ì ê°ë°ìê° íšëì ì¬ì©íê³ ì벜íê² í©ë²ì ìž ì©ëê° ìë€ë ì¬ì€ì ìžì íê³ ì£Œë³ì ìì©êµ¬ë¥Œ ì€ìŽë ê²ì ëë€.
ìŽ êµ¬ë¬ž êž°ë¥ìŽ ê°ë¥íë€ê³ ìê°íì§ë§ íì¬ ê°ë¥íì§ ìê±°ë ëªšë² ì¬ë¡ì ìŽêžëë 묞ì ê° ìë ìœëì ëª ê°ì§ ì륌 ë€ìŽ 죌ìê² ìµëê¹? ëêµ°ê°ê° íšë/복구륌 íµíŽ ìœë ì¬ì©ììê² ì€ë¥ë¥Œ ì ë¬íë 겜ì°, ìŽë íì¬ ëìŽì ì°ížëŠ¬ê² íê³ ë¶ëª í ìŽì ê°ì êµ¬ë¬žìŽ ì¶ê°ëëëŒë ì¬ì í ê³ìë ê²ì ëë€. ê°ë¥íìë€ë©Ž ë€ì ëµë³ì ë¶íë늜ëë€.
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 ì€ë¥ ì²ëŠ¬ì êŽí ê²ì ëë€.
ì€ë¥ë¥Œ 묎ìíë ê²ìŽ ìŽë¯ž ì¡Žì¬íë _
ìŽë¯ž í¬íšëìŽ ìë€ê³ ê°ì íêž° ë묞ì "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 ë 믞í/ìžì²Ž ê³µí(ëë êž°ê»íŽìŒ ìœë ë²í¬ì êŽë šë ì íì± ë¬žì )곌 ëì¡°ëë 믞ë¬í ì íì± ë¬žì ì êŽí ê²ìŽêž° ë묞ì ì ìê²
ëêµ°ê° ëŽê² ì€í곌 ë§ë²ì ì°šìŽì ëíŽ ë¬ŒìŽë³Œ ê² ê°ì ëëìŽ ë ë€. (ì§ì 묌ìŽëŽ ëë€.)
ì ë ìŽ ë§ë²ì ì ì륌 ì¬ì©í©ëë€. ìœê°ì ìì€ ìœë륌 ìŽíŽë³Žë©Ž ë€ì ìê³ ëŠ¬ìŠì ìŒë¶ ë³íì ìíŽ ìíëìŽìŒ íë ìì ì íì í ì ììµëë€.
ìŽ ìê³ ëŠ¬ìŠìŽ _ì ë¢°ì± ìê²_ ìœëê° ìíí ìì ì ëí ì¬ë°ë¥ž ìŽíŽë¥Œ ìì±íë€ë©Ž ê·žê²ì ë§ë²ìŽ ìëëë€. ê·žë ì§ ìë€ë©Ž ê·ž ìì ìŽë ì ëì ë§ë²ìŽ ìë ê²ì ëë€. 묞ì ì°žì¡° ë° ìë³ì ì ì륌 ë°ëŒ ë€ë¥ž ìë³ì ì ì륌 ë°ë¥Žë €ê³ í ë ìŽë¥Œ ìŒë§ë ì¬ê·ì ìŒë¡ ì ì©íŽìŒ íëì§ë 묞ì ì 구ì±/ìœëì _ë³µì¡ë_ê° ìë _ë³µì¡ë_ì ìí¥ì 믞칩ëë€.
ë§ë²ì ìë ë€ì곌 ê°ìµëë€. ë€ìì€íìŽì€ ììŽ ê°ì žì€êž° ë묞ì ì볞ìŒë¡ ëìê°ë ëª íí 겜ë¡ê° ìë ìë³ì(í¹í ë ìŽììŽ ìë ê²œì° 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ê°ì§ 겜ì°ì ì€ë¥ ì²ëŠ¬ë¥Œ ì²ëŠ¬í ì ììŽìŒ íë€ë ê²ì ëë€.
ì ìì ë€ì ìž ê°ì§ ë²ì£Œ ì€ íëì ìíë ê² ê°ìµëë€.
try-catch-finally
ì€íìŒì ì€ë¥ ì²ëŠ¬ë¡ ëë늜ëë€.죌ìŽì§ ì ìì ëí ë¹íì ìœë ê°ë ì±, ëª ííì§ ìì ì í, ë²ìì ë³ìì ììì ì¶ê°, ê°ê²°ì±ì ëí ì°ë €ë¡ ëëë ê² ê°ìµëë€. ê°ìžì ìŒë¡ë ì ìì ëí ë¹íì ê°ìžì ìž ìê²¬ìŽ ë§ìŽ ëìë€ê³ ìê°í©ëë€. ê·žê²ìŽ ëìë€ë ë§ì ìëì§ë§, ì ìì륌 íê°í ê°êŽì ìž êž°ì€ì ìë ê² ê°ìµëë€.
ëŽê° ê·ž êž°ì€ ëª©ë¡ì ë§ë€ë €ê³ íë ì¬ëì ìëì§ ëªšë¥Žì§ë§ ëêµ°ê°ê° ê·žê²ì ì 늬íë€ë©Ž ë§€ì° ëììŽ ë ê²ìŽëŒê³ ìê°í©ëë€. ëë ì§êžê¹ì§ ë Œìì ëí ëì ìŽíŽë¥Œ 1. ì°ëŠ¬ê° 볞 ê², 2. 묎ììŽ ì못ëìëì§, 3. ê·žê²ë€ìŽ ì못ë ìŽì , 4. ì°ëŠ¬ê° 묎ìì ëì ë³Žê³ ì¶ìŽ. ëë ì²ì 3ê° í목ì ìë¹í ìì 캡ì²íë€ê³ ìê°íì§ë§ "íì¬ Goê° ê°ì§ê³ ìë ê²"ì ìì§íì§ ìê³ í목 4ì ëí ëµì ì°Ÿë ë° ìŽë €ìì ê²ªê³ ììµëë€.
@jba ìë ë ë§ì 컚í ì€ížë¥Œ ìíŽ ìì ë ë€ë¥ž ë©ì§ ììœ ì£ŒììŽ ììµëë€. ê·žë ëŽê° ì¬êž°ì ë§í ë§ì ê²ì ë€ë¥ž ë§ë¡ ë§í©ëë€.
@ianlancetaylor ëë ëë³Žë€ íë¡ì ížì ë ë°ì íê² êŽë šë ë€ë¥ž ì¬ëìŽ
ëë í¬êŽì ìŽê³ ê³µìì ìž êž°ì€ ìžížë¥Œ ìì±í ì ìë€ê³ ìê°í©ëë€. ëŽê° í ì ìë ìµì ì ê·žë ê² íšìŒë¡ìš ìë¹í ìŽì ìŽ ìë 겜ì°ìë§ ë¬ŽìëìŽìŒ íë ì€ìí ìŒì ë¶ìì í 목ë¡ì ëë€.
ëë ì¬êž°ìì ìŽë€ ìì ìì ë©ëªšë¥Œ ìì§íꞰ륌 í¬ë§íì§ë§ ìŽ í ë¡ ìì 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
}
(ìœë륌 ë묎 ë§ìŽ ì¬ì©íì§ ë§ì. ë¬Œë¡ ë§ì ìë ìì§ë§ ìŽê²ì ëŽ ì€ì ìœëê° ìëë©° ìœê° ìì ëììì êž°ìµíììì€. ê·žëŠ¬ê³ ê·íì ìí ìœë륌 ê²ìíë ê²ì ë§ì ìë ììµëë€.)
êŽì°°:
if forwardPort == 0
ì ì _ìëì ìŒë¡_ ì€ë¥ë¥Œ íµíŽ ê³ìëë©°, ì, ìŽê²ì ì€ì ëììŽë©° ìŽ ìì ìì ì¶ê°í ê²ìŽ ìëëë€.ìŽê²ìŽ ê°ë¥í 몚ë ì€ë¥ ëìì 볎ì¬ì€ë€ê³ 죌ì¥íì§ë ìê² ì§ë§ ꜀ ë§ì ììì ë€ë£¹ëë€. (ëë ëŽ ââìœëê° ì늬ë ë쯀ìŽë©Ž ëŽ ë€ížìí¬ ìë²ìì ëŽê° _몚ë ì¢ ë¥ì_ ì€ë¥ ëìì íë 겜ì°ê° ì¢ ì¢ ììì ì§ì íšìŒë¡ìš 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ê°ì§ ì¡°ì ì ì ìí©ëë€.
nil
ë false
, nil
~ true
&&
ë° ||
ì ê°ì ëšìŒ í 조걎묞 ì°ì°ì ì§ìê·žëì
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
}
ìŽì ì,
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 ê°ì ë°ííë íšíŽ
ëí 겜í ë³Žê³ ìì ëíŽ @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
}
ìë¡ìŽ 구묞 êž°ë¥ìŽ íìí©ëë€.
collect
_!
(ëë íììì ìŽê²ì ê°ì§ê³ ëìê³ , ë€ë¥ž ê²ì 깚ëšëŠ¬ì§ ìê³ ìŽ ìŒì¹ë¥Œ identë¡ ë§ëë ê²ì ìŽë µì§ ìë€)ëŽê° ìŽì ê°ì ê²ì ì ìíë ìŽì ë "ì€ë¥ ì²ëŠ¬ê° ë묎 ë°ë³µì ìŽë€"ëŒë 죌ì¥ìŽ "묎 ê²ì¬ê° ë묎 ë°ë³µì ìŽë€"ë¡ ììœë ì ìêž° ë묞ì
ëë€. Goìë ìŽë¯ž ìë ê·žëë¡ ìëíë ì€ë¥ ì²ëŠ¬ êž°ë¥ìŽ ë§ìŽ ììµëë€. _
íì¬ ì€ë¥ë¥Œ 묎ìí ì ììµëë€(ëë ë°í ê°ì 캡ì²íì§ ìì ì ìì). ìì ëì§ ìì ì€ë¥ë¥Œ if err != nil { return err }
ë°ííê±°ë 컚í
ì€ížë¥Œ ì¶ê°íê³ if err != nil { return wrap(err) }
ë°íí ì ììµëë€. ìŽë¬í ë°©ë² ì€ ìŽë ê²ë ì첎ì ìŒë¡ ë묎 ë°ë³µì ìŽì§ ììµëë€. ë°ë³µì±( ë¶ëª
í )ì ìœë ì 첎ìì ìŽë¬í 구묞 ëë ì ì¬í 구묞ì ë°ë³µíŽìŒ íêž° ë묞ì ë°ìí©ëë€. nilìŽ ìë ê°ìŽ ë°ìí ëê¹ì§ ëª
ë ¹ë¬žì ì€ííë ë°©ë²ì ëì
íë ê²ì ì€ë¥ ì²ëŠ¬ë¥Œ ëìŒíê² ì ì§íë©Žì íìí ìì©êµ¬ì ìì ì€ìŽë ì¢ì ë°©ë²ìŽëŒê³ ìê°í©ëë€.
ëìŒíê² ì ì§ëë¯ë¡ íìžíììì€(ëë¶ë¶).
ì€ë¥ ì²ëŠ¬ ìœëë ìŽì íìí ê²œì° í ê³³ìŒë¡ ìŽëí ì ìì§ë§ íšìì íµì¬ì ì íìŒë¡ ìœì ì ìë ë°©ììŒë¡ ë°ìí ì ììµëë€.
íìžíìžì, ìŽê²ì ì¶ê° ì¬íìŽì§ ë³ê²œ ì¬íìŽ ìëëë€.
íìžíììì€. ì€ë¥ ì²ëŠ¬ ë©ì»€ëìŠìŽ ë€ë¥Žì§ ìêž° ë묞ì - ìŒë šì ì€í ë° í ë¹ìì nilìŽ ìë 첫 ë²ì§ž ê°ì "ìì§"íë êµ¬ë¬žìŽ ìì ë¿ìŽë©°, ìŽë ì€ë¥ ì륌 ì ííë ë° ì¬ì©í ì ììµëë€. íšììì ì€ë¥ ì²ëŠ¬ ìœë륌 ìì±íŽìŒ íë ìì¹
ì ìë êž°ë¥ìŽ ëšìí ì€ë¥ ì²ëŠ¬ ìŽìì ì ì©ëêž° ë묞ì ìŽê²ìŽ ì¬êž°ì ì ì©ëëì§ íì€íì§ ììµëë€. ëë ê·žê²ìŽ nil ê²ì¬ì ì¡°êž° ë°íì ìŽì§ëœíì§ ìê³ ì€ë¥ë¥Œ ìì± í ì ìë ìœë륌 ëšì¶íê³ ëª ííê² í ì ìë€ê³ ìê°í©ëë€.
ëìíê³ ë²ìê° ì€ë¥ ì²ëŠ¬ ìŽììŒë¡ íì¥ëë ë³ê²œìŽ ì ì í ì ììµëë€. 귌볞ì ìž ë¬žì ë nil
ì²Ží¬ ìžìŽ ë°ë³µì ìŽê³ ì¥í©íŽì§ë€ë ê²ìŽë©° error
ë nil
-able ì íì
ëë€.
@KernelDeimos ì°ëŠ¬ë 볞ì§ì ìŒë¡ ê°ì ê²ì ìê°íŽ ëìµëë€. ê·žë¬ë í ëšê³ ë ëìê° x, ? := doSomething()
ë°©ììŽ ì€ì ë¡ë ì ìëíì§ ìë ìŽì 륌 ì€ëª
íìµëë€. ? ì°ì°ì륌 í¥ë¯žë¡ìŽ ë°©ììŒë¡ ìžìŽë¡ ë³íí©ëë€.
ìŽê²ì Ʞ볞ì ìŒë¡ ê·žë¥ íšì ìëê°ì?
ë€ìì ì€í볌ì ëë€.
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
ìžì€íŽì€ì ëíŽ ì»ŽíìŒë¬ ê²œê³ ëë 늰ížë¥Œ ì ê³µíë©Ž ? ìžìŽ ë³ê²œìŽ íìíì§ ììµëë€.
ëê°ì§:
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
}
ë€ì곌 ê°ì ê²œì° íë¡ê·žëš íììŽ ì못ëììµëë€.
ìŽ ì ìì ê°ì¹ ìë ê²ì ëíŽ ë ë§ì 컚í ì€íž ì 볎륌 ì ê³µíë 묞ì 륌 ë€ë£šì§ ìëë€ë ì ìì ë€ë¥ž ì ì곌 ì ì¬í©ëë€.
@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 ê²ì¬ë ëª
íì±ì í¬ìíì§ ìê³ ê°ë¥í í ê°ëší©ëë€(ìë 구묞ì ëí ì°žê³ ì°žì¡°).
구묞ì ëí ì°žê³ ì¬í
ëë ìŽë° ì¢
ë¥ì 구묞(ì€ì ìì ë¶ë¶ìì .., ë°í곌 ì ì¬íš)ìŽ ììì ë°íìŽ ëì
íë ì ìŽ íëŠ ì€ëšì ìšêž°ì§ ìê³ ì€ë¥ ê²ì¬ ìì©êµ¬ë¥Œ ì ê±°íë ì¢ì ë°©ë²ìŽëŒê³ 죌ì¥í©ëë€.
ë€ì곌 ê°ì ììŽëìŽì ëšì
ê²ì¬ 묞ì íì íì¬ ëžë¡ìì ìµìì ìì€ìŽ ëë©° ì ìŽ íëŠì ìì íë ë€ë¥ž 묞(ì: ì¡°êž° ë°í)곌 ëìŒí ì€ìì±ì ê°ìµëë€.
ì¬êž° ë ë€ë¥ž ìê°ìŽ ììµëë€.
ë ìŽëžìŽ ìë 맀í¬ë¡ë¥Œ ì ìíë 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ì ìŽë»ê²ë ë§ì ì²ëŒ ìëíŽìŒ íë ||
ì°ì°ìì ëíŽ ìŽìŒêž°íê³ ììµëë€. ëë ê·žê²ì ì¢ìíì§ ìëë€.
ê°ì¥ ì ì©í ëêž
ì€ë¥ ì¥ìì ì§ìíì§ë§ ë 곌ê°í ìžìŽ ë³ê²œ(go1.10ì ìë)ìŽ íìí ëšìí ììŽëìŽë ìë¡ìŽ
check
í€ìëì ëì ì ëë€.check A
ë°check A, B
ë ê°ì§ íììŽ ììµëë€.A
ë°B
ë 몚ëerror
ì¬ìŒ í©ëë€. ë ë²ì§ž íìì ì€ë¥ë¥Œ ì¥ìí ëë§ ì¬ì©ë©ëë€. ìì ì ì€ë¥ë¥Œ ì¥ìí íìê° ìê±°ë êŸžë¯žê³ ì¶ì§ ìì ì¬ëë€ì ë ê°ëší íìì ì¬ì©í©ëë€.첫 ë²ì§ž ìì(A 첎í¬)
check A
ëA
íê°í©ëë€.nil
ìŽë©Ž ì묎 ìì ë ìííì§ ììµëë€.nil
ìëë©Žcheck
ëreturn {<zero>}*, A
ì²ëŒ ìëí©ëë€.ì
check
ìžëŒìžìŒë¡ ì¬ì©í ì ììŒë¯ë¡ëë€
ëë€
ë ë²ì§ž íì(A, B 첎í¬)
check A, B
ëA
íê°í©ëë€.nil
ìŽë©Ž ì묎 ìì ë ìííì§ ììµëë€.nil
ìëë©Žcheck
ëreturn {<zero>}*, B
ì²ëŒ ìëí©ëë€.ìŽê²ì ì€ë¥ ì¥ìì ìí ê²ì ëë€. ì°ëŠ¬ë ì¬ì í íìž
A
, ê·žë¬ëì ëë€B
ìì ì ìŒë¡ ì¬ì©ëëreturn
.ìì
ëë€
ë žíž
컎íìŒ ì€ë¥ì ëë€
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
)곌 ëìŒí ì€ìì±ì ê°ìµëë€.