[{"data":1,"prerenderedAt":4212},["ShallowReactive",2],{"page-\u002Fgo\u002F06-control-flow":3},{"id":4,"title":5,"body":6,"description":4205,"extension":4206,"meta":4207,"navigation":92,"path":4208,"seo":4209,"stem":4210,"__hash__":4211},"content\u002Fgo\u002F06-control-flow.md","06 — Control Flow",{"type":7,"value":8,"toc":4198},"minimark",[9,13,47,54,4194],[10,11,5],"h1",{"id":12},"_06-control-flow",[14,15,16,17,21,22,21,25,21,28,31,32,35,36,39,40,39,43,46],"p",{},"Go has five control-flow constructs: ",[18,19,20],"code",{},"if",", ",[18,23,24],{},"for",[18,26,27],{},"switch",[18,29,30],{},"select",", and ",[18,33,34],{},"goto",". No ",[18,37,38],{},"while",", no ",[18,41,42],{},"do-while",[18,44,45],{},"match",". This chapter covers the production patterns and the compiler-level mechanics.",[48,49,51,53],"h2",{"id":50},"if-init-statement-and-scoping",[18,52,20],{}," — Init Statement and Scoping",[55,56,58,278,283,4119,4178,4182],"code-wrapper",{"language":57},"go",[59,60,64],"pre",{"className":61,"code":62,"language":57,"meta":63,"style":63},"language-go shiki shiki-themes github-light github-dark","\u002F\u002F The if-init form: `if init; condition { ... }`\n\u002F\u002F The init statement runs before the condition; the declared variable\n\u002F\u002F is scoped to the if\u002Felse block — it doesn't leak to the outer scope.\n\nfunc ifInit() {\n    \u002F\u002F ✅ Idiomatic: err scoped to the if block\n    if err := doWork(); err != nil {\n        log.Fatal(err)\n    }\n    \u002F\u002F err is NOT accessible here — it's block-scoped\n\n    \u002F\u002F ❌ ANTI-PATTERN: leaking err to the outer scope\n    \u002F\u002F err := doWork()\n    \u002F\u002F if err != nil { ... }\n    \u002F\u002F err is still alive here — unnecessary scope pollution\n\n    \u002F\u002F Multiple init variables:\n    if user, err := fetchUser(id); err != nil {\n        return err\n    } else {\n        process(user)  \u002F\u002F user only accessible in the else block\n    }\n    \u002F\u002F neither user nor err is accessible here\n}\n","",[18,65,66,75,81,87,94,109,115,143,155,161,167,172,178,184,190,196,201,207,229,238,249,261,266,272],{"__ignoreMap":63},[67,68,71],"span",{"class":69,"line":70},"line",1,[67,72,74],{"class":73},"sdCPZ","\u002F\u002F The if-init form: `if init; condition { ... }`\n",[67,76,78],{"class":69,"line":77},2,[67,79,80],{"class":73},"\u002F\u002F The init statement runs before the condition; the declared variable\n",[67,82,84],{"class":69,"line":83},3,[67,85,86],{"class":73},"\u002F\u002F is scoped to the if\u002Felse block — it doesn't leak to the outer scope.\n",[67,88,90],{"class":69,"line":89},4,[67,91,93],{"emptyLinePlaceholder":92},true,"\n",[67,95,97,101,105],{"class":69,"line":96},5,[67,98,100],{"class":99},"svdQ7","func",[67,102,104],{"class":103},"sIsaT"," ifInit",[67,106,108],{"class":107},"ssxIu","() {\n",[67,110,112],{"class":69,"line":111},6,[67,113,114],{"class":73},"    \u002F\u002F ✅ Idiomatic: err scoped to the if block\n",[67,116,118,121,124,127,130,133,136,140],{"class":69,"line":117},7,[67,119,120],{"class":99},"    if",[67,122,123],{"class":107}," err ",[67,125,126],{"class":99},":=",[67,128,129],{"class":103}," doWork",[67,131,132],{"class":107},"(); err ",[67,134,135],{"class":99},"!=",[67,137,139],{"class":138},"snvgF"," nil",[67,141,142],{"class":107}," {\n",[67,144,146,149,152],{"class":69,"line":145},8,[67,147,148],{"class":107},"        log.",[67,150,151],{"class":103},"Fatal",[67,153,154],{"class":107},"(err)\n",[67,156,158],{"class":69,"line":157},9,[67,159,160],{"class":107},"    }\n",[67,162,164],{"class":69,"line":163},10,[67,165,166],{"class":73},"    \u002F\u002F err is NOT accessible here — it's block-scoped\n",[67,168,170],{"class":69,"line":169},11,[67,171,93],{"emptyLinePlaceholder":92},[67,173,175],{"class":69,"line":174},12,[67,176,177],{"class":73},"    \u002F\u002F ❌ ANTI-PATTERN: leaking err to the outer scope\n",[67,179,181],{"class":69,"line":180},13,[67,182,183],{"class":73},"    \u002F\u002F err := doWork()\n",[67,185,187],{"class":69,"line":186},14,[67,188,189],{"class":73},"    \u002F\u002F if err != nil { ... }\n",[67,191,193],{"class":69,"line":192},15,[67,194,195],{"class":73},"    \u002F\u002F err is still alive here — unnecessary scope pollution\n",[67,197,199],{"class":69,"line":198},16,[67,200,93],{"emptyLinePlaceholder":92},[67,202,204],{"class":69,"line":203},17,[67,205,206],{"class":73},"    \u002F\u002F Multiple init variables:\n",[67,208,210,212,215,217,220,223,225,227],{"class":69,"line":209},18,[67,211,120],{"class":99},[67,213,214],{"class":107}," user, err ",[67,216,126],{"class":99},[67,218,219],{"class":103}," fetchUser",[67,221,222],{"class":107},"(id); err ",[67,224,135],{"class":99},[67,226,139],{"class":138},[67,228,142],{"class":107},[67,230,232,235],{"class":69,"line":231},19,[67,233,234],{"class":99},"        return",[67,236,237],{"class":107}," err\n",[67,239,241,244,247],{"class":69,"line":240},20,[67,242,243],{"class":107},"    } ",[67,245,246],{"class":99},"else",[67,248,142],{"class":107},[67,250,252,255,258],{"class":69,"line":251},21,[67,253,254],{"class":103},"        process",[67,256,257],{"class":107},"(user)  ",[67,259,260],{"class":73},"\u002F\u002F user only accessible in the else block\n",[67,262,264],{"class":69,"line":263},22,[67,265,160],{"class":107},[67,267,269],{"class":69,"line":268},23,[67,270,271],{"class":73},"    \u002F\u002F neither user nor err is accessible here\n",[67,273,275],{"class":69,"line":274},24,[67,276,277],{"class":107},"}\n",[279,280,282],"h3",{"id":281},"brace-rules-mandatory-and-same-line","Brace rules — mandatory and same-line",[55,284,285,389,395],{"language":57},[59,286,288],{"className":61,"code":287,"language":57,"meta":63,"style":63},"\u002F\u002F Go's automatic semicolon insertion (ASI): the lexer inserts a semicolon\n\u002F\u002F after certain tokens at end of line. This means the opening brace MUST\n\u002F\u002F be on the same line as if\u002Ffor\u002Ffunc.\n\n\u002F\u002F ✅ Correct:\nif x > 0 {\n    doSomething()\n}\n\n\u002F\u002F ❌ Compile error: \"syntax error: unexpected semicolon or newline before {\"\n\u002F\u002F if x > 0\n\u002F\u002F {\n\u002F\u002F     doSomething()\n\u002F\u002F }\n\n\u002F\u002F Braces are mandatory even for one-line bodies:\n\u002F\u002F ✅ if x > 0 { return }    — compiles\n\u002F\u002F ❌ if x > 0 return         — syntax error (no braces)\n",[18,289,290,295,300,305,309,314,329,337,341,345,350,355,360,365,370,374,379,384],{"__ignoreMap":63},[67,291,292],{"class":69,"line":70},[67,293,294],{"class":73},"\u002F\u002F Go's automatic semicolon insertion (ASI): the lexer inserts a semicolon\n",[67,296,297],{"class":69,"line":77},[67,298,299],{"class":73},"\u002F\u002F after certain tokens at end of line. This means the opening brace MUST\n",[67,301,302],{"class":69,"line":83},[67,303,304],{"class":73},"\u002F\u002F be on the same line as if\u002Ffor\u002Ffunc.\n",[67,306,307],{"class":69,"line":89},[67,308,93],{"emptyLinePlaceholder":92},[67,310,311],{"class":69,"line":96},[67,312,313],{"class":73},"\u002F\u002F ✅ Correct:\n",[67,315,316,318,321,324,327],{"class":69,"line":111},[67,317,20],{"class":99},[67,319,320],{"class":107}," x ",[67,322,323],{"class":99},">",[67,325,326],{"class":138}," 0",[67,328,142],{"class":107},[67,330,331,334],{"class":69,"line":117},[67,332,333],{"class":103},"    doSomething",[67,335,336],{"class":107},"()\n",[67,338,339],{"class":69,"line":145},[67,340,277],{"class":107},[67,342,343],{"class":69,"line":157},[67,344,93],{"emptyLinePlaceholder":92},[67,346,347],{"class":69,"line":163},[67,348,349],{"class":73},"\u002F\u002F ❌ Compile error: \"syntax error: unexpected semicolon or newline before {\"\n",[67,351,352],{"class":69,"line":169},[67,353,354],{"class":73},"\u002F\u002F if x > 0\n",[67,356,357],{"class":69,"line":174},[67,358,359],{"class":73},"\u002F\u002F {\n",[67,361,362],{"class":69,"line":180},[67,363,364],{"class":73},"\u002F\u002F     doSomething()\n",[67,366,367],{"class":69,"line":186},[67,368,369],{"class":73},"\u002F\u002F }\n",[67,371,372],{"class":69,"line":192},[67,373,93],{"emptyLinePlaceholder":92},[67,375,376],{"class":69,"line":198},[67,377,378],{"class":73},"\u002F\u002F Braces are mandatory even for one-line bodies:\n",[67,380,381],{"class":69,"line":203},[67,382,383],{"class":73},"\u002F\u002F ✅ if x > 0 { return }    — compiles\n",[67,385,386],{"class":69,"line":209},[67,387,388],{"class":73},"\u002F\u002F ❌ if x > 0 return         — syntax error (no braces)\n",[48,390,392,394],{"id":391},"for-one-construct-four-forms",[18,393,24],{}," — One Construct, Four Forms",[55,396,397,664,671],{"language":57},[59,398,400],{"className":61,"code":399,"language":57,"meta":63,"style":63},"\u002F\u002F 1. Traditional (init; condition; post)\nfor i := 0; i \u003C 10; i++ {\n    fmt.Println(i)\n}\n\n\u002F\u002F 2. While-like (condition only)\nn := 10\nfor n > 0 {\n    n--\n}\n\n\u002F\u002F 3. Infinite (break to exit)\nfor {\n    if done {\n        break\n    }\n}\n\n\u002F\u002F 4. Range (slice, array, map, string, channel, integer)\nfor i, v := range items { }  \u002F\u002F index + value\nfor _, v := range items { }  \u002F\u002F value only (discard index)\nfor k, v := range m { }      \u002F\u002F map: key + value\nfor k := range m { }         \u002F\u002F map: key only\nfor i, r := range \"café\" { } \u002F\u002F string: byte_offset + rune\nfor v := range ch { }        \u002F\u002F channel: value (until closed)\nfor i := range 10 { }        \u002F\u002F Go 1.22+: integer (0..9)\n",[18,401,402,407,435,446,450,454,459,469,482,490,494,498,503,509,516,521,525,529,533,538,556,572,589,606,627,645],{"__ignoreMap":63},[67,403,404],{"class":69,"line":70},[67,405,406],{"class":73},"\u002F\u002F 1. Traditional (init; condition; post)\n",[67,408,409,411,414,416,418,421,424,427,430,433],{"class":69,"line":77},[67,410,24],{"class":99},[67,412,413],{"class":107}," i ",[67,415,126],{"class":99},[67,417,326],{"class":138},[67,419,420],{"class":107},"; i ",[67,422,423],{"class":99},"\u003C",[67,425,426],{"class":138}," 10",[67,428,429],{"class":107},"; i",[67,431,432],{"class":99},"++",[67,434,142],{"class":107},[67,436,437,440,443],{"class":69,"line":83},[67,438,439],{"class":107},"    fmt.",[67,441,442],{"class":103},"Println",[67,444,445],{"class":107},"(i)\n",[67,447,448],{"class":69,"line":89},[67,449,277],{"class":107},[67,451,452],{"class":69,"line":96},[67,453,93],{"emptyLinePlaceholder":92},[67,455,456],{"class":69,"line":111},[67,457,458],{"class":73},"\u002F\u002F 2. While-like (condition only)\n",[67,460,461,464,466],{"class":69,"line":117},[67,462,463],{"class":107},"n ",[67,465,126],{"class":99},[67,467,468],{"class":138}," 10\n",[67,470,471,473,476,478,480],{"class":69,"line":145},[67,472,24],{"class":99},[67,474,475],{"class":107}," n ",[67,477,323],{"class":99},[67,479,326],{"class":138},[67,481,142],{"class":107},[67,483,484,487],{"class":69,"line":157},[67,485,486],{"class":107},"    n",[67,488,489],{"class":99},"--\n",[67,491,492],{"class":69,"line":163},[67,493,277],{"class":107},[67,495,496],{"class":69,"line":169},[67,497,93],{"emptyLinePlaceholder":92},[67,499,500],{"class":69,"line":174},[67,501,502],{"class":73},"\u002F\u002F 3. Infinite (break to exit)\n",[67,504,505,507],{"class":69,"line":180},[67,506,24],{"class":99},[67,508,142],{"class":107},[67,510,511,513],{"class":69,"line":186},[67,512,120],{"class":99},[67,514,515],{"class":107}," done {\n",[67,517,518],{"class":69,"line":192},[67,519,520],{"class":99},"        break\n",[67,522,523],{"class":69,"line":198},[67,524,160],{"class":107},[67,526,527],{"class":69,"line":203},[67,528,277],{"class":107},[67,530,531],{"class":69,"line":209},[67,532,93],{"emptyLinePlaceholder":92},[67,534,535],{"class":69,"line":231},[67,536,537],{"class":73},"\u002F\u002F 4. Range (slice, array, map, string, channel, integer)\n",[67,539,540,542,545,547,550,553],{"class":69,"line":240},[67,541,24],{"class":99},[67,543,544],{"class":107}," i, v ",[67,546,126],{"class":99},[67,548,549],{"class":99}," range",[67,551,552],{"class":107}," items { }  ",[67,554,555],{"class":73},"\u002F\u002F index + value\n",[67,557,558,560,563,565,567,569],{"class":69,"line":251},[67,559,24],{"class":99},[67,561,562],{"class":107}," _, v ",[67,564,126],{"class":99},[67,566,549],{"class":99},[67,568,552],{"class":107},[67,570,571],{"class":73},"\u002F\u002F value only (discard index)\n",[67,573,574,576,579,581,583,586],{"class":69,"line":263},[67,575,24],{"class":99},[67,577,578],{"class":107}," k, v ",[67,580,126],{"class":99},[67,582,549],{"class":99},[67,584,585],{"class":107}," m { }      ",[67,587,588],{"class":73},"\u002F\u002F map: key + value\n",[67,590,591,593,596,598,600,603],{"class":69,"line":268},[67,592,24],{"class":99},[67,594,595],{"class":107}," k ",[67,597,126],{"class":99},[67,599,549],{"class":99},[67,601,602],{"class":107}," m { }         ",[67,604,605],{"class":73},"\u002F\u002F map: key only\n",[67,607,608,610,613,615,617,621,624],{"class":69,"line":274},[67,609,24],{"class":99},[67,611,612],{"class":107}," i, r ",[67,614,126],{"class":99},[67,616,549],{"class":99},[67,618,620],{"class":619},"sJ6F3"," \"café\"",[67,622,623],{"class":107}," { } ",[67,625,626],{"class":73},"\u002F\u002F string: byte_offset + rune\n",[67,628,630,632,635,637,639,642],{"class":69,"line":629},25,[67,631,24],{"class":99},[67,633,634],{"class":107}," v ",[67,636,126],{"class":99},[67,638,549],{"class":99},[67,640,641],{"class":107}," ch { }        ",[67,643,644],{"class":73},"\u002F\u002F channel: value (until closed)\n",[67,646,648,650,652,654,656,658,661],{"class":69,"line":647},26,[67,649,24],{"class":99},[67,651,413],{"class":107},[67,653,126],{"class":99},[67,655,549],{"class":99},[67,657,426],{"class":138},[67,659,660],{"class":107}," { }        ",[67,662,663],{"class":73},"\u002F\u002F Go 1.22+: integer (0..9)\n",[279,665,667,670],{"id":666},"range-internals-how-it-works",[18,668,669],{},"range"," internals — how it works",[55,672,673,1099,1103],{"language":57},[59,674,676],{"className":61,"code":675,"language":57,"meta":63,"style":63},"\u002F\u002F ┌──────────────────────────────────────────────────────────────────┐\n\u002F\u002F │ range evaluates the expression ONCE at loop start, then          │\n\u002F\u002F │ iterates over a snapshot (for slices) or live data (for chans).  │\n\u002F\u002F │                                                                  │\n\u002F\u002F │ For slices: range captures len(s) at start. If you append to s   │\n\u002F\u002F │ during the loop, the new elements are NOT iterated.              │\n\u002F\u002F │                                                                  │\n\u002F\u002F │ For maps: iteration order is RANDOMIZED (intentionally, since    │\n\u002F\u002F │ Go 1.0) to prevent code from depending on order. Each run may    │\n\u002F\u002F │ produce different order.                                         │\n\u002F\u002F │                                                                  │\n\u002F\u002F │ For channels: range receives until the channel is closed.        │\n\u002F\u002F │                                                                  │\n\u002F\u002F │ For strings: range decodes UTF-8 lazily, yielding (byte_offset,  │\n\u002F\u002F │ rune) — the offset jumps by the rune's byte width.               │\n\u002F\u002F │                                                                  │\n\u002F\u002F │ For integers (Go 1.22+): `for i := range n` is sugar for         │\n\u002F\u002F │ `for i := 0; i \u003C n; i++`. n must be a non-negative integer.      │\n\u002F\u002F └──────────────────────────────────────────────────────────────────┘\n\nfunc rangeInternals() {\n    s := []int{1, 2, 3}\n    for i, v := range s {\n        s = append(s, v*10)  \u002F\u002F appends to s, but range uses the original len\n        fmt.Println(i, v)    \u002F\u002F prints 0 1, 1 2, 2 3 — new elements NOT iterated\n    }\n    fmt.Println(s)  \u002F\u002F [1 2 3 10 20 30]\n\n    \u002F\u002F Map iteration is randomized:\n    m := map[string]int{\"a\": 1, \"b\": 2, \"c\": 3}\n    for k, v := range m {\n        fmt.Println(k, v)  \u002F\u002F order varies each run\n    }\n\n    \u002F\u002F Ordered map iteration — sort keys first:\n    keys := make([]string, 0, len(m))\n    for k := range m {\n        keys = append(keys, k)\n    }\n    sort.Strings(keys)\n    for _, k := range keys {\n        fmt.Println(k, m[k])  \u002F\u002F deterministic order\n    }\n}\n",[18,677,678,683,688,693,698,703,708,712,717,722,727,731,736,740,745,750,754,759,764,769,773,782,813,827,853,866,870,883,888,894,946,960,973,978,983,989,1018,1031,1044,1049,1061,1076,1089,1094],{"__ignoreMap":63},[67,679,680],{"class":69,"line":70},[67,681,682],{"class":73},"\u002F\u002F ┌──────────────────────────────────────────────────────────────────┐\n",[67,684,685],{"class":69,"line":77},[67,686,687],{"class":73},"\u002F\u002F │ range evaluates the expression ONCE at loop start, then          │\n",[67,689,690],{"class":69,"line":83},[67,691,692],{"class":73},"\u002F\u002F │ iterates over a snapshot (for slices) or live data (for chans).  │\n",[67,694,695],{"class":69,"line":89},[67,696,697],{"class":73},"\u002F\u002F │                                                                  │\n",[67,699,700],{"class":69,"line":96},[67,701,702],{"class":73},"\u002F\u002F │ For slices: range captures len(s) at start. If you append to s   │\n",[67,704,705],{"class":69,"line":111},[67,706,707],{"class":73},"\u002F\u002F │ during the loop, the new elements are NOT iterated.              │\n",[67,709,710],{"class":69,"line":117},[67,711,697],{"class":73},[67,713,714],{"class":69,"line":145},[67,715,716],{"class":73},"\u002F\u002F │ For maps: iteration order is RANDOMIZED (intentionally, since    │\n",[67,718,719],{"class":69,"line":157},[67,720,721],{"class":73},"\u002F\u002F │ Go 1.0) to prevent code from depending on order. Each run may    │\n",[67,723,724],{"class":69,"line":163},[67,725,726],{"class":73},"\u002F\u002F │ produce different order.                                         │\n",[67,728,729],{"class":69,"line":169},[67,730,697],{"class":73},[67,732,733],{"class":69,"line":174},[67,734,735],{"class":73},"\u002F\u002F │ For channels: range receives until the channel is closed.        │\n",[67,737,738],{"class":69,"line":180},[67,739,697],{"class":73},[67,741,742],{"class":69,"line":186},[67,743,744],{"class":73},"\u002F\u002F │ For strings: range decodes UTF-8 lazily, yielding (byte_offset,  │\n",[67,746,747],{"class":69,"line":192},[67,748,749],{"class":73},"\u002F\u002F │ rune) — the offset jumps by the rune's byte width.               │\n",[67,751,752],{"class":69,"line":198},[67,753,697],{"class":73},[67,755,756],{"class":69,"line":203},[67,757,758],{"class":73},"\u002F\u002F │ For integers (Go 1.22+): `for i := range n` is sugar for         │\n",[67,760,761],{"class":69,"line":209},[67,762,763],{"class":73},"\u002F\u002F │ `for i := 0; i \u003C n; i++`. n must be a non-negative integer.      │\n",[67,765,766],{"class":69,"line":231},[67,767,768],{"class":73},"\u002F\u002F └──────────────────────────────────────────────────────────────────┘\n",[67,770,771],{"class":69,"line":240},[67,772,93],{"emptyLinePlaceholder":92},[67,774,775,777,780],{"class":69,"line":251},[67,776,100],{"class":99},[67,778,779],{"class":103}," rangeInternals",[67,781,108],{"class":107},[67,783,784,787,789,792,795,798,801,803,806,808,811],{"class":69,"line":263},[67,785,786],{"class":107},"    s ",[67,788,126],{"class":99},[67,790,791],{"class":107}," []",[67,793,794],{"class":99},"int",[67,796,797],{"class":107},"{",[67,799,800],{"class":138},"1",[67,802,21],{"class":107},[67,804,805],{"class":138},"2",[67,807,21],{"class":107},[67,809,810],{"class":138},"3",[67,812,277],{"class":107},[67,814,815,818,820,822,824],{"class":69,"line":268},[67,816,817],{"class":99},"    for",[67,819,544],{"class":107},[67,821,126],{"class":99},[67,823,549],{"class":99},[67,825,826],{"class":107}," s {\n",[67,828,829,832,835,838,841,844,847,850],{"class":69,"line":274},[67,830,831],{"class":107},"        s ",[67,833,834],{"class":99},"=",[67,836,837],{"class":103}," append",[67,839,840],{"class":107},"(s, v",[67,842,843],{"class":99},"*",[67,845,846],{"class":138},"10",[67,848,849],{"class":107},")  ",[67,851,852],{"class":73},"\u002F\u002F appends to s, but range uses the original len\n",[67,854,855,858,860,863],{"class":69,"line":629},[67,856,857],{"class":107},"        fmt.",[67,859,442],{"class":103},[67,861,862],{"class":107},"(i, v)    ",[67,864,865],{"class":73},"\u002F\u002F prints 0 1, 1 2, 2 3 — new elements NOT iterated\n",[67,867,868],{"class":69,"line":647},[67,869,160],{"class":107},[67,871,873,875,877,880],{"class":69,"line":872},27,[67,874,439],{"class":107},[67,876,442],{"class":103},[67,878,879],{"class":107},"(s)  ",[67,881,882],{"class":73},"\u002F\u002F [1 2 3 10 20 30]\n",[67,884,886],{"class":69,"line":885},28,[67,887,93],{"emptyLinePlaceholder":92},[67,889,891],{"class":69,"line":890},29,[67,892,893],{"class":73},"    \u002F\u002F Map iteration is randomized:\n",[67,895,897,900,902,905,908,911,914,916,918,921,924,926,928,931,933,935,937,940,942,944],{"class":69,"line":896},30,[67,898,899],{"class":107},"    m ",[67,901,126],{"class":99},[67,903,904],{"class":99}," map",[67,906,907],{"class":107},"[",[67,909,910],{"class":99},"string",[67,912,913],{"class":107},"]",[67,915,794],{"class":99},[67,917,797],{"class":107},[67,919,920],{"class":619},"\"a\"",[67,922,923],{"class":107},": ",[67,925,800],{"class":138},[67,927,21],{"class":107},[67,929,930],{"class":619},"\"b\"",[67,932,923],{"class":107},[67,934,805],{"class":138},[67,936,21],{"class":107},[67,938,939],{"class":619},"\"c\"",[67,941,923],{"class":107},[67,943,810],{"class":138},[67,945,277],{"class":107},[67,947,949,951,953,955,957],{"class":69,"line":948},31,[67,950,817],{"class":99},[67,952,578],{"class":107},[67,954,126],{"class":99},[67,956,549],{"class":99},[67,958,959],{"class":107}," m {\n",[67,961,963,965,967,970],{"class":69,"line":962},32,[67,964,857],{"class":107},[67,966,442],{"class":103},[67,968,969],{"class":107},"(k, v)  ",[67,971,972],{"class":73},"\u002F\u002F order varies each run\n",[67,974,976],{"class":69,"line":975},33,[67,977,160],{"class":107},[67,979,981],{"class":69,"line":980},34,[67,982,93],{"emptyLinePlaceholder":92},[67,984,986],{"class":69,"line":985},35,[67,987,988],{"class":73},"    \u002F\u002F Ordered map iteration — sort keys first:\n",[67,990,992,995,997,1000,1003,1005,1007,1010,1012,1015],{"class":69,"line":991},36,[67,993,994],{"class":107},"    keys ",[67,996,126],{"class":99},[67,998,999],{"class":103}," make",[67,1001,1002],{"class":107},"([]",[67,1004,910],{"class":99},[67,1006,21],{"class":107},[67,1008,1009],{"class":138},"0",[67,1011,21],{"class":107},[67,1013,1014],{"class":103},"len",[67,1016,1017],{"class":107},"(m))\n",[67,1019,1021,1023,1025,1027,1029],{"class":69,"line":1020},37,[67,1022,817],{"class":99},[67,1024,595],{"class":107},[67,1026,126],{"class":99},[67,1028,549],{"class":99},[67,1030,959],{"class":107},[67,1032,1034,1037,1039,1041],{"class":69,"line":1033},38,[67,1035,1036],{"class":107},"        keys ",[67,1038,834],{"class":99},[67,1040,837],{"class":103},[67,1042,1043],{"class":107},"(keys, k)\n",[67,1045,1047],{"class":69,"line":1046},39,[67,1048,160],{"class":107},[67,1050,1052,1055,1058],{"class":69,"line":1051},40,[67,1053,1054],{"class":107},"    sort.",[67,1056,1057],{"class":103},"Strings",[67,1059,1060],{"class":107},"(keys)\n",[67,1062,1064,1066,1069,1071,1073],{"class":69,"line":1063},41,[67,1065,817],{"class":99},[67,1067,1068],{"class":107}," _, k ",[67,1070,126],{"class":99},[67,1072,549],{"class":99},[67,1074,1075],{"class":107}," keys {\n",[67,1077,1079,1081,1083,1086],{"class":69,"line":1078},42,[67,1080,857],{"class":107},[67,1082,442],{"class":103},[67,1084,1085],{"class":107},"(k, m[k])  ",[67,1087,1088],{"class":73},"\u002F\u002F deterministic order\n",[67,1090,1092],{"class":69,"line":1091},43,[67,1093,160],{"class":107},[67,1095,1097],{"class":69,"line":1096},44,[67,1098,277],{"class":107},[279,1100,1102],{"id":1101},"go-122-loop-variable-scoping-the-fix","Go 1.22 loop variable scoping — the fix",[55,1104,1105,1378,1384],{"language":57},[59,1106,1108],{"className":61,"code":1107,"language":57,"meta":63,"style":63},"\u002F\u002F ┌──────────────────────────────────────────────────────────────────┐\n\u002F\u002F │ Go 1.22 spec change: each iteration of a for loop gets its OWN   │\n\u002F\u002F │ loop variable(s), rather than sharing a single variable.         │\n\u002F\u002F │                                                                  │\n\u002F\u002F │ Pre-1.22: `for i := 0; ... { go func() { use(i) }() }`           │\n\u002F\u002F │   → all goroutines see the FINAL i (single variable reused)     │\n\u002F\u002F │                                                                  │\n\u002F\u002F │ 1.22+: same code → each goroutine sees its iteration's i         │\n\u002F\u002F │   → each iteration creates a fresh i                            │\n\u002F\u002F │                                                                  │\n\u002F\u002F │ The go.mod `go 1.22` directive controls this behavior.           │\n\u002F\u002F │ A module with `go 1.21` still uses the old semantics even on     │\n\u002F\u002F │ a 1.22+ toolchain.                                               │\n\u002F\u002F └──────────────────────────────────────────────────────────────────┘\n\nfunc loopScoping() {\n    \u002F\u002F Pre-1.22: prints 3 3 3 (or similar — all see final i)\n    \u002F\u002F 1.22+: prints 0 1 2 (each iteration's i is distinct)\n    for i := 0; i \u003C 3; i++ {\n        go func() { fmt.Println(i) }()\n    }\n    time.Sleep(time.Second)\n\n    \u002F\u002F ✅ Portable fix (works on ALL versions):\n    for i := 0; i \u003C 3; i++ {\n        go func(i int) { fmt.Println(i) }(i)  \u002F\u002F pass as argument — fresh copy\n    }\n\n    \u002F\u002F ✅ Or shadow (pre-1.22 idiom, harmless on 1.22+):\n    for i := 0; i \u003C 3; i++ {\n        i := i  \u002F\u002F shadow — new i per iteration\n        go func() { fmt.Println(i) }()\n    }\n}\n",[18,1109,1110,1114,1119,1124,1128,1133,1138,1142,1147,1152,1156,1161,1166,1171,1175,1179,1188,1193,1198,1221,1237,1241,1252,1256,1261,1283,1310,1314,1318,1323,1345,1358,1370,1374],{"__ignoreMap":63},[67,1111,1112],{"class":69,"line":70},[67,1113,682],{"class":73},[67,1115,1116],{"class":69,"line":77},[67,1117,1118],{"class":73},"\u002F\u002F │ Go 1.22 spec change: each iteration of a for loop gets its OWN   │\n",[67,1120,1121],{"class":69,"line":83},[67,1122,1123],{"class":73},"\u002F\u002F │ loop variable(s), rather than sharing a single variable.         │\n",[67,1125,1126],{"class":69,"line":89},[67,1127,697],{"class":73},[67,1129,1130],{"class":69,"line":96},[67,1131,1132],{"class":73},"\u002F\u002F │ Pre-1.22: `for i := 0; ... { go func() { use(i) }() }`           │\n",[67,1134,1135],{"class":69,"line":111},[67,1136,1137],{"class":73},"\u002F\u002F │   → all goroutines see the FINAL i (single variable reused)     │\n",[67,1139,1140],{"class":69,"line":117},[67,1141,697],{"class":73},[67,1143,1144],{"class":69,"line":145},[67,1145,1146],{"class":73},"\u002F\u002F │ 1.22+: same code → each goroutine sees its iteration's i         │\n",[67,1148,1149],{"class":69,"line":157},[67,1150,1151],{"class":73},"\u002F\u002F │   → each iteration creates a fresh i                            │\n",[67,1153,1154],{"class":69,"line":163},[67,1155,697],{"class":73},[67,1157,1158],{"class":69,"line":169},[67,1159,1160],{"class":73},"\u002F\u002F │ The go.mod `go 1.22` directive controls this behavior.           │\n",[67,1162,1163],{"class":69,"line":174},[67,1164,1165],{"class":73},"\u002F\u002F │ A module with `go 1.21` still uses the old semantics even on     │\n",[67,1167,1168],{"class":69,"line":180},[67,1169,1170],{"class":73},"\u002F\u002F │ a 1.22+ toolchain.                                               │\n",[67,1172,1173],{"class":69,"line":186},[67,1174,768],{"class":73},[67,1176,1177],{"class":69,"line":192},[67,1178,93],{"emptyLinePlaceholder":92},[67,1180,1181,1183,1186],{"class":69,"line":198},[67,1182,100],{"class":99},[67,1184,1185],{"class":103}," loopScoping",[67,1187,108],{"class":107},[67,1189,1190],{"class":69,"line":203},[67,1191,1192],{"class":73},"    \u002F\u002F Pre-1.22: prints 3 3 3 (or similar — all see final i)\n",[67,1194,1195],{"class":69,"line":209},[67,1196,1197],{"class":73},"    \u002F\u002F 1.22+: prints 0 1 2 (each iteration's i is distinct)\n",[67,1199,1200,1202,1204,1206,1208,1210,1212,1215,1217,1219],{"class":69,"line":231},[67,1201,817],{"class":99},[67,1203,413],{"class":107},[67,1205,126],{"class":99},[67,1207,326],{"class":138},[67,1209,420],{"class":107},[67,1211,423],{"class":99},[67,1213,1214],{"class":138}," 3",[67,1216,429],{"class":107},[67,1218,432],{"class":99},[67,1220,142],{"class":107},[67,1222,1223,1226,1229,1232,1234],{"class":69,"line":240},[67,1224,1225],{"class":99},"        go",[67,1227,1228],{"class":99}," func",[67,1230,1231],{"class":107},"() { fmt.",[67,1233,442],{"class":103},[67,1235,1236],{"class":107},"(i) }()\n",[67,1238,1239],{"class":69,"line":251},[67,1240,160],{"class":107},[67,1242,1243,1246,1249],{"class":69,"line":263},[67,1244,1245],{"class":107},"    time.",[67,1247,1248],{"class":103},"Sleep",[67,1250,1251],{"class":107},"(time.Second)\n",[67,1253,1254],{"class":69,"line":268},[67,1255,93],{"emptyLinePlaceholder":92},[67,1257,1258],{"class":69,"line":274},[67,1259,1260],{"class":73},"    \u002F\u002F ✅ Portable fix (works on ALL versions):\n",[67,1262,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281],{"class":69,"line":629},[67,1264,817],{"class":99},[67,1266,413],{"class":107},[67,1268,126],{"class":99},[67,1270,326],{"class":138},[67,1272,420],{"class":107},[67,1274,423],{"class":99},[67,1276,1214],{"class":138},[67,1278,429],{"class":107},[67,1280,432],{"class":99},[67,1282,142],{"class":107},[67,1284,1285,1287,1289,1292,1296,1299,1302,1304,1307],{"class":69,"line":647},[67,1286,1225],{"class":99},[67,1288,1228],{"class":99},[67,1290,1291],{"class":107},"(",[67,1293,1295],{"class":1294},"sCrzJ","i",[67,1297,1298],{"class":99}," int",[67,1300,1301],{"class":107},") { fmt.",[67,1303,442],{"class":103},[67,1305,1306],{"class":107},"(i) }(i)  ",[67,1308,1309],{"class":73},"\u002F\u002F pass as argument — fresh copy\n",[67,1311,1312],{"class":69,"line":872},[67,1313,160],{"class":107},[67,1315,1316],{"class":69,"line":885},[67,1317,93],{"emptyLinePlaceholder":92},[67,1319,1320],{"class":69,"line":890},[67,1321,1322],{"class":73},"    \u002F\u002F ✅ Or shadow (pre-1.22 idiom, harmless on 1.22+):\n",[67,1324,1325,1327,1329,1331,1333,1335,1337,1339,1341,1343],{"class":69,"line":896},[67,1326,817],{"class":99},[67,1328,413],{"class":107},[67,1330,126],{"class":99},[67,1332,326],{"class":138},[67,1334,420],{"class":107},[67,1336,423],{"class":99},[67,1338,1214],{"class":138},[67,1340,429],{"class":107},[67,1342,432],{"class":99},[67,1344,142],{"class":107},[67,1346,1347,1350,1352,1355],{"class":69,"line":948},[67,1348,1349],{"class":107},"        i ",[67,1351,126],{"class":99},[67,1353,1354],{"class":107}," i  ",[67,1356,1357],{"class":73},"\u002F\u002F shadow — new i per iteration\n",[67,1359,1360,1362,1364,1366,1368],{"class":69,"line":962},[67,1361,1225],{"class":99},[67,1363,1228],{"class":99},[67,1365,1231],{"class":107},[67,1367,442],{"class":103},[67,1369,1236],{"class":107},[67,1371,1372],{"class":69,"line":975},[67,1373,160],{"class":107},[67,1375,1376],{"class":69,"line":980},[67,1377,277],{"class":107},[48,1379,1381,1383],{"id":1380},"switch-dispatch-mechanics",[18,1382,27],{}," — Dispatch Mechanics",[55,1385,1386,1854,1858],{"language":57},[59,1387,1389],{"className":61,"code":1388,"language":57,"meta":63,"style":63},"\u002F\u002F Go switch does NOT fall through by default (unlike C\u002FJava).\n\u002F\u002F Each case ends implicitly — no break needed.\n\u002F\u002F fallthrough is explicit and rare.\n\nfunc basicSwitch(x int) {\n    switch x {\n    case 1:\n        fmt.Println(\"one\")\n    case 2, 3:           \u002F\u002F multiple values in one case\n        fmt.Println(\"two or three\")\n    case 4:\n        fmt.Println(\"four\")\n        \u002F\u002F no break needed — case ends here\n    default:\n        fmt.Println(\"other\")\n    }\n}\n\n\u002F\u002F fallthrough — jumps to the next case's body UNCONDITIONALLY\n\u002F\u002F (does NOT evaluate the next case's condition — unlike C):\nfunc fallthroughDemo(x int) {\n    switch x {\n    case 1:\n        fmt.Println(\"one\")\n        fallthrough       \u002F\u002F executes case 2's body regardless of x\n    case 2:\n        fmt.Println(\"one or two\")\n    }\n}\n\n\u002F\u002F No-expression switch — like if\u002Felse chain, but cleaner:\nfunc noExprSwitch(x int) string {\n    switch {\n    case x \u003C 0:\n        return \"negative\"\n    case x == 0:\n        return \"zero\"\n    case x > 0:\n        return \"positive\"\n    default:\n        return \"impossible\"\n    }\n}\n\n\u002F\u002F Init + no-expression switch:\nfunc initSwitch() {\n    switch n := computeValue(); {\n    case n \u003C 0:\n        handleNegative(n)\n    case n == 0:\n        handleZero()\n    default:\n        handlePositive(n)\n    }\n}\n",[18,1390,1391,1396,1401,1406,1410,1427,1435,1446,1460,1477,1490,1499,1512,1517,1524,1537,1541,1545,1549,1554,1559,1574,1580,1588,1600,1608,1616,1629,1633,1637,1641,1646,1666,1672,1684,1691,1704,1711,1723,1730,1736,1743,1747,1751,1755,1761,1771,1786,1799,1808,1821,1829,1836,1844,1849],{"__ignoreMap":63},[67,1392,1393],{"class":69,"line":70},[67,1394,1395],{"class":73},"\u002F\u002F Go switch does NOT fall through by default (unlike C\u002FJava).\n",[67,1397,1398],{"class":69,"line":77},[67,1399,1400],{"class":73},"\u002F\u002F Each case ends implicitly — no break needed.\n",[67,1402,1403],{"class":69,"line":83},[67,1404,1405],{"class":73},"\u002F\u002F fallthrough is explicit and rare.\n",[67,1407,1408],{"class":69,"line":89},[67,1409,93],{"emptyLinePlaceholder":92},[67,1411,1412,1414,1417,1419,1422,1424],{"class":69,"line":96},[67,1413,100],{"class":99},[67,1415,1416],{"class":103}," basicSwitch",[67,1418,1291],{"class":107},[67,1420,1421],{"class":1294},"x",[67,1423,1298],{"class":99},[67,1425,1426],{"class":107},") {\n",[67,1428,1429,1432],{"class":69,"line":111},[67,1430,1431],{"class":99},"    switch",[67,1433,1434],{"class":107}," x {\n",[67,1436,1437,1440,1443],{"class":69,"line":117},[67,1438,1439],{"class":99},"    case",[67,1441,1442],{"class":138}," 1",[67,1444,1445],{"class":107},":\n",[67,1447,1448,1450,1452,1454,1457],{"class":69,"line":145},[67,1449,857],{"class":107},[67,1451,442],{"class":103},[67,1453,1291],{"class":107},[67,1455,1456],{"class":619},"\"one\"",[67,1458,1459],{"class":107},")\n",[67,1461,1462,1464,1467,1469,1471,1474],{"class":69,"line":157},[67,1463,1439],{"class":99},[67,1465,1466],{"class":138}," 2",[67,1468,21],{"class":107},[67,1470,810],{"class":138},[67,1472,1473],{"class":107},":           ",[67,1475,1476],{"class":73},"\u002F\u002F multiple values in one case\n",[67,1478,1479,1481,1483,1485,1488],{"class":69,"line":163},[67,1480,857],{"class":107},[67,1482,442],{"class":103},[67,1484,1291],{"class":107},[67,1486,1487],{"class":619},"\"two or three\"",[67,1489,1459],{"class":107},[67,1491,1492,1494,1497],{"class":69,"line":169},[67,1493,1439],{"class":99},[67,1495,1496],{"class":138}," 4",[67,1498,1445],{"class":107},[67,1500,1501,1503,1505,1507,1510],{"class":69,"line":174},[67,1502,857],{"class":107},[67,1504,442],{"class":103},[67,1506,1291],{"class":107},[67,1508,1509],{"class":619},"\"four\"",[67,1511,1459],{"class":107},[67,1513,1514],{"class":69,"line":180},[67,1515,1516],{"class":73},"        \u002F\u002F no break needed — case ends here\n",[67,1518,1519,1522],{"class":69,"line":186},[67,1520,1521],{"class":99},"    default",[67,1523,1445],{"class":107},[67,1525,1526,1528,1530,1532,1535],{"class":69,"line":192},[67,1527,857],{"class":107},[67,1529,442],{"class":103},[67,1531,1291],{"class":107},[67,1533,1534],{"class":619},"\"other\"",[67,1536,1459],{"class":107},[67,1538,1539],{"class":69,"line":198},[67,1540,160],{"class":107},[67,1542,1543],{"class":69,"line":203},[67,1544,277],{"class":107},[67,1546,1547],{"class":69,"line":209},[67,1548,93],{"emptyLinePlaceholder":92},[67,1550,1551],{"class":69,"line":231},[67,1552,1553],{"class":73},"\u002F\u002F fallthrough — jumps to the next case's body UNCONDITIONALLY\n",[67,1555,1556],{"class":69,"line":240},[67,1557,1558],{"class":73},"\u002F\u002F (does NOT evaluate the next case's condition — unlike C):\n",[67,1560,1561,1563,1566,1568,1570,1572],{"class":69,"line":251},[67,1562,100],{"class":99},[67,1564,1565],{"class":103}," fallthroughDemo",[67,1567,1291],{"class":107},[67,1569,1421],{"class":1294},[67,1571,1298],{"class":99},[67,1573,1426],{"class":107},[67,1575,1576,1578],{"class":69,"line":263},[67,1577,1431],{"class":99},[67,1579,1434],{"class":107},[67,1581,1582,1584,1586],{"class":69,"line":268},[67,1583,1439],{"class":99},[67,1585,1442],{"class":138},[67,1587,1445],{"class":107},[67,1589,1590,1592,1594,1596,1598],{"class":69,"line":274},[67,1591,857],{"class":107},[67,1593,442],{"class":103},[67,1595,1291],{"class":107},[67,1597,1456],{"class":619},[67,1599,1459],{"class":107},[67,1601,1602,1605],{"class":69,"line":629},[67,1603,1604],{"class":99},"        fallthrough",[67,1606,1607],{"class":73},"       \u002F\u002F executes case 2's body regardless of x\n",[67,1609,1610,1612,1614],{"class":69,"line":647},[67,1611,1439],{"class":99},[67,1613,1466],{"class":138},[67,1615,1445],{"class":107},[67,1617,1618,1620,1622,1624,1627],{"class":69,"line":872},[67,1619,857],{"class":107},[67,1621,442],{"class":103},[67,1623,1291],{"class":107},[67,1625,1626],{"class":619},"\"one or two\"",[67,1628,1459],{"class":107},[67,1630,1631],{"class":69,"line":885},[67,1632,160],{"class":107},[67,1634,1635],{"class":69,"line":890},[67,1636,277],{"class":107},[67,1638,1639],{"class":69,"line":896},[67,1640,93],{"emptyLinePlaceholder":92},[67,1642,1643],{"class":69,"line":948},[67,1644,1645],{"class":73},"\u002F\u002F No-expression switch — like if\u002Felse chain, but cleaner:\n",[67,1647,1648,1650,1653,1655,1657,1659,1662,1664],{"class":69,"line":962},[67,1649,100],{"class":99},[67,1651,1652],{"class":103}," noExprSwitch",[67,1654,1291],{"class":107},[67,1656,1421],{"class":1294},[67,1658,1298],{"class":99},[67,1660,1661],{"class":107},") ",[67,1663,910],{"class":99},[67,1665,142],{"class":107},[67,1667,1668,1670],{"class":69,"line":975},[67,1669,1431],{"class":99},[67,1671,142],{"class":107},[67,1673,1674,1676,1678,1680,1682],{"class":69,"line":980},[67,1675,1439],{"class":99},[67,1677,320],{"class":107},[67,1679,423],{"class":99},[67,1681,326],{"class":138},[67,1683,1445],{"class":107},[67,1685,1686,1688],{"class":69,"line":985},[67,1687,234],{"class":99},[67,1689,1690],{"class":619}," \"negative\"\n",[67,1692,1693,1695,1697,1700,1702],{"class":69,"line":991},[67,1694,1439],{"class":99},[67,1696,320],{"class":107},[67,1698,1699],{"class":99},"==",[67,1701,326],{"class":138},[67,1703,1445],{"class":107},[67,1705,1706,1708],{"class":69,"line":1020},[67,1707,234],{"class":99},[67,1709,1710],{"class":619}," \"zero\"\n",[67,1712,1713,1715,1717,1719,1721],{"class":69,"line":1033},[67,1714,1439],{"class":99},[67,1716,320],{"class":107},[67,1718,323],{"class":99},[67,1720,326],{"class":138},[67,1722,1445],{"class":107},[67,1724,1725,1727],{"class":69,"line":1046},[67,1726,234],{"class":99},[67,1728,1729],{"class":619}," \"positive\"\n",[67,1731,1732,1734],{"class":69,"line":1051},[67,1733,1521],{"class":99},[67,1735,1445],{"class":107},[67,1737,1738,1740],{"class":69,"line":1063},[67,1739,234],{"class":99},[67,1741,1742],{"class":619}," \"impossible\"\n",[67,1744,1745],{"class":69,"line":1078},[67,1746,160],{"class":107},[67,1748,1749],{"class":69,"line":1091},[67,1750,277],{"class":107},[67,1752,1753],{"class":69,"line":1096},[67,1754,93],{"emptyLinePlaceholder":92},[67,1756,1758],{"class":69,"line":1757},45,[67,1759,1760],{"class":73},"\u002F\u002F Init + no-expression switch:\n",[67,1762,1764,1766,1769],{"class":69,"line":1763},46,[67,1765,100],{"class":99},[67,1767,1768],{"class":103}," initSwitch",[67,1770,108],{"class":107},[67,1772,1774,1776,1778,1780,1783],{"class":69,"line":1773},47,[67,1775,1431],{"class":99},[67,1777,475],{"class":107},[67,1779,126],{"class":99},[67,1781,1782],{"class":103}," computeValue",[67,1784,1785],{"class":107},"(); {\n",[67,1787,1789,1791,1793,1795,1797],{"class":69,"line":1788},48,[67,1790,1439],{"class":99},[67,1792,475],{"class":107},[67,1794,423],{"class":99},[67,1796,326],{"class":138},[67,1798,1445],{"class":107},[67,1800,1802,1805],{"class":69,"line":1801},49,[67,1803,1804],{"class":103},"        handleNegative",[67,1806,1807],{"class":107},"(n)\n",[67,1809,1811,1813,1815,1817,1819],{"class":69,"line":1810},50,[67,1812,1439],{"class":99},[67,1814,475],{"class":107},[67,1816,1699],{"class":99},[67,1818,326],{"class":138},[67,1820,1445],{"class":107},[67,1822,1824,1827],{"class":69,"line":1823},51,[67,1825,1826],{"class":103},"        handleZero",[67,1828,336],{"class":107},[67,1830,1832,1834],{"class":69,"line":1831},52,[67,1833,1521],{"class":99},[67,1835,1445],{"class":107},[67,1837,1839,1842],{"class":69,"line":1838},53,[67,1840,1841],{"class":103},"        handlePositive",[67,1843,1807],{"class":107},[67,1845,1847],{"class":69,"line":1846},54,[67,1848,160],{"class":107},[67,1850,1852],{"class":69,"line":1851},55,[67,1853,277],{"class":107},[279,1855,1857],{"id":1856},"type-switch-the-interface-dispatch-pattern","Type switch — the interface dispatch pattern",[55,1859,1860,2205,2217],{"language":57},[59,1861,1863],{"className":61,"code":1862,"language":57,"meta":63,"style":63},"func typeSwitch(v any) string {\n    switch x := v.(type) {\n    case nil:\n        return \"nil\"\n    case int:\n        return fmt.Sprintf(\"int: %d\", x)     \u002F\u002F x is int here\n    case string:\n        return fmt.Sprintf(\"string: %q\", x)  \u002F\u002F x is string here\n    case []byte:\n        return fmt.Sprintf(\"bytes: %d\", len(x))\n    case error:\n        return x.Error()                      \u002F\u002F x is error here\n    default:\n        return fmt.Sprintf(\"unknown: %T\", x)\n    }\n}\n\n\u002F\u002F Multiple types in one case:\nfunc multiTypeSwitch(v any) {\n    switch v.(type) {\n    case int, int8, int16, int32, int64:\n        fmt.Println(\"integer type\")\n    case uint, uint8, uint16, uint32, uint64:\n        fmt.Println(\"unsigned integer type\")\n    }\n}\n",[18,1864,1865,1886,1902,1910,1917,1925,1952,1961,1985,1996,2020,2029,2045,2051,2072,2076,2080,2084,2089,2104,2114,2142,2155,2184,2197,2201],{"__ignoreMap":63},[67,1866,1867,1869,1872,1874,1877,1880,1882,1884],{"class":69,"line":70},[67,1868,100],{"class":99},[67,1870,1871],{"class":103}," typeSwitch",[67,1873,1291],{"class":107},[67,1875,1876],{"class":1294},"v",[67,1878,1879],{"class":103}," any",[67,1881,1661],{"class":107},[67,1883,910],{"class":99},[67,1885,142],{"class":107},[67,1887,1888,1890,1892,1894,1897,1900],{"class":69,"line":77},[67,1889,1431],{"class":99},[67,1891,320],{"class":107},[67,1893,126],{"class":99},[67,1895,1896],{"class":107}," v.(",[67,1898,1899],{"class":99},"type",[67,1901,1426],{"class":107},[67,1903,1904,1906,1908],{"class":69,"line":83},[67,1905,1439],{"class":99},[67,1907,139],{"class":138},[67,1909,1445],{"class":107},[67,1911,1912,1914],{"class":69,"line":89},[67,1913,234],{"class":99},[67,1915,1916],{"class":619}," \"nil\"\n",[67,1918,1919,1921,1923],{"class":69,"line":96},[67,1920,1439],{"class":99},[67,1922,1298],{"class":99},[67,1924,1445],{"class":107},[67,1926,1927,1929,1932,1935,1937,1940,1943,1946,1949],{"class":69,"line":111},[67,1928,234],{"class":99},[67,1930,1931],{"class":107}," fmt.",[67,1933,1934],{"class":103},"Sprintf",[67,1936,1291],{"class":107},[67,1938,1939],{"class":619},"\"int: ",[67,1941,1942],{"class":138},"%d",[67,1944,1945],{"class":619},"\"",[67,1947,1948],{"class":107},", x)     ",[67,1950,1951],{"class":73},"\u002F\u002F x is int here\n",[67,1953,1954,1956,1959],{"class":69,"line":117},[67,1955,1439],{"class":99},[67,1957,1958],{"class":99}," string",[67,1960,1445],{"class":107},[67,1962,1963,1965,1967,1969,1971,1974,1977,1979,1982],{"class":69,"line":145},[67,1964,234],{"class":99},[67,1966,1931],{"class":107},[67,1968,1934],{"class":103},[67,1970,1291],{"class":107},[67,1972,1973],{"class":619},"\"string: ",[67,1975,1976],{"class":138},"%q",[67,1978,1945],{"class":619},[67,1980,1981],{"class":107},", x)  ",[67,1983,1984],{"class":73},"\u002F\u002F x is string here\n",[67,1986,1987,1989,1991,1994],{"class":69,"line":157},[67,1988,1439],{"class":99},[67,1990,791],{"class":107},[67,1992,1993],{"class":99},"byte",[67,1995,1445],{"class":107},[67,1997,1998,2000,2002,2004,2006,2009,2011,2013,2015,2017],{"class":69,"line":163},[67,1999,234],{"class":99},[67,2001,1931],{"class":107},[67,2003,1934],{"class":103},[67,2005,1291],{"class":107},[67,2007,2008],{"class":619},"\"bytes: ",[67,2010,1942],{"class":138},[67,2012,1945],{"class":619},[67,2014,21],{"class":107},[67,2016,1014],{"class":103},[67,2018,2019],{"class":107},"(x))\n",[67,2021,2022,2024,2027],{"class":69,"line":169},[67,2023,1439],{"class":99},[67,2025,2026],{"class":99}," error",[67,2028,1445],{"class":107},[67,2030,2031,2033,2036,2039,2042],{"class":69,"line":174},[67,2032,234],{"class":99},[67,2034,2035],{"class":107}," x.",[67,2037,2038],{"class":103},"Error",[67,2040,2041],{"class":107},"()                      ",[67,2043,2044],{"class":73},"\u002F\u002F x is error here\n",[67,2046,2047,2049],{"class":69,"line":180},[67,2048,1521],{"class":99},[67,2050,1445],{"class":107},[67,2052,2053,2055,2057,2059,2061,2064,2067,2069],{"class":69,"line":186},[67,2054,234],{"class":99},[67,2056,1931],{"class":107},[67,2058,1934],{"class":103},[67,2060,1291],{"class":107},[67,2062,2063],{"class":619},"\"unknown: ",[67,2065,2066],{"class":138},"%T",[67,2068,1945],{"class":619},[67,2070,2071],{"class":107},", x)\n",[67,2073,2074],{"class":69,"line":192},[67,2075,160],{"class":107},[67,2077,2078],{"class":69,"line":198},[67,2079,277],{"class":107},[67,2081,2082],{"class":69,"line":203},[67,2083,93],{"emptyLinePlaceholder":92},[67,2085,2086],{"class":69,"line":209},[67,2087,2088],{"class":73},"\u002F\u002F Multiple types in one case:\n",[67,2090,2091,2093,2096,2098,2100,2102],{"class":69,"line":231},[67,2092,100],{"class":99},[67,2094,2095],{"class":103}," multiTypeSwitch",[67,2097,1291],{"class":107},[67,2099,1876],{"class":1294},[67,2101,1879],{"class":103},[67,2103,1426],{"class":107},[67,2105,2106,2108,2110,2112],{"class":69,"line":240},[67,2107,1431],{"class":99},[67,2109,1896],{"class":107},[67,2111,1899],{"class":99},[67,2113,1426],{"class":107},[67,2115,2116,2118,2120,2122,2125,2127,2130,2132,2135,2137,2140],{"class":69,"line":251},[67,2117,1439],{"class":99},[67,2119,1298],{"class":99},[67,2121,21],{"class":107},[67,2123,2124],{"class":99},"int8",[67,2126,21],{"class":107},[67,2128,2129],{"class":99},"int16",[67,2131,21],{"class":107},[67,2133,2134],{"class":99},"int32",[67,2136,21],{"class":107},[67,2138,2139],{"class":99},"int64",[67,2141,1445],{"class":107},[67,2143,2144,2146,2148,2150,2153],{"class":69,"line":263},[67,2145,857],{"class":107},[67,2147,442],{"class":103},[67,2149,1291],{"class":107},[67,2151,2152],{"class":619},"\"integer type\"",[67,2154,1459],{"class":107},[67,2156,2157,2159,2162,2164,2167,2169,2172,2174,2177,2179,2182],{"class":69,"line":268},[67,2158,1439],{"class":99},[67,2160,2161],{"class":99}," uint",[67,2163,21],{"class":107},[67,2165,2166],{"class":99},"uint8",[67,2168,21],{"class":107},[67,2170,2171],{"class":99},"uint16",[67,2173,21],{"class":107},[67,2175,2176],{"class":99},"uint32",[67,2178,21],{"class":107},[67,2180,2181],{"class":99},"uint64",[67,2183,1445],{"class":107},[67,2185,2186,2188,2190,2192,2195],{"class":69,"line":274},[67,2187,857],{"class":107},[67,2189,442],{"class":103},[67,2191,1291],{"class":107},[67,2193,2194],{"class":619},"\"unsigned integer type\"",[67,2196,1459],{"class":107},[67,2198,2199],{"class":69,"line":629},[67,2200,160],{"class":107},[67,2202,2203],{"class":69,"line":647},[67,2204,277],{"class":107},[48,2206,2208,2209,2212,2213,2216],{"id":2207},"labeled-breakcontinue-nested-loop-control","Labeled ",[18,2210,2211],{},"break","\u002F",[18,2214,2215],{},"continue"," — Nested Loop Control",[55,2218,2219,2519,2525],{"language":57},[59,2220,2222],{"className":61,"code":2221,"language":57,"meta":63,"style":63},"\u002F\u002F Labels allow break\u002Fcontinue to target an OUTER loop from an inner one.\n\u002F\u002F Without labels, break\u002Fcontinue only affect the innermost loop.\n\nfunc searchMatrix(matrix [][]int, target int) bool {\nouter:\n    for i, row := range matrix {\n        for j, val := range row {\n            if val == target {\n                fmt.Printf(\"found at [%d][%d]\\n\", i, j)\n                break outer  \u002F\u002F exits BOTH loops\n            }\n            if val > target {\n                continue outer  \u002F\u002F skip to next row (not next column)\n            }\n        }\n    }\n    return true\n}\n\n\u002F\u002F Labels are also used with select (to break out of a for-select loop):\nfunc forSelectLoop(ch \u003C-chan int, done \u003C-chan struct{}) {\nloop:\n    for {\n        select {\n        case v := \u003C-ch:\n            process(v)\n        case \u003C-done:\n            break loop  \u002F\u002F exit the for loop (not just the select)\n        }\n    }\n}\n",[18,2223,2224,2229,2234,2238,2269,2274,2288,2303,2316,2346,2357,2362,2372,2382,2386,2391,2395,2403,2407,2411,2416,2446,2451,2457,2464,2479,2487,2496,2507,2511,2515],{"__ignoreMap":63},[67,2225,2226],{"class":69,"line":70},[67,2227,2228],{"class":73},"\u002F\u002F Labels allow break\u002Fcontinue to target an OUTER loop from an inner one.\n",[67,2230,2231],{"class":69,"line":77},[67,2232,2233],{"class":73},"\u002F\u002F Without labels, break\u002Fcontinue only affect the innermost loop.\n",[67,2235,2236],{"class":69,"line":83},[67,2237,93],{"emptyLinePlaceholder":92},[67,2239,2240,2242,2245,2247,2250,2253,2255,2257,2260,2262,2264,2267],{"class":69,"line":89},[67,2241,100],{"class":99},[67,2243,2244],{"class":103}," searchMatrix",[67,2246,1291],{"class":107},[67,2248,2249],{"class":1294},"matrix",[67,2251,2252],{"class":107}," [][]",[67,2254,794],{"class":99},[67,2256,21],{"class":107},[67,2258,2259],{"class":1294},"target",[67,2261,1298],{"class":99},[67,2263,1661],{"class":107},[67,2265,2266],{"class":99},"bool",[67,2268,142],{"class":107},[67,2270,2271],{"class":69,"line":96},[67,2272,2273],{"class":107},"outer:\n",[67,2275,2276,2278,2281,2283,2285],{"class":69,"line":111},[67,2277,817],{"class":99},[67,2279,2280],{"class":107}," i, row ",[67,2282,126],{"class":99},[67,2284,549],{"class":99},[67,2286,2287],{"class":107}," matrix {\n",[67,2289,2290,2293,2296,2298,2300],{"class":69,"line":117},[67,2291,2292],{"class":99},"        for",[67,2294,2295],{"class":107}," j, val ",[67,2297,126],{"class":99},[67,2299,549],{"class":99},[67,2301,2302],{"class":107}," row {\n",[67,2304,2305,2308,2311,2313],{"class":69,"line":145},[67,2306,2307],{"class":99},"            if",[67,2309,2310],{"class":107}," val ",[67,2312,1699],{"class":99},[67,2314,2315],{"class":107}," target {\n",[67,2317,2318,2321,2324,2326,2329,2331,2334,2336,2338,2341,2343],{"class":69,"line":157},[67,2319,2320],{"class":107},"                fmt.",[67,2322,2323],{"class":103},"Printf",[67,2325,1291],{"class":107},[67,2327,2328],{"class":619},"\"found at [",[67,2330,1942],{"class":138},[67,2332,2333],{"class":619},"][",[67,2335,1942],{"class":138},[67,2337,913],{"class":619},[67,2339,2340],{"class":138},"\\n",[67,2342,1945],{"class":619},[67,2344,2345],{"class":107},", i, j)\n",[67,2347,2348,2351,2354],{"class":69,"line":163},[67,2349,2350],{"class":99},"                break",[67,2352,2353],{"class":107}," outer  ",[67,2355,2356],{"class":73},"\u002F\u002F exits BOTH loops\n",[67,2358,2359],{"class":69,"line":169},[67,2360,2361],{"class":107},"            }\n",[67,2363,2364,2366,2368,2370],{"class":69,"line":174},[67,2365,2307],{"class":99},[67,2367,2310],{"class":107},[67,2369,323],{"class":99},[67,2371,2315],{"class":107},[67,2373,2374,2377,2379],{"class":69,"line":180},[67,2375,2376],{"class":99},"                continue",[67,2378,2353],{"class":107},[67,2380,2381],{"class":73},"\u002F\u002F skip to next row (not next column)\n",[67,2383,2384],{"class":69,"line":186},[67,2385,2361],{"class":107},[67,2387,2388],{"class":69,"line":192},[67,2389,2390],{"class":107},"        }\n",[67,2392,2393],{"class":69,"line":198},[67,2394,160],{"class":107},[67,2396,2397,2400],{"class":69,"line":203},[67,2398,2399],{"class":99},"    return",[67,2401,2402],{"class":138}," true\n",[67,2404,2405],{"class":69,"line":209},[67,2406,277],{"class":107},[67,2408,2409],{"class":69,"line":231},[67,2410,93],{"emptyLinePlaceholder":92},[67,2412,2413],{"class":69,"line":240},[67,2414,2415],{"class":73},"\u002F\u002F Labels are also used with select (to break out of a for-select loop):\n",[67,2417,2418,2420,2423,2425,2428,2431,2433,2435,2438,2440,2443],{"class":69,"line":251},[67,2419,100],{"class":99},[67,2421,2422],{"class":103}," forSelectLoop",[67,2424,1291],{"class":107},[67,2426,2427],{"class":1294},"ch",[67,2429,2430],{"class":99}," \u003C-chan",[67,2432,1298],{"class":99},[67,2434,21],{"class":107},[67,2436,2437],{"class":1294},"done",[67,2439,2430],{"class":99},[67,2441,2442],{"class":99}," struct",[67,2444,2445],{"class":107},"{}) {\n",[67,2447,2448],{"class":69,"line":263},[67,2449,2450],{"class":107},"loop:\n",[67,2452,2453,2455],{"class":69,"line":268},[67,2454,817],{"class":99},[67,2456,142],{"class":107},[67,2458,2459,2462],{"class":69,"line":274},[67,2460,2461],{"class":99},"        select",[67,2463,142],{"class":107},[67,2465,2466,2469,2471,2473,2476],{"class":69,"line":629},[67,2467,2468],{"class":99},"        case",[67,2470,634],{"class":107},[67,2472,126],{"class":99},[67,2474,2475],{"class":99}," \u003C-",[67,2477,2478],{"class":107},"ch:\n",[67,2480,2481,2484],{"class":69,"line":647},[67,2482,2483],{"class":103},"            process",[67,2485,2486],{"class":107},"(v)\n",[67,2488,2489,2491,2493],{"class":69,"line":872},[67,2490,2468],{"class":99},[67,2492,2475],{"class":99},[67,2494,2495],{"class":107},"done:\n",[67,2497,2498,2501,2504],{"class":69,"line":885},[67,2499,2500],{"class":99},"            break",[67,2502,2503],{"class":107}," loop  ",[67,2505,2506],{"class":73},"\u002F\u002F exit the for loop (not just the select)\n",[67,2508,2509],{"class":69,"line":890},[67,2510,2390],{"class":107},[67,2512,2513],{"class":69,"line":896},[67,2514,160],{"class":107},[67,2516,2517],{"class":69,"line":948},[67,2518,277],{"class":107},[48,2520,2522,2524],{"id":2521},"goto-the-one-legitimate-use",[18,2523,34],{}," — The One Legitimate Use",[55,2526,2527,2800,2806],{"language":57},[59,2528,2530],{"className":61,"code":2529,"language":57,"meta":63,"style":63},"\u002F\u002F goto is almost never used in idiomatic Go. The one legitimate pattern\n\u002F\u002F is centralized error cleanup in C-style code (generated code, parsers):\n\nfunc parseFile(path string) error {\n    f, err := os.Open(path)\n    if err != nil {\n        goto errOpen  \u002F\u002F skip other cleanups — nothing was opened yet\n    }\n    defer f.Close()\n\n    buf, err := allocateBuffer()\n    if err != nil {\n        goto errBuf\n    }\n    defer buf.Free()\n\n    \u002F\u002F ... happy path ...\n\n    return nil\n\nerrBuf:\n    \u002F\u002F buf failed to allocate — only f needs cleanup\n    \u002F\u002F (defer f.Close() already registered, runs on return)\n    return fmt.Errorf(\"parse: %w\", err)\n\nerrOpen:\n    \u002F\u002F f was never opened — no cleanup needed\n    return fmt.Errorf(\"parse: %w\", err)\n}\n\n\u002F\u002F ⚠️ goto restrictions:\n\u002F\u002F   - Can't jump over variable declarations (compile error)\n\u002F\u002F   - Can't jump into a block from outside\n\u002F\u002F   - Can't jump out of a function\n\u002F\u002F These restrictions prevent spaghetti code — goto is deliberately limited.\n",[18,2531,2532,2537,2542,2546,2567,2583,2595,2606,2610,2623,2627,2639,2651,2658,2662,2674,2678,2683,2687,2694,2698,2703,2708,2713,2735,2739,2744,2749,2767,2771,2775,2780,2785,2790,2795],{"__ignoreMap":63},[67,2533,2534],{"class":69,"line":70},[67,2535,2536],{"class":73},"\u002F\u002F goto is almost never used in idiomatic Go. The one legitimate pattern\n",[67,2538,2539],{"class":69,"line":77},[67,2540,2541],{"class":73},"\u002F\u002F is centralized error cleanup in C-style code (generated code, parsers):\n",[67,2543,2544],{"class":69,"line":83},[67,2545,93],{"emptyLinePlaceholder":92},[67,2547,2548,2550,2553,2555,2558,2560,2562,2565],{"class":69,"line":89},[67,2549,100],{"class":99},[67,2551,2552],{"class":103}," parseFile",[67,2554,1291],{"class":107},[67,2556,2557],{"class":1294},"path",[67,2559,1958],{"class":99},[67,2561,1661],{"class":107},[67,2563,2564],{"class":99},"error",[67,2566,142],{"class":107},[67,2568,2569,2572,2574,2577,2580],{"class":69,"line":96},[67,2570,2571],{"class":107},"    f, err ",[67,2573,126],{"class":99},[67,2575,2576],{"class":107}," os.",[67,2578,2579],{"class":103},"Open",[67,2581,2582],{"class":107},"(path)\n",[67,2584,2585,2587,2589,2591,2593],{"class":69,"line":111},[67,2586,120],{"class":99},[67,2588,123],{"class":107},[67,2590,135],{"class":99},[67,2592,139],{"class":138},[67,2594,142],{"class":107},[67,2596,2597,2600,2603],{"class":69,"line":117},[67,2598,2599],{"class":99},"        goto",[67,2601,2602],{"class":107}," errOpen  ",[67,2604,2605],{"class":73},"\u002F\u002F skip other cleanups — nothing was opened yet\n",[67,2607,2608],{"class":69,"line":145},[67,2609,160],{"class":107},[67,2611,2612,2615,2618,2621],{"class":69,"line":157},[67,2613,2614],{"class":99},"    defer",[67,2616,2617],{"class":107}," f.",[67,2619,2620],{"class":103},"Close",[67,2622,336],{"class":107},[67,2624,2625],{"class":69,"line":163},[67,2626,93],{"emptyLinePlaceholder":92},[67,2628,2629,2632,2634,2637],{"class":69,"line":169},[67,2630,2631],{"class":107},"    buf, err ",[67,2633,126],{"class":99},[67,2635,2636],{"class":103}," allocateBuffer",[67,2638,336],{"class":107},[67,2640,2641,2643,2645,2647,2649],{"class":69,"line":174},[67,2642,120],{"class":99},[67,2644,123],{"class":107},[67,2646,135],{"class":99},[67,2648,139],{"class":138},[67,2650,142],{"class":107},[67,2652,2653,2655],{"class":69,"line":180},[67,2654,2599],{"class":99},[67,2656,2657],{"class":107}," errBuf\n",[67,2659,2660],{"class":69,"line":186},[67,2661,160],{"class":107},[67,2663,2664,2666,2669,2672],{"class":69,"line":192},[67,2665,2614],{"class":99},[67,2667,2668],{"class":107}," buf.",[67,2670,2671],{"class":103},"Free",[67,2673,336],{"class":107},[67,2675,2676],{"class":69,"line":198},[67,2677,93],{"emptyLinePlaceholder":92},[67,2679,2680],{"class":69,"line":203},[67,2681,2682],{"class":73},"    \u002F\u002F ... happy path ...\n",[67,2684,2685],{"class":69,"line":209},[67,2686,93],{"emptyLinePlaceholder":92},[67,2688,2689,2691],{"class":69,"line":231},[67,2690,2399],{"class":99},[67,2692,2693],{"class":138}," nil\n",[67,2695,2696],{"class":69,"line":240},[67,2697,93],{"emptyLinePlaceholder":92},[67,2699,2700],{"class":69,"line":251},[67,2701,2702],{"class":107},"errBuf:\n",[67,2704,2705],{"class":69,"line":263},[67,2706,2707],{"class":73},"    \u002F\u002F buf failed to allocate — only f needs cleanup\n",[67,2709,2710],{"class":69,"line":268},[67,2711,2712],{"class":73},"    \u002F\u002F (defer f.Close() already registered, runs on return)\n",[67,2714,2715,2717,2719,2722,2724,2727,2730,2732],{"class":69,"line":274},[67,2716,2399],{"class":99},[67,2718,1931],{"class":107},[67,2720,2721],{"class":103},"Errorf",[67,2723,1291],{"class":107},[67,2725,2726],{"class":619},"\"parse: ",[67,2728,2729],{"class":138},"%w",[67,2731,1945],{"class":619},[67,2733,2734],{"class":107},", err)\n",[67,2736,2737],{"class":69,"line":629},[67,2738,93],{"emptyLinePlaceholder":92},[67,2740,2741],{"class":69,"line":647},[67,2742,2743],{"class":107},"errOpen:\n",[67,2745,2746],{"class":69,"line":872},[67,2747,2748],{"class":73},"    \u002F\u002F f was never opened — no cleanup needed\n",[67,2750,2751,2753,2755,2757,2759,2761,2763,2765],{"class":69,"line":885},[67,2752,2399],{"class":99},[67,2754,1931],{"class":107},[67,2756,2721],{"class":103},[67,2758,1291],{"class":107},[67,2760,2726],{"class":619},[67,2762,2729],{"class":138},[67,2764,1945],{"class":619},[67,2766,2734],{"class":107},[67,2768,2769],{"class":69,"line":890},[67,2770,277],{"class":107},[67,2772,2773],{"class":69,"line":896},[67,2774,93],{"emptyLinePlaceholder":92},[67,2776,2777],{"class":69,"line":948},[67,2778,2779],{"class":73},"\u002F\u002F ⚠️ goto restrictions:\n",[67,2781,2782],{"class":69,"line":962},[67,2783,2784],{"class":73},"\u002F\u002F   - Can't jump over variable declarations (compile error)\n",[67,2786,2787],{"class":69,"line":975},[67,2788,2789],{"class":73},"\u002F\u002F   - Can't jump into a block from outside\n",[67,2791,2792],{"class":69,"line":980},[67,2793,2794],{"class":73},"\u002F\u002F   - Can't jump out of a function\n",[67,2796,2797],{"class":69,"line":985},[67,2798,2799],{"class":73},"\u002F\u002F These restrictions prevent spaghetti code — goto is deliberately limited.\n",[48,2801,2803,2805],{"id":2802},"select-concurrent-control-flow",[18,2804,30],{}," — Concurrent Control Flow",[55,2807,2808,3148,3154],{"language":57},[59,2809,2811],{"className":61,"code":2810,"language":57,"meta":63,"style":63},"\u002F\u002F select is Go's concurrent control flow — it waits on multiple channel\n\u002F\u002F operations simultaneously, executing the first one that's ready.\n\u002F\u002F If multiple are ready, it picks ONE at random.\n\nfunc selectBasics() {\n    ch1 := make(chan int, 1)\n    ch2 := make(chan int, 1)\n    ch1 \u003C- 1\n\n    select {\n    case v := \u003C-ch1:\n        fmt.Println(\"from ch1:\", v)\n    case v := \u003C-ch2:\n        fmt.Println(\"from ch2:\", v)\n    case \u003C-time.After(5 * time.Second):\n        fmt.Println(\"timeout\")\n    default:\n        fmt.Println(\"no channel ready (non-blocking)\")\n    }\n}\n\n\u002F\u002F select in a for loop — the event loop pattern:\nfunc eventLoop(events \u003C-chan Event, done \u003C-chan struct{}) {\n    for {\n        select {\n        case e := \u003C-events:\n            handleEvent(e)\n        case \u003C-done:\n            return  \u002F\u002F graceful shutdown\n        }\n    }\n}\n\n\u002F\u002F ⚠️ Without `default`, select BLOCKS until a case is ready.\n\u002F\u002F With `default`, select is non-blocking (runs default if nothing ready).\n\u002F\u002F `default` in a for-select loop creates a busy-spin (CPU 100%) —\n\u002F\u002F almost always a bug. Don't use default in for-select unless you\n\u002F\u002F genuinely want non-blocking polling with a sleep.\n",[18,2812,2813,2818,2823,2828,2832,2841,2863,2884,2894,2898,2905,2918,2932,2945,2958,2981,2994,3000,3013,3017,3021,3025,3030,3057,3063,3069,3083,3091,3099,3107,3111,3115,3119,3123,3128,3133,3138,3143],{"__ignoreMap":63},[67,2814,2815],{"class":69,"line":70},[67,2816,2817],{"class":73},"\u002F\u002F select is Go's concurrent control flow — it waits on multiple channel\n",[67,2819,2820],{"class":69,"line":77},[67,2821,2822],{"class":73},"\u002F\u002F operations simultaneously, executing the first one that's ready.\n",[67,2824,2825],{"class":69,"line":83},[67,2826,2827],{"class":73},"\u002F\u002F If multiple are ready, it picks ONE at random.\n",[67,2829,2830],{"class":69,"line":89},[67,2831,93],{"emptyLinePlaceholder":92},[67,2833,2834,2836,2839],{"class":69,"line":96},[67,2835,100],{"class":99},[67,2837,2838],{"class":103}," selectBasics",[67,2840,108],{"class":107},[67,2842,2843,2846,2848,2850,2852,2855,2857,2859,2861],{"class":69,"line":111},[67,2844,2845],{"class":107},"    ch1 ",[67,2847,126],{"class":99},[67,2849,999],{"class":103},[67,2851,1291],{"class":107},[67,2853,2854],{"class":99},"chan",[67,2856,1298],{"class":99},[67,2858,21],{"class":107},[67,2860,800],{"class":138},[67,2862,1459],{"class":107},[67,2864,2865,2868,2870,2872,2874,2876,2878,2880,2882],{"class":69,"line":117},[67,2866,2867],{"class":107},"    ch2 ",[67,2869,126],{"class":99},[67,2871,999],{"class":103},[67,2873,1291],{"class":107},[67,2875,2854],{"class":99},[67,2877,1298],{"class":99},[67,2879,21],{"class":107},[67,2881,800],{"class":138},[67,2883,1459],{"class":107},[67,2885,2886,2888,2891],{"class":69,"line":145},[67,2887,2845],{"class":107},[67,2889,2890],{"class":99},"\u003C-",[67,2892,2893],{"class":138}," 1\n",[67,2895,2896],{"class":69,"line":157},[67,2897,93],{"emptyLinePlaceholder":92},[67,2899,2900,2903],{"class":69,"line":163},[67,2901,2902],{"class":99},"    select",[67,2904,142],{"class":107},[67,2906,2907,2909,2911,2913,2915],{"class":69,"line":169},[67,2908,1439],{"class":99},[67,2910,634],{"class":107},[67,2912,126],{"class":99},[67,2914,2475],{"class":99},[67,2916,2917],{"class":107},"ch1:\n",[67,2919,2920,2922,2924,2926,2929],{"class":69,"line":174},[67,2921,857],{"class":107},[67,2923,442],{"class":103},[67,2925,1291],{"class":107},[67,2927,2928],{"class":619},"\"from ch1:\"",[67,2930,2931],{"class":107},", v)\n",[67,2933,2934,2936,2938,2940,2942],{"class":69,"line":180},[67,2935,1439],{"class":99},[67,2937,634],{"class":107},[67,2939,126],{"class":99},[67,2941,2475],{"class":99},[67,2943,2944],{"class":107},"ch2:\n",[67,2946,2947,2949,2951,2953,2956],{"class":69,"line":186},[67,2948,857],{"class":107},[67,2950,442],{"class":103},[67,2952,1291],{"class":107},[67,2954,2955],{"class":619},"\"from ch2:\"",[67,2957,2931],{"class":107},[67,2959,2960,2962,2964,2967,2970,2972,2975,2978],{"class":69,"line":192},[67,2961,1439],{"class":99},[67,2963,2475],{"class":99},[67,2965,2966],{"class":107},"time.",[67,2968,2969],{"class":103},"After",[67,2971,1291],{"class":107},[67,2973,2974],{"class":138},"5",[67,2976,2977],{"class":99}," *",[67,2979,2980],{"class":107}," time.Second):\n",[67,2982,2983,2985,2987,2989,2992],{"class":69,"line":198},[67,2984,857],{"class":107},[67,2986,442],{"class":103},[67,2988,1291],{"class":107},[67,2990,2991],{"class":619},"\"timeout\"",[67,2993,1459],{"class":107},[67,2995,2996,2998],{"class":69,"line":203},[67,2997,1521],{"class":99},[67,2999,1445],{"class":107},[67,3001,3002,3004,3006,3008,3011],{"class":69,"line":209},[67,3003,857],{"class":107},[67,3005,442],{"class":103},[67,3007,1291],{"class":107},[67,3009,3010],{"class":619},"\"no channel ready (non-blocking)\"",[67,3012,1459],{"class":107},[67,3014,3015],{"class":69,"line":231},[67,3016,160],{"class":107},[67,3018,3019],{"class":69,"line":240},[67,3020,277],{"class":107},[67,3022,3023],{"class":69,"line":251},[67,3024,93],{"emptyLinePlaceholder":92},[67,3026,3027],{"class":69,"line":263},[67,3028,3029],{"class":73},"\u002F\u002F select in a for loop — the event loop pattern:\n",[67,3031,3032,3034,3037,3039,3042,3044,3047,3049,3051,3053,3055],{"class":69,"line":268},[67,3033,100],{"class":99},[67,3035,3036],{"class":103}," eventLoop",[67,3038,1291],{"class":107},[67,3040,3041],{"class":1294},"events",[67,3043,2430],{"class":99},[67,3045,3046],{"class":103}," Event",[67,3048,21],{"class":107},[67,3050,2437],{"class":1294},[67,3052,2430],{"class":99},[67,3054,2442],{"class":99},[67,3056,2445],{"class":107},[67,3058,3059,3061],{"class":69,"line":274},[67,3060,817],{"class":99},[67,3062,142],{"class":107},[67,3064,3065,3067],{"class":69,"line":629},[67,3066,2461],{"class":99},[67,3068,142],{"class":107},[67,3070,3071,3073,3076,3078,3080],{"class":69,"line":647},[67,3072,2468],{"class":99},[67,3074,3075],{"class":107}," e ",[67,3077,126],{"class":99},[67,3079,2475],{"class":99},[67,3081,3082],{"class":107},"events:\n",[67,3084,3085,3088],{"class":69,"line":872},[67,3086,3087],{"class":103},"            handleEvent",[67,3089,3090],{"class":107},"(e)\n",[67,3092,3093,3095,3097],{"class":69,"line":885},[67,3094,2468],{"class":99},[67,3096,2475],{"class":99},[67,3098,2495],{"class":107},[67,3100,3101,3104],{"class":69,"line":890},[67,3102,3103],{"class":99},"            return",[67,3105,3106],{"class":73},"  \u002F\u002F graceful shutdown\n",[67,3108,3109],{"class":69,"line":896},[67,3110,2390],{"class":107},[67,3112,3113],{"class":69,"line":948},[67,3114,160],{"class":107},[67,3116,3117],{"class":69,"line":962},[67,3118,277],{"class":107},[67,3120,3121],{"class":69,"line":975},[67,3122,93],{"emptyLinePlaceholder":92},[67,3124,3125],{"class":69,"line":980},[67,3126,3127],{"class":73},"\u002F\u002F ⚠️ Without `default`, select BLOCKS until a case is ready.\n",[67,3129,3130],{"class":69,"line":985},[67,3131,3132],{"class":73},"\u002F\u002F With `default`, select is non-blocking (runs default if nothing ready).\n",[67,3134,3135],{"class":69,"line":991},[67,3136,3137],{"class":73},"\u002F\u002F `default` in a for-select loop creates a busy-spin (CPU 100%) —\n",[67,3139,3140],{"class":69,"line":1020},[67,3141,3142],{"class":73},"\u002F\u002F almost always a bug. Don't use default in for-select unless you\n",[67,3144,3145],{"class":69,"line":1033},[67,3146,3147],{"class":73},"\u002F\u002F genuinely want non-blocking polling with a sleep.\n",[48,3149,3151,3152],{"id":3150},"production-pattern-state-machine-with-switch","Production Pattern — State Machine with ",[18,3153,27],{},[55,3155,3156,3717,3721,3821,3825,4004,4008],{"language":57},[59,3157,3159],{"className":61,"code":3158,"language":57,"meta":63,"style":63},"type State int\nconst (\n    StateIdle State = iota\n    StateConnecting\n    StateConnected\n    StateReconnecting\n    StateError\n)\n\ntype Event int\nconst (\n    EventConnect Event = iota\n    EventConnected\n    EventDisconnect\n    EventError\n    EventRetry\n)\n\n\u002F\u002F transition table — pure function, easy to test\nfunc transition(s State, e Event) (State, error) {\n    switch s {\n    case StateIdle:\n        switch e {\n        case EventConnect:\n            return StateConnecting, nil\n        default:\n            return s, fmt.Errorf(\"illegal event %d in state Idle\", e)\n        }\n    case StateConnecting:\n        switch e {\n        case EventConnected:\n            return StateConnected, nil\n        case EventError:\n            return StateError, nil\n        case EventDisconnect:\n            return StateIdle, nil\n        default:\n            return s, fmt.Errorf(\"illegal event %d in state Connecting\", e)\n        }\n    case StateConnected:\n        switch e {\n        case EventDisconnect:\n            return StateIdle, nil\n        case EventError:\n            return StateReconnecting, nil\n        default:\n            return s, fmt.Errorf(\"illegal event %d in state Connected\", e)\n        }\n    case StateReconnecting:\n        switch e {\n        case EventConnected:\n            return StateConnected, nil\n        case EventError:\n            return StateError, nil\n        default:\n            return s, fmt.Errorf(\"illegal event %d in state Reconnecting\", e)\n        }\n    case StateError:\n        switch e {\n        case EventRetry:\n            return StateConnecting, nil\n        default:\n            return s, fmt.Errorf(\"illegal event %d in state Error\", e)\n        }\n    default:\n        return s, fmt.Errorf(\"unknown state %d\", s)\n    }\n}\n",[18,3160,3161,3171,3179,3192,3197,3202,3207,3212,3216,3220,3228,3234,3245,3250,3255,3260,3265,3269,3273,3278,3311,3317,3324,3332,3339,3349,3356,3378,3382,3389,3395,3402,3411,3418,3427,3434,3443,3449,3468,3472,3479,3485,3491,3499,3505,3514,3520,3539,3543,3550,3556,3562,3570,3576,3584,3590,3610,3615,3623,3630,3638,3647,3654,3674,3679,3686,3707,3712],{"__ignoreMap":63},[67,3162,3163,3165,3168],{"class":69,"line":70},[67,3164,1899],{"class":99},[67,3166,3167],{"class":103}," State",[67,3169,3170],{"class":99}," int\n",[67,3172,3173,3176],{"class":69,"line":77},[67,3174,3175],{"class":99},"const",[67,3177,3178],{"class":107}," (\n",[67,3180,3181,3184,3186,3189],{"class":69,"line":83},[67,3182,3183],{"class":138},"    StateIdle",[67,3185,3167],{"class":103},[67,3187,3188],{"class":99}," =",[67,3190,3191],{"class":138}," iota\n",[67,3193,3194],{"class":69,"line":89},[67,3195,3196],{"class":138},"    StateConnecting\n",[67,3198,3199],{"class":69,"line":96},[67,3200,3201],{"class":138},"    StateConnected\n",[67,3203,3204],{"class":69,"line":111},[67,3205,3206],{"class":138},"    StateReconnecting\n",[67,3208,3209],{"class":69,"line":117},[67,3210,3211],{"class":138},"    StateError\n",[67,3213,3214],{"class":69,"line":145},[67,3215,1459],{"class":107},[67,3217,3218],{"class":69,"line":157},[67,3219,93],{"emptyLinePlaceholder":92},[67,3221,3222,3224,3226],{"class":69,"line":163},[67,3223,1899],{"class":99},[67,3225,3046],{"class":103},[67,3227,3170],{"class":99},[67,3229,3230,3232],{"class":69,"line":169},[67,3231,3175],{"class":99},[67,3233,3178],{"class":107},[67,3235,3236,3239,3241,3243],{"class":69,"line":174},[67,3237,3238],{"class":138},"    EventConnect",[67,3240,3046],{"class":103},[67,3242,3188],{"class":99},[67,3244,3191],{"class":138},[67,3246,3247],{"class":69,"line":180},[67,3248,3249],{"class":138},"    EventConnected\n",[67,3251,3252],{"class":69,"line":186},[67,3253,3254],{"class":138},"    EventDisconnect\n",[67,3256,3257],{"class":69,"line":192},[67,3258,3259],{"class":138},"    EventError\n",[67,3261,3262],{"class":69,"line":198},[67,3263,3264],{"class":138},"    EventRetry\n",[67,3266,3267],{"class":69,"line":203},[67,3268,1459],{"class":107},[67,3270,3271],{"class":69,"line":209},[67,3272,93],{"emptyLinePlaceholder":92},[67,3274,3275],{"class":69,"line":231},[67,3276,3277],{"class":73},"\u002F\u002F transition table — pure function, easy to test\n",[67,3279,3280,3282,3285,3287,3290,3292,3294,3297,3299,3302,3305,3307,3309],{"class":69,"line":240},[67,3281,100],{"class":99},[67,3283,3284],{"class":103}," transition",[67,3286,1291],{"class":107},[67,3288,3289],{"class":1294},"s",[67,3291,3167],{"class":103},[67,3293,21],{"class":107},[67,3295,3296],{"class":1294},"e",[67,3298,3046],{"class":103},[67,3300,3301],{"class":107},") (",[67,3303,3304],{"class":103},"State",[67,3306,21],{"class":107},[67,3308,2564],{"class":99},[67,3310,1426],{"class":107},[67,3312,3313,3315],{"class":69,"line":251},[67,3314,1431],{"class":99},[67,3316,826],{"class":107},[67,3318,3319,3321],{"class":69,"line":263},[67,3320,1439],{"class":99},[67,3322,3323],{"class":107}," StateIdle:\n",[67,3325,3326,3329],{"class":69,"line":268},[67,3327,3328],{"class":99},"        switch",[67,3330,3331],{"class":107}," e {\n",[67,3333,3334,3336],{"class":69,"line":274},[67,3335,2468],{"class":99},[67,3337,3338],{"class":107}," EventConnect:\n",[67,3340,3341,3343,3346],{"class":69,"line":629},[67,3342,3103],{"class":99},[67,3344,3345],{"class":107}," StateConnecting, ",[67,3347,3348],{"class":138},"nil\n",[67,3350,3351,3354],{"class":69,"line":647},[67,3352,3353],{"class":99},"        default",[67,3355,1445],{"class":107},[67,3357,3358,3360,3363,3365,3367,3370,3372,3375],{"class":69,"line":872},[67,3359,3103],{"class":99},[67,3361,3362],{"class":107}," s, fmt.",[67,3364,2721],{"class":103},[67,3366,1291],{"class":107},[67,3368,3369],{"class":619},"\"illegal event ",[67,3371,1942],{"class":138},[67,3373,3374],{"class":619}," in state Idle\"",[67,3376,3377],{"class":107},", e)\n",[67,3379,3380],{"class":69,"line":885},[67,3381,2390],{"class":107},[67,3383,3384,3386],{"class":69,"line":890},[67,3385,1439],{"class":99},[67,3387,3388],{"class":107}," StateConnecting:\n",[67,3390,3391,3393],{"class":69,"line":896},[67,3392,3328],{"class":99},[67,3394,3331],{"class":107},[67,3396,3397,3399],{"class":69,"line":948},[67,3398,2468],{"class":99},[67,3400,3401],{"class":107}," EventConnected:\n",[67,3403,3404,3406,3409],{"class":69,"line":962},[67,3405,3103],{"class":99},[67,3407,3408],{"class":107}," StateConnected, ",[67,3410,3348],{"class":138},[67,3412,3413,3415],{"class":69,"line":975},[67,3414,2468],{"class":99},[67,3416,3417],{"class":107}," EventError:\n",[67,3419,3420,3422,3425],{"class":69,"line":980},[67,3421,3103],{"class":99},[67,3423,3424],{"class":107}," StateError, ",[67,3426,3348],{"class":138},[67,3428,3429,3431],{"class":69,"line":985},[67,3430,2468],{"class":99},[67,3432,3433],{"class":107}," EventDisconnect:\n",[67,3435,3436,3438,3441],{"class":69,"line":991},[67,3437,3103],{"class":99},[67,3439,3440],{"class":107}," StateIdle, ",[67,3442,3348],{"class":138},[67,3444,3445,3447],{"class":69,"line":1020},[67,3446,3353],{"class":99},[67,3448,1445],{"class":107},[67,3450,3451,3453,3455,3457,3459,3461,3463,3466],{"class":69,"line":1033},[67,3452,3103],{"class":99},[67,3454,3362],{"class":107},[67,3456,2721],{"class":103},[67,3458,1291],{"class":107},[67,3460,3369],{"class":619},[67,3462,1942],{"class":138},[67,3464,3465],{"class":619}," in state Connecting\"",[67,3467,3377],{"class":107},[67,3469,3470],{"class":69,"line":1046},[67,3471,2390],{"class":107},[67,3473,3474,3476],{"class":69,"line":1051},[67,3475,1439],{"class":99},[67,3477,3478],{"class":107}," StateConnected:\n",[67,3480,3481,3483],{"class":69,"line":1063},[67,3482,3328],{"class":99},[67,3484,3331],{"class":107},[67,3486,3487,3489],{"class":69,"line":1078},[67,3488,2468],{"class":99},[67,3490,3433],{"class":107},[67,3492,3493,3495,3497],{"class":69,"line":1091},[67,3494,3103],{"class":99},[67,3496,3440],{"class":107},[67,3498,3348],{"class":138},[67,3500,3501,3503],{"class":69,"line":1096},[67,3502,2468],{"class":99},[67,3504,3417],{"class":107},[67,3506,3507,3509,3512],{"class":69,"line":1757},[67,3508,3103],{"class":99},[67,3510,3511],{"class":107}," StateReconnecting, ",[67,3513,3348],{"class":138},[67,3515,3516,3518],{"class":69,"line":1763},[67,3517,3353],{"class":99},[67,3519,1445],{"class":107},[67,3521,3522,3524,3526,3528,3530,3532,3534,3537],{"class":69,"line":1773},[67,3523,3103],{"class":99},[67,3525,3362],{"class":107},[67,3527,2721],{"class":103},[67,3529,1291],{"class":107},[67,3531,3369],{"class":619},[67,3533,1942],{"class":138},[67,3535,3536],{"class":619}," in state Connected\"",[67,3538,3377],{"class":107},[67,3540,3541],{"class":69,"line":1788},[67,3542,2390],{"class":107},[67,3544,3545,3547],{"class":69,"line":1801},[67,3546,1439],{"class":99},[67,3548,3549],{"class":107}," StateReconnecting:\n",[67,3551,3552,3554],{"class":69,"line":1810},[67,3553,3328],{"class":99},[67,3555,3331],{"class":107},[67,3557,3558,3560],{"class":69,"line":1823},[67,3559,2468],{"class":99},[67,3561,3401],{"class":107},[67,3563,3564,3566,3568],{"class":69,"line":1831},[67,3565,3103],{"class":99},[67,3567,3408],{"class":107},[67,3569,3348],{"class":138},[67,3571,3572,3574],{"class":69,"line":1838},[67,3573,2468],{"class":99},[67,3575,3417],{"class":107},[67,3577,3578,3580,3582],{"class":69,"line":1846},[67,3579,3103],{"class":99},[67,3581,3424],{"class":107},[67,3583,3348],{"class":138},[67,3585,3586,3588],{"class":69,"line":1851},[67,3587,3353],{"class":99},[67,3589,1445],{"class":107},[67,3591,3593,3595,3597,3599,3601,3603,3605,3608],{"class":69,"line":3592},56,[67,3594,3103],{"class":99},[67,3596,3362],{"class":107},[67,3598,2721],{"class":103},[67,3600,1291],{"class":107},[67,3602,3369],{"class":619},[67,3604,1942],{"class":138},[67,3606,3607],{"class":619}," in state Reconnecting\"",[67,3609,3377],{"class":107},[67,3611,3613],{"class":69,"line":3612},57,[67,3614,2390],{"class":107},[67,3616,3618,3620],{"class":69,"line":3617},58,[67,3619,1439],{"class":99},[67,3621,3622],{"class":107}," StateError:\n",[67,3624,3626,3628],{"class":69,"line":3625},59,[67,3627,3328],{"class":99},[67,3629,3331],{"class":107},[67,3631,3633,3635],{"class":69,"line":3632},60,[67,3634,2468],{"class":99},[67,3636,3637],{"class":107}," EventRetry:\n",[67,3639,3641,3643,3645],{"class":69,"line":3640},61,[67,3642,3103],{"class":99},[67,3644,3345],{"class":107},[67,3646,3348],{"class":138},[67,3648,3650,3652],{"class":69,"line":3649},62,[67,3651,3353],{"class":99},[67,3653,1445],{"class":107},[67,3655,3657,3659,3661,3663,3665,3667,3669,3672],{"class":69,"line":3656},63,[67,3658,3103],{"class":99},[67,3660,3362],{"class":107},[67,3662,2721],{"class":103},[67,3664,1291],{"class":107},[67,3666,3369],{"class":619},[67,3668,1942],{"class":138},[67,3670,3671],{"class":619}," in state Error\"",[67,3673,3377],{"class":107},[67,3675,3677],{"class":69,"line":3676},64,[67,3678,2390],{"class":107},[67,3680,3682,3684],{"class":69,"line":3681},65,[67,3683,1521],{"class":99},[67,3685,1445],{"class":107},[67,3687,3689,3691,3693,3695,3697,3700,3702,3704],{"class":69,"line":3688},66,[67,3690,234],{"class":99},[67,3692,3362],{"class":107},[67,3694,2721],{"class":103},[67,3696,1291],{"class":107},[67,3698,3699],{"class":619},"\"unknown state ",[67,3701,1942],{"class":138},[67,3703,1945],{"class":619},[67,3705,3706],{"class":107},", s)\n",[67,3708,3710],{"class":69,"line":3709},67,[67,3711,160],{"class":107},[67,3713,3715],{"class":69,"line":3714},68,[67,3716,277],{"class":107},[48,3718,3720],{"id":3719},"tips-tricks","💡 Tips & Tricks",[3722,3723,3724,3739,3754,3769,3781,3797],"ul",{},[3725,3726,3727,923,3731,3734,3735,3738],"li",{},[3728,3729,3730],"strong",{},"Idiom",[18,3732,3733],{},"if init; condition"," keeps temporary variables scoped to the block — ",[18,3736,3737],{},"if err := f(); err != nil"," signals \"err is only for this check.\" This is the Go equivalent of try-catch's local error scope.",[3725,3740,3741,923,3743,3745,3746,3749,3750,3753],{},[3728,3742,3730],{},[18,3744,27],{}," with no expression (",[18,3747,3748],{},"switch { case x \u003C 0: ... }",") is cleaner than long ",[18,3751,3752],{},"if\u002Felse if"," chains — each case has its own condition, and the compiler generates a jump table when possible.",[3725,3755,3756,923,3758,3761,3762,3764,3765,3768],{},[3728,3757,3730],{},[18,3759,3760],{},"for i := range n"," (Go 1.22+) is the cleanest simple count loop — no off-by-one, no ",[18,3763,423],{}," vs ",[18,3766,3767],{},"\u003C="," confusion. Use for any \"do this N times\" loop.",[3725,3770,3771,923,3774,3776,3777,3780],{},[3728,3772,3773],{},"Performance",[18,3775,669],{}," over a slice copies the element value into the loop variable — for large structs, use index access (",[18,3778,3779],{},"for i := range s { s[i].field }",") to avoid copying. Or range over a slice of pointers.",[3725,3782,3783,3785,3786,3788,3789,3792,3793,3796],{},[3728,3784,3730],{},": labeled ",[18,3787,2211],{}," for nested-loop exits — ",[18,3790,3791],{},"break outer"," is the clean way to exit from deep inside nested loops. The alternative (flags like ",[18,3794,3795],{},"found := true; break",") is less readable.",[3725,3798,3799,923,3801,3804,3805,3807,3808,3811,3812,3814,3815,3817,3818,3820],{},[3728,3800,3730],{},[18,3802,3803],{},"for-select"," with a ",[18,3806,2437],{}," channel and ",[18,3809,3810],{},"break loop"," is the standard concurrent event-loop pattern — the label is needed because ",[18,3813,2211],{}," alone only exits the ",[18,3816,30],{},", not the ",[18,3819,24],{},".",[48,3822,3824],{"id":3823},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[3722,3826,3827,3845,3864,3883,3891,3913,3931,3951,3969,3983,3996],{},[3725,3828,3829,923,3832,3835,3836,3838,3839,2212,3841,2212,3843,3820],{},[3728,3830,3831],{},"Braces mandatory, same-line",[18,3833,3834],{},"if x\\n{"," is a syntax error (ASI inserts a semicolon after ",[18,3837,1421],{},"). The opening brace must be on the same line as ",[18,3840,20],{},[18,3842,24],{},[18,3844,100],{},[3725,3846,3847,3852,3853,3855,3856,3859,3860,3863],{},[3728,3848,3849,3851],{},[18,3850,27],{}," doesn't fall through by default",": unlike C\u002FJava, each case ends without ",[18,3854,2211],{},". ",[18,3857,3858],{},"fallthrough"," is explicit and jumps to the next case's body ",[3728,3861,3862],{},"unconditionally"," (doesn't check the next case's value).",[3725,3865,3866,923,3871,3874,3875,3878,3879,3882],{},[3728,3867,3868,3870],{},[18,3869,669],{}," over a string yields byte offsets",[18,3872,3873],{},"for i, r := range \"café\""," gives ",[18,3876,3877],{},"i=0,2,3,4"," (not ",[18,3880,3881],{},"0,1,2,3",") because 'a' is 1 byte but 'é' is 2 bytes — the index is the byte position, not the character index.",[3725,3884,3885,3890],{},[3728,3886,3887,3889],{},[18,3888,669],{}," over a map is randomized",": iteration order is intentionally shuffled each run. Never depend on map iteration order — sort keys explicitly.",[3725,3892,3893,923,3898,3901,3902,3904,3905,3908,3909,3912],{},[3728,3894,3895,3896],{},"Modifying a slice during ",[18,3897,669],{},[18,3899,3900],{},"for i, v := range s { s = append(s, v) }"," — ",[18,3903,669],{}," captured ",[18,3906,3907],{},"len(s)"," at loop start, so appended elements aren't iterated. Modifying existing elements (",[18,3910,3911],{},"s[i] = ...",") works fine.",[3725,3914,3915,923,3920,3923,3924,3926,3927,3930],{},[3728,3916,3917,3919],{},[18,3918,669],{}," copies the element",[18,3921,3922],{},"for _, v := range largeSlice"," copies each element into ",[18,3925,1876],{},". For large structs, use ",[18,3928,3929],{},"for i := range s { v := &s[i] }"," to avoid copies.",[3725,3932,3933,923,3943,3945,3946,3817,3948,3950],{},[3728,3934,3935,3937,3938,3940,3941],{},[18,3936,2215],{}," in a ",[18,3939,30],{}," inside a ",[18,3942,24],{},[18,3944,2215],{}," applies to the enclosing ",[18,3947,24],{},[18,3949,30],{},". This is correct but surprising.",[3725,3952,3953,3961,3962,3965,3966,3968],{},[3728,3954,3955,3937,3958,3960],{},[18,3956,3957],{},"default",[18,3959,3803],{}," causes busy-spin",": without a blocking case or a ",[18,3963,3964],{},"time.Sleep",", the loop spins at 100% CPU. Only use ",[18,3967,3957],{}," when you genuinely want non-blocking polling.",[3725,3970,3971,923,3976,3979,3980,3982],{},[3728,3972,3973,3975],{},[18,3974,34],{}," can't jump over variable declarations",[18,3977,3978],{},"goto end; x := 5; end:"," is a compile error. ",[18,3981,34],{}," is restricted to prevent scope violations.",[3725,3984,3985,923,3988,3991,3992,3995],{},[3728,3986,3987],{},"Go 1.22 loop scoping is controlled by go.mod",[18,3989,3990],{},"go 1.22"," in go.mod enables per-iteration loop variables. ",[18,3993,3994],{},"go 1.21"," keeps old semantics even on a 1.22+ compiler. The go directive is a language version selector, not just a minimum.",[3725,3997,3998,4003],{},[3728,3999,4000],{},[18,4001,4002],{},"for i := range -1"," (Go 1.22+): negative integers cause a runtime panic (\"range clause: negative range value\"). Always validate before ranging over a computed integer.",[48,4005,4007],{"id":4006},"quick-quiz","🧠 Quick Quiz",[55,4009,4010,4116],{"language":57},[59,4011,4013],{"className":61,"code":4012,"language":57,"meta":63,"style":63},"s := []int{1, 2, 3}\nfor i, v := range s {\n    s = append(s, v*10)\n    fmt.Printf(\"i=%d v=%d len=%d\\n\", i, v, len(s))\n}\nfmt.Println(s)\n",[18,4014,4015,4040,4052,4068,4102,4106],{"__ignoreMap":63},[67,4016,4017,4020,4022,4024,4026,4028,4030,4032,4034,4036,4038],{"class":69,"line":70},[67,4018,4019],{"class":107},"s ",[67,4021,126],{"class":99},[67,4023,791],{"class":107},[67,4025,794],{"class":99},[67,4027,797],{"class":107},[67,4029,800],{"class":138},[67,4031,21],{"class":107},[67,4033,805],{"class":138},[67,4035,21],{"class":107},[67,4037,810],{"class":138},[67,4039,277],{"class":107},[67,4041,4042,4044,4046,4048,4050],{"class":69,"line":77},[67,4043,24],{"class":99},[67,4045,544],{"class":107},[67,4047,126],{"class":99},[67,4049,549],{"class":99},[67,4051,826],{"class":107},[67,4053,4054,4056,4058,4060,4062,4064,4066],{"class":69,"line":83},[67,4055,786],{"class":107},[67,4057,834],{"class":99},[67,4059,837],{"class":103},[67,4061,840],{"class":107},[67,4063,843],{"class":99},[67,4065,846],{"class":138},[67,4067,1459],{"class":107},[67,4069,4070,4072,4074,4076,4079,4081,4084,4086,4089,4092,4094,4097,4099],{"class":69,"line":89},[67,4071,439],{"class":107},[67,4073,2323],{"class":103},[67,4075,1291],{"class":107},[67,4077,4078],{"class":619},"\"i=",[67,4080,1942],{"class":138},[67,4082,4083],{"class":619}," v=",[67,4085,1942],{"class":138},[67,4087,4088],{"class":619}," len=",[67,4090,4091],{"class":138},"%d\\n",[67,4093,1945],{"class":619},[67,4095,4096],{"class":107},", i, v, ",[67,4098,1014],{"class":103},[67,4100,4101],{"class":107},"(s))\n",[67,4103,4104],{"class":69,"line":96},[67,4105,277],{"class":107},[67,4107,4108,4111,4113],{"class":69,"line":111},[67,4109,4110],{"class":107},"fmt.",[67,4112,442],{"class":103},[67,4114,4115],{"class":107},"(s)\n",[14,4117,4118],{},"What's printed?",[4120,4121,4122,4126,4134,4156,4166],"details",{},[4123,4124,4125],"summary",{},"Answer",[59,4127,4132],{"className":4128,"code":4130,"language":4131},[4129],"language-text","i=0 v=1 len=4\ni=1 v=2 len=5\ni=2 v=3 len=6\n[1 2 3 10 20 30]\n","text",[18,4133,4130],{"__ignoreMap":63},[14,4135,4136,4138,4139,4141,4142,4145,4146,4149,4150,4152,4153,4155],{},[18,4137,669],{}," evaluates ",[18,4140,3289],{}," once at loop start, capturing ",[18,4143,4144],{},"len(s) = 3",". The loop runs exactly 3 times (i=0,1,2) with the original values (1,2,3). The ",[18,4147,4148],{},"append"," inside the loop grows ",[18,4151,3289],{},", but ",[18,4154,669],{}," doesn't see the new length — it uses the snapshot from loop start.",[14,4157,4158,4159,4161,4162,4165],{},"The final ",[18,4160,3289],{}," is ",[18,4163,4164],{},"[1 2 3 10 20 30]"," — the appends did happen, they just weren't iterated.",[14,4167,4168,923,4171,4173,4174,4177],{},[3728,4169,4170],{},"The lesson",[18,4172,669],{}," captures the slice's length at loop start. Appending during iteration doesn't extend the loop. If you need to process appended elements, use an explicit index loop: ",[18,4175,4176],{},"for i := 0; i \u003C len(s); i++ { s = append(s, s[i]*10) }"," — but this creates an infinite loop! Use a captured length or a separate slice.",[48,4179,4181],{"id":4180},"whats-next","📚 What's Next",[14,4183,4184,4185,4190,4191,4193],{},"→ ",[4186,4187,4189],"a",{"href":4188},"\u002Fgo\u002F07-arrays-slices-and-strings","07 — Arrays, Slices & Strings"," — slice header mechanics, ",[18,4192,4148],{}," growth strategy, aliasing traps, and zero-allocation string patterns.",[4195,4196,4197],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":63,"searchDepth":77,"depth":77,"links":4199},[4200,4204],{"id":50,"depth":77,"text":4201,"children":4202},"if — Init Statement and Scoping",[4203],{"id":281,"depth":83,"text":282},{"id":4180,"depth":77,"text":4181},"if-init scoping, for-range internals, switch dispatch mechanics, labeled breaks, Go 1.22 loop scoping, and select as a concurrent control-flow primitive.","md",{},"\u002Fgo\u002F06-control-flow",{"title":5,"description":4205},"go\u002F06-control-flow","BQFKk59iJW7OZ1ofqqi2YFThZWtfuocC7HPoREPRxjo",1789924648317]