[{"data":1,"prerenderedAt":3838},["ShallowReactive",2],{"page-\u002Fgo\u002F03-variables-constants-and-types":3},{"id":4,"title":5,"body":6,"description":3831,"extension":3832,"meta":3833,"navigation":93,"path":3834,"seo":3835,"stem":3836,"__hash__":3837},"content\u002Fgo\u002F03-variables-constants-and-types.md","03 — Variables, Constants & Types",{"type":7,"value":8,"toc":3806},"minimark",[9,13,18,336,343,699,703,916,920,1176,1180,1456,1460,1692,1699,2231,2239,2444,2448,2823,2827,3125,3132,3342,3346,3450,3454,3638,3642,3721,3789,3793,3802],[10,11,5],"h1",{"id":12},"_03-variables-constants-types",[14,15,17],"h2",{"id":16},"variable-declaration-all-forms-and-when-to-use-each","Variable Declaration — All Forms and When to Use Each",[19,20,22],"code-wrapper",{"language":21},"go",[23,24,28],"pre",{"className":25,"code":26,"language":21,"meta":27,"style":27},"language-go shiki shiki-themes github-light github-dark","\u002F\u002F ┌─────────────────────────────────────────────────────────────────┐\n\u002F\u002F │ Form            │ Scope        │ Use When                       │\n\u002F\u002F │ ─────────────── │ ──────────── │ ────────────────────────────── │\n\u002F\u002F │ var x int       │ any          │ need zero value, explicit type │\n\u002F\u002F │ var x = 42      │ any          │ type inference at pkg scope    │\n\u002F\u002F │ var x int = 42  │ any          │ explicit type + initial value  │\n\u002F\u002F │ x := 42         │ func body    │ most common inside functions   │\n\u002F\u002F │ var (...)       │ any          │ grouped package-level vars     │\n\u002F\u002F └─────────────────────────────────────────────────────────────────┘\n\npackage server\n\n\u002F\u002F Package-level declarations — use `var` (:= not allowed here).\nvar (\n    shutdownChan = make(chan struct{})  \u002F\u002F type inferred: chan struct{}\n    listenAddr   = \":8080\"              \u002F\u002F type inferred: string\n    maxProcs     = runtime.GOMAXPROCS(0) \u002F\u002F type inferred: int (runtime call)\n)\n\nfunc example() {\n    \u002F\u002F Inside functions — `:=` is idiomatic.\n    port := 8080\n    host, err := lookupHost(\"example.com\")  \u002F\u002F multi-value declaration\n    if err != nil {\n        return\n    }\n\n    \u002F\u002F `:=` with mixed new + existing variables — legal if ≥1 is new.\n    host2, err := lookupHost(\"other.com\")  \u002F\u002F host2 is new, err is reassigned\n    _ = host2\n}\n","",[29,30,31,40,46,52,58,64,70,76,82,88,95,106,111,117,127,154,169,195,201,206,218,224,236,258,276,282,288,293,299,319,330],"code",{"__ignoreMap":27},[32,33,36],"span",{"class":34,"line":35},"line",1,[32,37,39],{"class":38},"sdCPZ","\u002F\u002F ┌─────────────────────────────────────────────────────────────────┐\n",[32,41,43],{"class":34,"line":42},2,[32,44,45],{"class":38},"\u002F\u002F │ Form            │ Scope        │ Use When                       │\n",[32,47,49],{"class":34,"line":48},3,[32,50,51],{"class":38},"\u002F\u002F │ ─────────────── │ ──────────── │ ────────────────────────────── │\n",[32,53,55],{"class":34,"line":54},4,[32,56,57],{"class":38},"\u002F\u002F │ var x int       │ any          │ need zero value, explicit type │\n",[32,59,61],{"class":34,"line":60},5,[32,62,63],{"class":38},"\u002F\u002F │ var x = 42      │ any          │ type inference at pkg scope    │\n",[32,65,67],{"class":34,"line":66},6,[32,68,69],{"class":38},"\u002F\u002F │ var x int = 42  │ any          │ explicit type + initial value  │\n",[32,71,73],{"class":34,"line":72},7,[32,74,75],{"class":38},"\u002F\u002F │ x := 42         │ func body    │ most common inside functions   │\n",[32,77,79],{"class":34,"line":78},8,[32,80,81],{"class":38},"\u002F\u002F │ var (...)       │ any          │ grouped package-level vars     │\n",[32,83,85],{"class":34,"line":84},9,[32,86,87],{"class":38},"\u002F\u002F └─────────────────────────────────────────────────────────────────┘\n",[32,89,91],{"class":34,"line":90},10,[32,92,94],{"emptyLinePlaceholder":93},true,"\n",[32,96,98,102],{"class":34,"line":97},11,[32,99,101],{"class":100},"svdQ7","package",[32,103,105],{"class":104},"sIsaT"," server\n",[32,107,109],{"class":34,"line":108},12,[32,110,94],{"emptyLinePlaceholder":93},[32,112,114],{"class":34,"line":113},13,[32,115,116],{"class":38},"\u002F\u002F Package-level declarations — use `var` (:= not allowed here).\n",[32,118,120,123],{"class":34,"line":119},14,[32,121,122],{"class":100},"var",[32,124,126],{"class":125},"ssxIu"," (\n",[32,128,130,133,136,139,142,145,148,151],{"class":34,"line":129},15,[32,131,132],{"class":125},"    shutdownChan ",[32,134,135],{"class":100},"=",[32,137,138],{"class":104}," make",[32,140,141],{"class":125},"(",[32,143,144],{"class":100},"chan",[32,146,147],{"class":100}," struct",[32,149,150],{"class":125},"{})  ",[32,152,153],{"class":38},"\u002F\u002F type inferred: chan struct{}\n",[32,155,157,160,162,166],{"class":34,"line":156},16,[32,158,159],{"class":125},"    listenAddr   ",[32,161,135],{"class":100},[32,163,165],{"class":164},"sJ6F3"," \":8080\"",[32,167,168],{"class":38},"              \u002F\u002F type inferred: string\n",[32,170,172,175,177,180,183,185,189,192],{"class":34,"line":171},17,[32,173,174],{"class":125},"    maxProcs     ",[32,176,135],{"class":100},[32,178,179],{"class":125}," runtime.",[32,181,182],{"class":104},"GOMAXPROCS",[32,184,141],{"class":125},[32,186,188],{"class":187},"snvgF","0",[32,190,191],{"class":125},") ",[32,193,194],{"class":38},"\u002F\u002F type inferred: int (runtime call)\n",[32,196,198],{"class":34,"line":197},18,[32,199,200],{"class":125},")\n",[32,202,204],{"class":34,"line":203},19,[32,205,94],{"emptyLinePlaceholder":93},[32,207,209,212,215],{"class":34,"line":208},20,[32,210,211],{"class":100},"func",[32,213,214],{"class":104}," example",[32,216,217],{"class":125},"() {\n",[32,219,221],{"class":34,"line":220},21,[32,222,223],{"class":38},"    \u002F\u002F Inside functions — `:=` is idiomatic.\n",[32,225,227,230,233],{"class":34,"line":226},22,[32,228,229],{"class":125},"    port ",[32,231,232],{"class":100},":=",[32,234,235],{"class":187}," 8080\n",[32,237,239,242,244,247,249,252,255],{"class":34,"line":238},23,[32,240,241],{"class":125},"    host, err ",[32,243,232],{"class":100},[32,245,246],{"class":104}," lookupHost",[32,248,141],{"class":125},[32,250,251],{"class":164},"\"example.com\"",[32,253,254],{"class":125},")  ",[32,256,257],{"class":38},"\u002F\u002F multi-value declaration\n",[32,259,261,264,267,270,273],{"class":34,"line":260},24,[32,262,263],{"class":100},"    if",[32,265,266],{"class":125}," err ",[32,268,269],{"class":100},"!=",[32,271,272],{"class":187}," nil",[32,274,275],{"class":125}," {\n",[32,277,279],{"class":34,"line":278},25,[32,280,281],{"class":100},"        return\n",[32,283,285],{"class":34,"line":284},26,[32,286,287],{"class":125},"    }\n",[32,289,291],{"class":34,"line":290},27,[32,292,94],{"emptyLinePlaceholder":93},[32,294,296],{"class":34,"line":295},28,[32,297,298],{"class":38},"    \u002F\u002F `:=` with mixed new + existing variables — legal if ≥1 is new.\n",[32,300,302,305,307,309,311,314,316],{"class":34,"line":301},29,[32,303,304],{"class":125},"    host2, err ",[32,306,232],{"class":100},[32,308,246],{"class":104},[32,310,141],{"class":125},[32,312,313],{"class":164},"\"other.com\"",[32,315,254],{"class":125},[32,317,318],{"class":38},"\u002F\u002F host2 is new, err is reassigned\n",[32,320,322,325,327],{"class":34,"line":321},30,[32,323,324],{"class":125},"    _ ",[32,326,135],{"class":100},[32,328,329],{"class":125}," host2\n",[32,331,333],{"class":34,"line":332},31,[32,334,335],{"class":125},"}\n",[337,338,340,342],"h3",{"id":339},"rules-and-the-shadowing-trap",[29,341,232],{}," rules and the shadowing trap",[19,344,345],{"language":21},[23,346,348],{"className":25,"code":347,"language":21,"meta":27,"style":27},"func shadowTrap() int {\n    x := 5\n\n    if true {\n        x := 10        \u002F\u002F ❌ ANTI-PATTERN: declares a NEW x in the if-block scope\n                       \u002F\u002F   shadows the outer x — outer x is never modified\n        fmt.Println(x) \u002F\u002F 10 (inner x)\n    }\n    fmt.Println(x)    \u002F\u002F 5 (outer x unchanged)\n    return x           \u002F\u002F returns 5\n\n    \u002F\u002F ✅ CORRECT: use `=` to modify the outer variable:\n    \u002F\u002F x = 10          \u002F\u002F assignment, not declaration — modifies outer x\n}\n\n\u002F\u002F ⚠️ The same trap in for-loops (pre-Go 1.22):\nfunc loopShadowPre122() {\n    var fns []func()\n    for i := 0; i \u003C 3; i++ {\n        fns = append(fns, func() { fmt.Println(i) })  \u002F\u002F captures the SAME i\n    }\n    for _, f := range fns {\n        f()  \u002F\u002F pre-1.22: prints 3 3 3 (all see final i=3)\n    }\n}\n\n\u002F\u002F ✅ Fixed — pass as parameter (pre-1.22 pattern):\nfunc loopShadowFixed() {\n    var fns []func()\n    for i := 0; i \u003C 3; i++ {\n        i := i  \u002F\u002F ⚠️ creates a new i per iteration (pre-1.22 idiom)\n        fns = append(fns, func() { fmt.Println(i) })\n    }\n    \u002F\u002F Go 1.22+ fixes this — loop vars are per-iteration by default.\n    \u002F\u002F The `i := i` shadow is no longer needed (but doesn't hurt).\n}\n",[29,349,350,365,375,379,388,401,406,420,424,437,448,452,457,465,469,473,478,487,500,530,556,560,575,586,590,594,598,603,612,622,644,657,677,682,688,694],{"__ignoreMap":27},[32,351,352,354,357,360,363],{"class":34,"line":35},[32,353,211],{"class":100},[32,355,356],{"class":104}," shadowTrap",[32,358,359],{"class":125},"() ",[32,361,362],{"class":100},"int",[32,364,275],{"class":125},[32,366,367,370,372],{"class":34,"line":42},[32,368,369],{"class":125},"    x ",[32,371,232],{"class":100},[32,373,374],{"class":187}," 5\n",[32,376,377],{"class":34,"line":48},[32,378,94],{"emptyLinePlaceholder":93},[32,380,381,383,386],{"class":34,"line":54},[32,382,263],{"class":100},[32,384,385],{"class":187}," true",[32,387,275],{"class":125},[32,389,390,393,395,398],{"class":34,"line":60},[32,391,392],{"class":125},"        x ",[32,394,232],{"class":100},[32,396,397],{"class":187}," 10",[32,399,400],{"class":38},"        \u002F\u002F ❌ ANTI-PATTERN: declares a NEW x in the if-block scope\n",[32,402,403],{"class":34,"line":66},[32,404,405],{"class":38},"                       \u002F\u002F   shadows the outer x — outer x is never modified\n",[32,407,408,411,414,417],{"class":34,"line":72},[32,409,410],{"class":125},"        fmt.",[32,412,413],{"class":104},"Println",[32,415,416],{"class":125},"(x) ",[32,418,419],{"class":38},"\u002F\u002F 10 (inner x)\n",[32,421,422],{"class":34,"line":78},[32,423,287],{"class":125},[32,425,426,429,431,434],{"class":34,"line":84},[32,427,428],{"class":125},"    fmt.",[32,430,413],{"class":104},[32,432,433],{"class":125},"(x)    ",[32,435,436],{"class":38},"\u002F\u002F 5 (outer x unchanged)\n",[32,438,439,442,445],{"class":34,"line":90},[32,440,441],{"class":100},"    return",[32,443,444],{"class":125}," x           ",[32,446,447],{"class":38},"\u002F\u002F returns 5\n",[32,449,450],{"class":34,"line":97},[32,451,94],{"emptyLinePlaceholder":93},[32,453,454],{"class":34,"line":108},[32,455,456],{"class":38},"    \u002F\u002F ✅ CORRECT: use `=` to modify the outer variable:\n",[32,458,459,462],{"class":34,"line":113},[32,460,461],{"class":38},"    \u002F\u002F x = 10",[32,463,464],{"class":38},"          \u002F\u002F assignment, not declaration — modifies outer x\n",[32,466,467],{"class":34,"line":119},[32,468,335],{"class":125},[32,470,471],{"class":34,"line":129},[32,472,94],{"emptyLinePlaceholder":93},[32,474,475],{"class":34,"line":156},[32,476,477],{"class":38},"\u002F\u002F ⚠️ The same trap in for-loops (pre-Go 1.22):\n",[32,479,480,482,485],{"class":34,"line":171},[32,481,211],{"class":100},[32,483,484],{"class":104}," loopShadowPre122",[32,486,217],{"class":125},[32,488,489,492,495,497],{"class":34,"line":197},[32,490,491],{"class":100},"    var",[32,493,494],{"class":125}," fns []",[32,496,211],{"class":100},[32,498,499],{"class":125},"()\n",[32,501,502,505,508,510,513,516,519,522,525,528],{"class":34,"line":203},[32,503,504],{"class":100},"    for",[32,506,507],{"class":125}," i ",[32,509,232],{"class":100},[32,511,512],{"class":187}," 0",[32,514,515],{"class":125},"; i ",[32,517,518],{"class":100},"\u003C",[32,520,521],{"class":187}," 3",[32,523,524],{"class":125},"; i",[32,526,527],{"class":100},"++",[32,529,275],{"class":125},[32,531,532,535,537,540,543,545,548,550,553],{"class":34,"line":208},[32,533,534],{"class":125},"        fns ",[32,536,135],{"class":100},[32,538,539],{"class":104}," append",[32,541,542],{"class":125},"(fns, ",[32,544,211],{"class":100},[32,546,547],{"class":125},"() { fmt.",[32,549,413],{"class":104},[32,551,552],{"class":125},"(i) })  ",[32,554,555],{"class":38},"\u002F\u002F captures the SAME i\n",[32,557,558],{"class":34,"line":220},[32,559,287],{"class":125},[32,561,562,564,567,569,572],{"class":34,"line":226},[32,563,504],{"class":100},[32,565,566],{"class":125}," _, f ",[32,568,232],{"class":100},[32,570,571],{"class":100}," range",[32,573,574],{"class":125}," fns {\n",[32,576,577,580,583],{"class":34,"line":238},[32,578,579],{"class":104},"        f",[32,581,582],{"class":125},"()  ",[32,584,585],{"class":38},"\u002F\u002F pre-1.22: prints 3 3 3 (all see final i=3)\n",[32,587,588],{"class":34,"line":260},[32,589,287],{"class":125},[32,591,592],{"class":34,"line":278},[32,593,335],{"class":125},[32,595,596],{"class":34,"line":284},[32,597,94],{"emptyLinePlaceholder":93},[32,599,600],{"class":34,"line":290},[32,601,602],{"class":38},"\u002F\u002F ✅ Fixed — pass as parameter (pre-1.22 pattern):\n",[32,604,605,607,610],{"class":34,"line":295},[32,606,211],{"class":100},[32,608,609],{"class":104}," loopShadowFixed",[32,611,217],{"class":125},[32,613,614,616,618,620],{"class":34,"line":301},[32,615,491],{"class":100},[32,617,494],{"class":125},[32,619,211],{"class":100},[32,621,499],{"class":125},[32,623,624,626,628,630,632,634,636,638,640,642],{"class":34,"line":321},[32,625,504],{"class":100},[32,627,507],{"class":125},[32,629,232],{"class":100},[32,631,512],{"class":187},[32,633,515],{"class":125},[32,635,518],{"class":100},[32,637,521],{"class":187},[32,639,524],{"class":125},[32,641,527],{"class":100},[32,643,275],{"class":125},[32,645,646,649,651,654],{"class":34,"line":332},[32,647,648],{"class":125},"        i ",[32,650,232],{"class":100},[32,652,653],{"class":125}," i  ",[32,655,656],{"class":38},"\u002F\u002F ⚠️ creates a new i per iteration (pre-1.22 idiom)\n",[32,658,660,662,664,666,668,670,672,674],{"class":34,"line":659},32,[32,661,534],{"class":125},[32,663,135],{"class":100},[32,665,539],{"class":104},[32,667,542],{"class":125},[32,669,211],{"class":100},[32,671,547],{"class":125},[32,673,413],{"class":104},[32,675,676],{"class":125},"(i) })\n",[32,678,680],{"class":34,"line":679},33,[32,681,287],{"class":125},[32,683,685],{"class":34,"line":684},34,[32,686,687],{"class":38},"    \u002F\u002F Go 1.22+ fixes this — loop vars are per-iteration by default.\n",[32,689,691],{"class":34,"line":690},35,[32,692,693],{"class":38},"    \u002F\u002F The `i := i` shadow is no longer needed (but doesn't hurt).\n",[32,695,697],{"class":34,"line":696},36,[32,698,335],{"class":125},[14,700,702],{"id":701},"zero-values-the-memory-story","Zero Values — The Memory Story",[19,704,705],{"language":21},[23,706,708],{"className":25,"code":707,"language":21,"meta":27,"style":27},"\u002F\u002F Every Go variable is initialized to its type's zero value.\n\u002F\u002F No \"uninitialized\" memory ever exists — this is a safety guarantee.\n\n\u002F\u002F ┌───────────────────────────────────────────────────────────────┐\n\u002F\u002F │ Type          │ Zero value    │ Memory representation         │\n\u002F\u002F │ ────────────  │ ────────────  │ ──────────────────────────── │\n\u002F\u002F │ int, uint     │ 0             │ all zero bytes (e.g., 8 bytes)│\n\u002F\u002F │ float64       │ 0.0           │ IEEE 754 all-zero = 0.0      │\n\u002F\u002F │ bool          │ false         │ 0 byte                        │\n\u002F\u002F │ string        │ \"\"            │ {ptr=nil, len=0} (16 bytes)   │\n\u002F\u002F │ pointer       │ nil           │ 0x0 (8 bytes)                 │\n\u002F\u002F │ slice         │ nil           │ {ptr=nil, len=0, cap=0} (24B)│\n\u002F\u002F │ map           │ nil           │ pointer to nil hmap (8 bytes) │\n\u002F\u002F │ chan          │ nil           │ pointer to nil hchan (8 bytes)│\n\u002F\u002F │ func          │ nil           │ pointer to nil (8 bytes)      │\n\u002F\u002F │ interface     │ nil           │ {type=nil, val=nil} (16 bytes)│\n\u002F\u002F │ struct        │ all-zero      │ each field at its zero value  │\n\u002F\u002F └───────────────────────────────────────────────────────────────┘\n\nfunc zeroValueDemo() {\n    var s []int\n    fmt.Println(s == nil)  \u002F\u002F true — nil slice (ptr is nil, len 0, cap 0)\n\n    t := make([]int, 0)    \u002F\u002F non-nil empty slice (ptr to real array, len 0, cap 0)\n    fmt.Println(t == nil)  \u002F\u002F false\n\n    \u002F\u002F Both have len=0 and range over them does nothing. BUT:\n    \u002F\u002F   json.Marshal(s) → \"null\"     (nil slice)\n    \u002F\u002F   json.Marshal(t) → \"[]\"       (empty slice)\n    \u002F\u002F API consumers treat null and [] differently — be deliberate.\n}\n",[29,709,710,715,720,724,729,734,739,744,749,754,759,764,769,774,779,784,789,794,799,803,812,822,841,845,870,888,892,897,902,907,912],{"__ignoreMap":27},[32,711,712],{"class":34,"line":35},[32,713,714],{"class":38},"\u002F\u002F Every Go variable is initialized to its type's zero value.\n",[32,716,717],{"class":34,"line":42},[32,718,719],{"class":38},"\u002F\u002F No \"uninitialized\" memory ever exists — this is a safety guarantee.\n",[32,721,722],{"class":34,"line":48},[32,723,94],{"emptyLinePlaceholder":93},[32,725,726],{"class":34,"line":54},[32,727,728],{"class":38},"\u002F\u002F ┌───────────────────────────────────────────────────────────────┐\n",[32,730,731],{"class":34,"line":60},[32,732,733],{"class":38},"\u002F\u002F │ Type          │ Zero value    │ Memory representation         │\n",[32,735,736],{"class":34,"line":66},[32,737,738],{"class":38},"\u002F\u002F │ ────────────  │ ────────────  │ ──────────────────────────── │\n",[32,740,741],{"class":34,"line":72},[32,742,743],{"class":38},"\u002F\u002F │ int, uint     │ 0             │ all zero bytes (e.g., 8 bytes)│\n",[32,745,746],{"class":34,"line":78},[32,747,748],{"class":38},"\u002F\u002F │ float64       │ 0.0           │ IEEE 754 all-zero = 0.0      │\n",[32,750,751],{"class":34,"line":84},[32,752,753],{"class":38},"\u002F\u002F │ bool          │ false         │ 0 byte                        │\n",[32,755,756],{"class":34,"line":90},[32,757,758],{"class":38},"\u002F\u002F │ string        │ \"\"            │ {ptr=nil, len=0} (16 bytes)   │\n",[32,760,761],{"class":34,"line":97},[32,762,763],{"class":38},"\u002F\u002F │ pointer       │ nil           │ 0x0 (8 bytes)                 │\n",[32,765,766],{"class":34,"line":108},[32,767,768],{"class":38},"\u002F\u002F │ slice         │ nil           │ {ptr=nil, len=0, cap=0} (24B)│\n",[32,770,771],{"class":34,"line":113},[32,772,773],{"class":38},"\u002F\u002F │ map           │ nil           │ pointer to nil hmap (8 bytes) │\n",[32,775,776],{"class":34,"line":119},[32,777,778],{"class":38},"\u002F\u002F │ chan          │ nil           │ pointer to nil hchan (8 bytes)│\n",[32,780,781],{"class":34,"line":129},[32,782,783],{"class":38},"\u002F\u002F │ func          │ nil           │ pointer to nil (8 bytes)      │\n",[32,785,786],{"class":34,"line":156},[32,787,788],{"class":38},"\u002F\u002F │ interface     │ nil           │ {type=nil, val=nil} (16 bytes)│\n",[32,790,791],{"class":34,"line":171},[32,792,793],{"class":38},"\u002F\u002F │ struct        │ all-zero      │ each field at its zero value  │\n",[32,795,796],{"class":34,"line":197},[32,797,798],{"class":38},"\u002F\u002F └───────────────────────────────────────────────────────────────┘\n",[32,800,801],{"class":34,"line":203},[32,802,94],{"emptyLinePlaceholder":93},[32,804,805,807,810],{"class":34,"line":208},[32,806,211],{"class":100},[32,808,809],{"class":104}," zeroValueDemo",[32,811,217],{"class":125},[32,813,814,816,819],{"class":34,"line":220},[32,815,491],{"class":100},[32,817,818],{"class":125}," s []",[32,820,821],{"class":100},"int\n",[32,823,824,826,828,831,834,836,838],{"class":34,"line":226},[32,825,428],{"class":125},[32,827,413],{"class":104},[32,829,830],{"class":125},"(s ",[32,832,833],{"class":100},"==",[32,835,272],{"class":187},[32,837,254],{"class":125},[32,839,840],{"class":38},"\u002F\u002F true — nil slice (ptr is nil, len 0, cap 0)\n",[32,842,843],{"class":34,"line":238},[32,844,94],{"emptyLinePlaceholder":93},[32,846,847,850,852,854,857,859,862,864,867],{"class":34,"line":260},[32,848,849],{"class":125},"    t ",[32,851,232],{"class":100},[32,853,138],{"class":104},[32,855,856],{"class":125},"([]",[32,858,362],{"class":100},[32,860,861],{"class":125},", ",[32,863,188],{"class":187},[32,865,866],{"class":125},")    ",[32,868,869],{"class":38},"\u002F\u002F non-nil empty slice (ptr to real array, len 0, cap 0)\n",[32,871,872,874,876,879,881,883,885],{"class":34,"line":278},[32,873,428],{"class":125},[32,875,413],{"class":104},[32,877,878],{"class":125},"(t ",[32,880,833],{"class":100},[32,882,272],{"class":187},[32,884,254],{"class":125},[32,886,887],{"class":38},"\u002F\u002F false\n",[32,889,890],{"class":34,"line":284},[32,891,94],{"emptyLinePlaceholder":93},[32,893,894],{"class":34,"line":290},[32,895,896],{"class":38},"    \u002F\u002F Both have len=0 and range over them does nothing. BUT:\n",[32,898,899],{"class":34,"line":295},[32,900,901],{"class":38},"    \u002F\u002F   json.Marshal(s) → \"null\"     (nil slice)\n",[32,903,904],{"class":34,"line":301},[32,905,906],{"class":38},"    \u002F\u002F   json.Marshal(t) → \"[]\"       (empty slice)\n",[32,908,909],{"class":34,"line":321},[32,910,911],{"class":38},"    \u002F\u002F API consumers treat null and [] differently — be deliberate.\n",[32,913,914],{"class":34,"line":332},[32,915,335],{"class":125},[337,917,919],{"id":918},"zero-value-struct-initialization","Zero-value struct initialization",[19,921,922],{"language":21},[23,923,925],{"className":25,"code":924,"language":21,"meta":27,"style":27},"type Server struct {\n    Addr    string\n    Port    int\n    TLS     *tls.Config  \u002F\u002F nil = no TLS (zero value is meaningful)\n    Timeout time.Duration\n}\n\nfunc zeroValueStruct() {\n    \u002F\u002F Zero-value initialization — all fields at their zero values.\n    \u002F\u002F Design structs so the zero value is usable (Go idiom).\n    var s Server\n    \u002F\u002F s.Addr = \"\", s.Port = 0, s.TLS = nil, s.Timeout = 0\n\n    \u002F\u002F `0` for Port is probably wrong — use a constructor:\n    srv := NewServer(\":8080\")\n    _ = srv\n}\n\n\u002F\u002F ✅ Idiom: make zero values useful, provide constructors for required fields.\nfunc NewServer(addr string) *Server {\n    return &Server{\n        Addr:    addr,\n        Port:    8080,           \u002F\u002F sensible default\n        Timeout: 30 * time.Second,\n    }\n}\n\n\u002F\u002F ❌ ANTI-PATTERN: struct with required fields and no constructor.\n\u002F\u002F   type Config struct { DSN string }  \u002F\u002F zero value has empty DSN → runtime panic\n\u002F\u002F   Users will write `var cfg Config` and forget DSN.\n",[29,926,927,939,947,954,974,987,991,995,1004,1009,1014,1024,1029,1033,1038,1055,1064,1068,1072,1077,1101,1113,1118,1132,1146,1150,1154,1158,1163,1171],{"__ignoreMap":27},[32,928,929,932,935,937],{"class":34,"line":35},[32,930,931],{"class":100},"type",[32,933,934],{"class":104}," Server",[32,936,147],{"class":100},[32,938,275],{"class":125},[32,940,941,944],{"class":34,"line":42},[32,942,943],{"class":125},"    Addr    ",[32,945,946],{"class":100},"string\n",[32,948,949,952],{"class":34,"line":48},[32,950,951],{"class":125},"    Port    ",[32,953,821],{"class":100},[32,955,956,959,962,965,968,971],{"class":34,"line":54},[32,957,958],{"class":125},"    TLS     ",[32,960,961],{"class":100},"*",[32,963,964],{"class":104},"tls",[32,966,967],{"class":125},".",[32,969,970],{"class":104},"Config",[32,972,973],{"class":38},"  \u002F\u002F nil = no TLS (zero value is meaningful)\n",[32,975,976,979,982,984],{"class":34,"line":60},[32,977,978],{"class":125},"    Timeout ",[32,980,981],{"class":104},"time",[32,983,967],{"class":125},[32,985,986],{"class":104},"Duration\n",[32,988,989],{"class":34,"line":66},[32,990,335],{"class":125},[32,992,993],{"class":34,"line":72},[32,994,94],{"emptyLinePlaceholder":93},[32,996,997,999,1002],{"class":34,"line":78},[32,998,211],{"class":100},[32,1000,1001],{"class":104}," zeroValueStruct",[32,1003,217],{"class":125},[32,1005,1006],{"class":34,"line":84},[32,1007,1008],{"class":38},"    \u002F\u002F Zero-value initialization — all fields at their zero values.\n",[32,1010,1011],{"class":34,"line":90},[32,1012,1013],{"class":38},"    \u002F\u002F Design structs so the zero value is usable (Go idiom).\n",[32,1015,1016,1018,1021],{"class":34,"line":97},[32,1017,491],{"class":100},[32,1019,1020],{"class":125}," s ",[32,1022,1023],{"class":104},"Server\n",[32,1025,1026],{"class":34,"line":108},[32,1027,1028],{"class":38},"    \u002F\u002F s.Addr = \"\", s.Port = 0, s.TLS = nil, s.Timeout = 0\n",[32,1030,1031],{"class":34,"line":113},[32,1032,94],{"emptyLinePlaceholder":93},[32,1034,1035],{"class":34,"line":119},[32,1036,1037],{"class":38},"    \u002F\u002F `0` for Port is probably wrong — use a constructor:\n",[32,1039,1040,1043,1045,1048,1050,1053],{"class":34,"line":129},[32,1041,1042],{"class":125},"    srv ",[32,1044,232],{"class":100},[32,1046,1047],{"class":104}," NewServer",[32,1049,141],{"class":125},[32,1051,1052],{"class":164},"\":8080\"",[32,1054,200],{"class":125},[32,1056,1057,1059,1061],{"class":34,"line":156},[32,1058,324],{"class":125},[32,1060,135],{"class":100},[32,1062,1063],{"class":125}," srv\n",[32,1065,1066],{"class":34,"line":171},[32,1067,335],{"class":125},[32,1069,1070],{"class":34,"line":197},[32,1071,94],{"emptyLinePlaceholder":93},[32,1073,1074],{"class":34,"line":203},[32,1075,1076],{"class":38},"\u002F\u002F ✅ Idiom: make zero values useful, provide constructors for required fields.\n",[32,1078,1079,1081,1083,1085,1089,1092,1094,1096,1099],{"class":34,"line":208},[32,1080,211],{"class":100},[32,1082,1047],{"class":104},[32,1084,141],{"class":125},[32,1086,1088],{"class":1087},"sCrzJ","addr",[32,1090,1091],{"class":100}," string",[32,1093,191],{"class":125},[32,1095,961],{"class":100},[32,1097,1098],{"class":104},"Server",[32,1100,275],{"class":125},[32,1102,1103,1105,1108,1110],{"class":34,"line":220},[32,1104,441],{"class":100},[32,1106,1107],{"class":100}," &",[32,1109,1098],{"class":104},[32,1111,1112],{"class":125},"{\n",[32,1114,1115],{"class":34,"line":226},[32,1116,1117],{"class":125},"        Addr:    addr,\n",[32,1119,1120,1123,1126,1129],{"class":34,"line":238},[32,1121,1122],{"class":125},"        Port:    ",[32,1124,1125],{"class":187},"8080",[32,1127,1128],{"class":125},",           ",[32,1130,1131],{"class":38},"\u002F\u002F sensible default\n",[32,1133,1134,1137,1140,1143],{"class":34,"line":260},[32,1135,1136],{"class":125},"        Timeout: ",[32,1138,1139],{"class":187},"30",[32,1141,1142],{"class":100}," *",[32,1144,1145],{"class":125}," time.Second,\n",[32,1147,1148],{"class":34,"line":278},[32,1149,287],{"class":125},[32,1151,1152],{"class":34,"line":284},[32,1153,335],{"class":125},[32,1155,1156],{"class":34,"line":290},[32,1157,94],{"emptyLinePlaceholder":93},[32,1159,1160],{"class":34,"line":295},[32,1161,1162],{"class":38},"\u002F\u002F ❌ ANTI-PATTERN: struct with required fields and no constructor.\n",[32,1164,1165,1168],{"class":34,"line":301},[32,1166,1167],{"class":38},"\u002F\u002F   type Config struct { DSN string }",[32,1169,1170],{"class":38},"  \u002F\u002F zero value has empty DSN → runtime panic\n",[32,1172,1173],{"class":34,"line":321},[32,1174,1175],{"class":38},"\u002F\u002F   Users will write `var cfg Config` and forget DSN.\n",[14,1177,1179],{"id":1178},"constants-compile-time-immutability","Constants — Compile-Time Immutability",[19,1181,1182],{"language":21},[23,1183,1185],{"className":25,"code":1184,"language":21,"meta":27,"style":27},"\u002F\u002F Constants are evaluated at compile time. They CANNOT be:\n\u002F\u002F   - mutated at runtime\n\u002F\u002F   - of types that require runtime computation (slices, maps, structs)\n\u002F\u002F   - declared with function calls (unless the function is constant)\n\nconst (\n    Pi       = 3.14159265358979323846264338327950288  \u002F\u002F arbitrary precision\n    MaxInt32 = 1 \u003C\u003C 31 - 1                              \u002F\u002F compile-time arithmetic\n    DefaultPort = 8080\n)\n\n\u002F\u002F Typed vs untyped:\nconst (\n    TimeoutSeconds int = 30          \u002F\u002F typed: must convert to use as int64\n    TimeoutGeneric   = 30            \u002F\u002F untyped: adapts to any numeric context\n)\n\nfunc constantTypes() {\n    \u002F\u002F Untyped constant adapts:\n    var i int = TimeoutGeneric        \u002F\u002F ok — becomes int\n    var i64 int64 = TimeoutGeneric    \u002F\u002F ok — becomes int64\n    var f float64 = TimeoutGeneric    \u002F\u002F ok — becomes float64\n    _ = i; _ = i64; _ = f\n\n    \u002F\u002F Typed constant requires explicit conversion:\n    var i2 int64 = int64(TimeoutSeconds)  \u002F\u002F ok — explicit conversion\n    \u002F\u002F var i3 int64 = TimeoutSeconds       \u002F\u002F ❌ compile error: int ≠ int64\n    _ = i2\n}\n",[29,1186,1187,1192,1197,1202,1207,1211,1218,1232,1257,1266,1270,1274,1279,1285,1301,1314,1318,1322,1331,1336,1352,1370,1387,1406,1410,1415,1435,1443,1452],{"__ignoreMap":27},[32,1188,1189],{"class":34,"line":35},[32,1190,1191],{"class":38},"\u002F\u002F Constants are evaluated at compile time. They CANNOT be:\n",[32,1193,1194],{"class":34,"line":42},[32,1195,1196],{"class":38},"\u002F\u002F   - mutated at runtime\n",[32,1198,1199],{"class":34,"line":48},[32,1200,1201],{"class":38},"\u002F\u002F   - of types that require runtime computation (slices, maps, structs)\n",[32,1203,1204],{"class":34,"line":54},[32,1205,1206],{"class":38},"\u002F\u002F   - declared with function calls (unless the function is constant)\n",[32,1208,1209],{"class":34,"line":60},[32,1210,94],{"emptyLinePlaceholder":93},[32,1212,1213,1216],{"class":34,"line":66},[32,1214,1215],{"class":100},"const",[32,1217,126],{"class":125},[32,1219,1220,1223,1226,1229],{"class":34,"line":72},[32,1221,1222],{"class":187},"    Pi",[32,1224,1225],{"class":100},"       =",[32,1227,1228],{"class":187}," 3.14159265358979323846264338327950288",[32,1230,1231],{"class":38},"  \u002F\u002F arbitrary precision\n",[32,1233,1234,1237,1240,1243,1246,1249,1252,1254],{"class":34,"line":78},[32,1235,1236],{"class":187},"    MaxInt32",[32,1238,1239],{"class":100}," =",[32,1241,1242],{"class":187}," 1",[32,1244,1245],{"class":100}," \u003C\u003C",[32,1247,1248],{"class":187}," 31",[32,1250,1251],{"class":100}," -",[32,1253,1242],{"class":187},[32,1255,1256],{"class":38},"                              \u002F\u002F compile-time arithmetic\n",[32,1258,1259,1262,1264],{"class":34,"line":84},[32,1260,1261],{"class":187},"    DefaultPort",[32,1263,1239],{"class":100},[32,1265,235],{"class":187},[32,1267,1268],{"class":34,"line":90},[32,1269,200],{"class":125},[32,1271,1272],{"class":34,"line":97},[32,1273,94],{"emptyLinePlaceholder":93},[32,1275,1276],{"class":34,"line":108},[32,1277,1278],{"class":38},"\u002F\u002F Typed vs untyped:\n",[32,1280,1281,1283],{"class":34,"line":113},[32,1282,1215],{"class":100},[32,1284,126],{"class":125},[32,1286,1287,1290,1293,1295,1298],{"class":34,"line":119},[32,1288,1289],{"class":187},"    TimeoutSeconds",[32,1291,1292],{"class":100}," int",[32,1294,1239],{"class":100},[32,1296,1297],{"class":187}," 30",[32,1299,1300],{"class":38},"          \u002F\u002F typed: must convert to use as int64\n",[32,1302,1303,1306,1309,1311],{"class":34,"line":129},[32,1304,1305],{"class":187},"    TimeoutGeneric",[32,1307,1308],{"class":100},"   =",[32,1310,1297],{"class":187},[32,1312,1313],{"class":38},"            \u002F\u002F untyped: adapts to any numeric context\n",[32,1315,1316],{"class":34,"line":156},[32,1317,200],{"class":125},[32,1319,1320],{"class":34,"line":171},[32,1321,94],{"emptyLinePlaceholder":93},[32,1323,1324,1326,1329],{"class":34,"line":197},[32,1325,211],{"class":100},[32,1327,1328],{"class":104}," constantTypes",[32,1330,217],{"class":125},[32,1332,1333],{"class":34,"line":203},[32,1334,1335],{"class":38},"    \u002F\u002F Untyped constant adapts:\n",[32,1337,1338,1340,1342,1344,1346,1349],{"class":34,"line":208},[32,1339,491],{"class":100},[32,1341,507],{"class":125},[32,1343,362],{"class":100},[32,1345,1239],{"class":100},[32,1347,1348],{"class":125}," TimeoutGeneric        ",[32,1350,1351],{"class":38},"\u002F\u002F ok — becomes int\n",[32,1353,1354,1356,1359,1362,1364,1367],{"class":34,"line":220},[32,1355,491],{"class":100},[32,1357,1358],{"class":125}," i64 ",[32,1360,1361],{"class":100},"int64",[32,1363,1239],{"class":100},[32,1365,1366],{"class":125}," TimeoutGeneric    ",[32,1368,1369],{"class":38},"\u002F\u002F ok — becomes int64\n",[32,1371,1372,1374,1377,1380,1382,1384],{"class":34,"line":226},[32,1373,491],{"class":100},[32,1375,1376],{"class":125}," f ",[32,1378,1379],{"class":100},"float64",[32,1381,1239],{"class":100},[32,1383,1366],{"class":125},[32,1385,1386],{"class":38},"\u002F\u002F ok — becomes float64\n",[32,1388,1389,1391,1393,1396,1398,1401,1403],{"class":34,"line":238},[32,1390,324],{"class":125},[32,1392,135],{"class":100},[32,1394,1395],{"class":125}," i; _ ",[32,1397,135],{"class":100},[32,1399,1400],{"class":125}," i64; _ ",[32,1402,135],{"class":100},[32,1404,1405],{"class":125}," f\n",[32,1407,1408],{"class":34,"line":260},[32,1409,94],{"emptyLinePlaceholder":93},[32,1411,1412],{"class":34,"line":278},[32,1413,1414],{"class":38},"    \u002F\u002F Typed constant requires explicit conversion:\n",[32,1416,1417,1419,1422,1424,1426,1429,1432],{"class":34,"line":284},[32,1418,491],{"class":100},[32,1420,1421],{"class":125}," i2 ",[32,1423,1361],{"class":100},[32,1425,1239],{"class":100},[32,1427,1428],{"class":100}," int64",[32,1430,1431],{"class":125},"(TimeoutSeconds)  ",[32,1433,1434],{"class":38},"\u002F\u002F ok — explicit conversion\n",[32,1436,1437,1440],{"class":34,"line":290},[32,1438,1439],{"class":38},"    \u002F\u002F var i3 int64 = TimeoutSeconds",[32,1441,1442],{"class":38},"       \u002F\u002F ❌ compile error: int ≠ int64\n",[32,1444,1445,1447,1449],{"class":34,"line":295},[32,1446,324],{"class":125},[32,1448,135],{"class":100},[32,1450,1451],{"class":125}," i2\n",[32,1453,1454],{"class":34,"line":301},[32,1455,335],{"class":125},[337,1457,1459],{"id":1458},"untyped-constant-precision-the-power-and-the-trap","Untyped constant precision — the power and the trap",[19,1461,1462],{"language":21},[23,1463,1465],{"className":25,"code":1464,"language":21,"meta":27,"style":27},"\u002F\u002F Untyped constants have ARBITRARY precision (they're big.Int at compile time).\n\u002F\u002F This lets you express values that don't fit in any runtime type:\n\nconst (\n    Big = 1 \u003C\u003C 100             \u002F\u002F 2^100 — way bigger than int64 (2^63-1)\n    Small = Big >> 99          \u002F\u002F 2^1 = 2 — works because Big is untyped\n)\n\nfunc bigConstants() {\n    \u002F\u002F The constant itself is fine (compile-time):\n    fmt.Println(Small)         \u002F\u002F 2\n\n    \u002F\u002F But assigning to a runtime type fails if it doesn't fit:\n    \u002F\u002F var x int = Big          \u002F\u002F ❌ compile error: constant overflows int\n    var x int = Small           \u002F\u002F ok — 2 fits in int\n    _ = x\n\n    \u002F\u002F ⚠️ Float constant precision trap:\n    const Almost = 0.1 + 0.2   \u002F\u002F 0.3 exactly (arbitrary precision at compile time)\n    var f float64 = 0.1 + 0.2  \u002F\u002F 0.30000000000000004 (float64 arithmetic at runtime)\n    fmt.Println(Almost == 0.3) \u002F\u002F true (compile-time, untyped)\n    fmt.Println(f == 0.3)      \u002F\u002F false (runtime float64)\n}\n",[29,1466,1467,1472,1477,1481,1487,1504,1523,1527,1531,1540,1545,1557,1561,1566,1574,1591,1600,1604,1609,1631,1650,1669,1688],{"__ignoreMap":27},[32,1468,1469],{"class":34,"line":35},[32,1470,1471],{"class":38},"\u002F\u002F Untyped constants have ARBITRARY precision (they're big.Int at compile time).\n",[32,1473,1474],{"class":34,"line":42},[32,1475,1476],{"class":38},"\u002F\u002F This lets you express values that don't fit in any runtime type:\n",[32,1478,1479],{"class":34,"line":48},[32,1480,94],{"emptyLinePlaceholder":93},[32,1482,1483,1485],{"class":34,"line":54},[32,1484,1215],{"class":100},[32,1486,126],{"class":125},[32,1488,1489,1492,1494,1496,1498,1501],{"class":34,"line":60},[32,1490,1491],{"class":187},"    Big",[32,1493,1239],{"class":100},[32,1495,1242],{"class":187},[32,1497,1245],{"class":100},[32,1499,1500],{"class":187}," 100",[32,1502,1503],{"class":38},"             \u002F\u002F 2^100 — way bigger than int64 (2^63-1)\n",[32,1505,1506,1509,1511,1514,1517,1520],{"class":34,"line":66},[32,1507,1508],{"class":187},"    Small",[32,1510,1239],{"class":100},[32,1512,1513],{"class":125}," Big ",[32,1515,1516],{"class":100},">>",[32,1518,1519],{"class":187}," 99",[32,1521,1522],{"class":38},"          \u002F\u002F 2^1 = 2 — works because Big is untyped\n",[32,1524,1525],{"class":34,"line":72},[32,1526,200],{"class":125},[32,1528,1529],{"class":34,"line":78},[32,1530,94],{"emptyLinePlaceholder":93},[32,1532,1533,1535,1538],{"class":34,"line":84},[32,1534,211],{"class":100},[32,1536,1537],{"class":104}," bigConstants",[32,1539,217],{"class":125},[32,1541,1542],{"class":34,"line":90},[32,1543,1544],{"class":38},"    \u002F\u002F The constant itself is fine (compile-time):\n",[32,1546,1547,1549,1551,1554],{"class":34,"line":97},[32,1548,428],{"class":125},[32,1550,413],{"class":104},[32,1552,1553],{"class":125},"(Small)         ",[32,1555,1556],{"class":38},"\u002F\u002F 2\n",[32,1558,1559],{"class":34,"line":108},[32,1560,94],{"emptyLinePlaceholder":93},[32,1562,1563],{"class":34,"line":113},[32,1564,1565],{"class":38},"    \u002F\u002F But assigning to a runtime type fails if it doesn't fit:\n",[32,1567,1568,1571],{"class":34,"line":119},[32,1569,1570],{"class":38},"    \u002F\u002F var x int = Big",[32,1572,1573],{"class":38},"          \u002F\u002F ❌ compile error: constant overflows int\n",[32,1575,1576,1578,1581,1583,1585,1588],{"class":34,"line":129},[32,1577,491],{"class":100},[32,1579,1580],{"class":125}," x ",[32,1582,362],{"class":100},[32,1584,1239],{"class":100},[32,1586,1587],{"class":125}," Small           ",[32,1589,1590],{"class":38},"\u002F\u002F ok — 2 fits in int\n",[32,1592,1593,1595,1597],{"class":34,"line":156},[32,1594,324],{"class":125},[32,1596,135],{"class":100},[32,1598,1599],{"class":125}," x\n",[32,1601,1602],{"class":34,"line":171},[32,1603,94],{"emptyLinePlaceholder":93},[32,1605,1606],{"class":34,"line":197},[32,1607,1608],{"class":38},"    \u002F\u002F ⚠️ Float constant precision trap:\n",[32,1610,1611,1614,1617,1619,1622,1625,1628],{"class":34,"line":203},[32,1612,1613],{"class":100},"    const",[32,1615,1616],{"class":187}," Almost",[32,1618,1239],{"class":100},[32,1620,1621],{"class":187}," 0.1",[32,1623,1624],{"class":100}," +",[32,1626,1627],{"class":187}," 0.2",[32,1629,1630],{"class":38},"   \u002F\u002F 0.3 exactly (arbitrary precision at compile time)\n",[32,1632,1633,1635,1637,1639,1641,1643,1645,1647],{"class":34,"line":208},[32,1634,491],{"class":100},[32,1636,1376],{"class":125},[32,1638,1379],{"class":100},[32,1640,1239],{"class":100},[32,1642,1621],{"class":187},[32,1644,1624],{"class":100},[32,1646,1627],{"class":187},[32,1648,1649],{"class":38},"  \u002F\u002F 0.30000000000000004 (float64 arithmetic at runtime)\n",[32,1651,1652,1654,1656,1659,1661,1664,1666],{"class":34,"line":220},[32,1653,428],{"class":125},[32,1655,413],{"class":104},[32,1657,1658],{"class":125},"(Almost ",[32,1660,833],{"class":100},[32,1662,1663],{"class":187}," 0.3",[32,1665,191],{"class":125},[32,1667,1668],{"class":38},"\u002F\u002F true (compile-time, untyped)\n",[32,1670,1671,1673,1675,1678,1680,1682,1685],{"class":34,"line":226},[32,1672,428],{"class":125},[32,1674,413],{"class":104},[32,1676,1677],{"class":125},"(f ",[32,1679,833],{"class":100},[32,1681,1663],{"class":187},[32,1683,1684],{"class":125},")      ",[32,1686,1687],{"class":38},"\u002F\u002F false (runtime float64)\n",[32,1689,1690],{"class":34,"line":238},[32,1691,335],{"class":125},[14,1693,1695,1698],{"id":1694},"iota-beyond-simple-enums",[29,1696,1697],{},"iota"," — Beyond Simple Enums",[19,1700,1701],{"language":21},[23,1702,1704],{"className":25,"code":1703,"language":21,"meta":27,"style":27},"\u002F\u002F iota resets to 0 in each const block and increments per LINE (not per use).\n\n\u002F\u002F --- Basic enum ---\ntype Weekday int\nconst (\n    Sunday Weekday = iota    \u002F\u002F 0\n    Monday                   \u002F\u002F 1\n    Tuesday                  \u002F\u002F 2\n    Wednesday                \u002F\u002F 3\n    Thursday                 \u002F\u002F 4\n    Friday                   \u002F\u002F 5\n    Saturday                 \u002F\u002F 6\n)\n\n\u002F\u002F --- Bit flags (permissions) ---\ntype Permission uint8\nconst (\n    Read    Permission = 1 \u003C\u003C iota    \u002F\u002F 1  (00000001)\n    Write                              \u002F\u002F 2  (00000010)\n    Execute                            \u002F\u002F 4  (00000100)\n    Delete                             \u002F\u002F 8  (00001000)\n    Admin    = Read | Write | Execute | Delete  \u002F\u002F 15 — manual composition\n)\n\nfunc checkPerm(p, required Permission) bool {\n    return p&required == required  \u002F\u002F all bits must be set\n}\n\n\u002F\u002F --- Skipping with _ (file sizes) ---\nconst (\n    _  = iota             \u002F\u002F 0 — ignored (we don't need a \"Byte\" unit)\n    KB = 1 \u003C\u003C (10 * iota) \u002F\u002F 1 \u003C\u003C 10 = 1024\n    MB                     \u002F\u002F 1 \u003C\u003C 20\n    GB                     \u002F\u002F 1 \u003C\u003C 30\n    TB                     \u002F\u002F 1 \u003C\u003C 40\n    PB                     \u002F\u002F 1 \u003C\u003C 50\n)\n\n\u002F\u002F --- iota in expressions (state machine states) ---\ntype State int\nconst (\n    StateIdle State = iota     \u002F\u002F 0\n    StateConnecting            \u002F\u002F 1\n    StateConnected             \u002F\u002F 2\n    StateDisconnecting         \u002F\u002F 3\n    StateError    = -1         \u002F\u002F explicit value, iota continues below\n)\n\n\u002F\u002F --- iota for array index alignment ---\nconst (\n    ColorRed = iota\n    ColorGreen\n    ColorBlue\n    ColorCount  \u002F\u002F 3 — use as array size: [ColorCount]string\n)\nvar colorNames = [ColorCount]string{\"red\", \"green\", \"blue\"}\n",[29,1705,1706,1711,1715,1720,1730,1736,1751,1759,1767,1775,1783,1791,1799,1803,1807,1812,1822,1828,1847,1855,1863,1871,1901,1905,1909,1935,1956,1960,1964,1969,1975,1988,2014,2022,2030,2038,2046,2051,2056,2062,2072,2079,2094,2103,2112,2121,2137,2142,2147,2153,2160,2171,2177,2183,2192,2197],{"__ignoreMap":27},[32,1707,1708],{"class":34,"line":35},[32,1709,1710],{"class":38},"\u002F\u002F iota resets to 0 in each const block and increments per LINE (not per use).\n",[32,1712,1713],{"class":34,"line":42},[32,1714,94],{"emptyLinePlaceholder":93},[32,1716,1717],{"class":34,"line":48},[32,1718,1719],{"class":38},"\u002F\u002F --- Basic enum ---\n",[32,1721,1722,1724,1727],{"class":34,"line":54},[32,1723,931],{"class":100},[32,1725,1726],{"class":104}," Weekday",[32,1728,1729],{"class":100}," int\n",[32,1731,1732,1734],{"class":34,"line":60},[32,1733,1215],{"class":100},[32,1735,126],{"class":125},[32,1737,1738,1741,1743,1745,1748],{"class":34,"line":66},[32,1739,1740],{"class":187},"    Sunday",[32,1742,1726],{"class":104},[32,1744,1239],{"class":100},[32,1746,1747],{"class":187}," iota",[32,1749,1750],{"class":38},"    \u002F\u002F 0\n",[32,1752,1753,1756],{"class":34,"line":72},[32,1754,1755],{"class":187},"    Monday",[32,1757,1758],{"class":38},"                   \u002F\u002F 1\n",[32,1760,1761,1764],{"class":34,"line":78},[32,1762,1763],{"class":187},"    Tuesday",[32,1765,1766],{"class":38},"                  \u002F\u002F 2\n",[32,1768,1769,1772],{"class":34,"line":84},[32,1770,1771],{"class":187},"    Wednesday",[32,1773,1774],{"class":38},"                \u002F\u002F 3\n",[32,1776,1777,1780],{"class":34,"line":90},[32,1778,1779],{"class":187},"    Thursday",[32,1781,1782],{"class":38},"                 \u002F\u002F 4\n",[32,1784,1785,1788],{"class":34,"line":97},[32,1786,1787],{"class":187},"    Friday",[32,1789,1790],{"class":38},"                   \u002F\u002F 5\n",[32,1792,1793,1796],{"class":34,"line":108},[32,1794,1795],{"class":187},"    Saturday",[32,1797,1798],{"class":38},"                 \u002F\u002F 6\n",[32,1800,1801],{"class":34,"line":113},[32,1802,200],{"class":125},[32,1804,1805],{"class":34,"line":119},[32,1806,94],{"emptyLinePlaceholder":93},[32,1808,1809],{"class":34,"line":129},[32,1810,1811],{"class":38},"\u002F\u002F --- Bit flags (permissions) ---\n",[32,1813,1814,1816,1819],{"class":34,"line":156},[32,1815,931],{"class":100},[32,1817,1818],{"class":104}," Permission",[32,1820,1821],{"class":100}," uint8\n",[32,1823,1824,1826],{"class":34,"line":171},[32,1825,1215],{"class":100},[32,1827,126],{"class":125},[32,1829,1830,1833,1836,1838,1840,1842,1844],{"class":34,"line":197},[32,1831,1832],{"class":187},"    Read",[32,1834,1835],{"class":104},"    Permission",[32,1837,1239],{"class":100},[32,1839,1242],{"class":187},[32,1841,1245],{"class":100},[32,1843,1747],{"class":187},[32,1845,1846],{"class":38},"    \u002F\u002F 1  (00000001)\n",[32,1848,1849,1852],{"class":34,"line":203},[32,1850,1851],{"class":187},"    Write",[32,1853,1854],{"class":38},"                              \u002F\u002F 2  (00000010)\n",[32,1856,1857,1860],{"class":34,"line":208},[32,1858,1859],{"class":187},"    Execute",[32,1861,1862],{"class":38},"                            \u002F\u002F 4  (00000100)\n",[32,1864,1865,1868],{"class":34,"line":220},[32,1866,1867],{"class":187},"    Delete",[32,1869,1870],{"class":38},"                             \u002F\u002F 8  (00001000)\n",[32,1872,1873,1876,1879,1882,1885,1888,1890,1893,1895,1898],{"class":34,"line":226},[32,1874,1875],{"class":187},"    Admin",[32,1877,1878],{"class":100},"    =",[32,1880,1881],{"class":125}," Read ",[32,1883,1884],{"class":100},"|",[32,1886,1887],{"class":125}," Write ",[32,1889,1884],{"class":100},[32,1891,1892],{"class":125}," Execute ",[32,1894,1884],{"class":100},[32,1896,1897],{"class":125}," Delete  ",[32,1899,1900],{"class":38},"\u002F\u002F 15 — manual composition\n",[32,1902,1903],{"class":34,"line":238},[32,1904,200],{"class":125},[32,1906,1907],{"class":34,"line":260},[32,1908,94],{"emptyLinePlaceholder":93},[32,1910,1911,1913,1916,1918,1921,1923,1926,1928,1930,1933],{"class":34,"line":278},[32,1912,211],{"class":100},[32,1914,1915],{"class":104}," checkPerm",[32,1917,141],{"class":125},[32,1919,1920],{"class":1087},"p",[32,1922,861],{"class":125},[32,1924,1925],{"class":1087},"required",[32,1927,1818],{"class":104},[32,1929,191],{"class":125},[32,1931,1932],{"class":100},"bool",[32,1934,275],{"class":125},[32,1936,1937,1939,1942,1945,1948,1950,1953],{"class":34,"line":284},[32,1938,441],{"class":100},[32,1940,1941],{"class":125}," p",[32,1943,1944],{"class":100},"&",[32,1946,1947],{"class":125},"required ",[32,1949,833],{"class":100},[32,1951,1952],{"class":125}," required  ",[32,1954,1955],{"class":38},"\u002F\u002F all bits must be set\n",[32,1957,1958],{"class":34,"line":290},[32,1959,335],{"class":125},[32,1961,1962],{"class":34,"line":295},[32,1963,94],{"emptyLinePlaceholder":93},[32,1965,1966],{"class":34,"line":301},[32,1967,1968],{"class":38},"\u002F\u002F --- Skipping with _ (file sizes) ---\n",[32,1970,1971,1973],{"class":34,"line":321},[32,1972,1215],{"class":100},[32,1974,126],{"class":125},[32,1976,1977,1980,1983,1985],{"class":34,"line":332},[32,1978,1979],{"class":187},"    _",[32,1981,1982],{"class":100},"  =",[32,1984,1747],{"class":187},[32,1986,1987],{"class":38},"             \u002F\u002F 0 — ignored (we don't need a \"Byte\" unit)\n",[32,1989,1990,1993,1995,1997,1999,2002,2005,2007,2009,2011],{"class":34,"line":659},[32,1991,1992],{"class":187},"    KB",[32,1994,1239],{"class":100},[32,1996,1242],{"class":187},[32,1998,1245],{"class":100},[32,2000,2001],{"class":125}," (",[32,2003,2004],{"class":187},"10",[32,2006,1142],{"class":100},[32,2008,1747],{"class":187},[32,2010,191],{"class":125},[32,2012,2013],{"class":38},"\u002F\u002F 1 \u003C\u003C 10 = 1024\n",[32,2015,2016,2019],{"class":34,"line":679},[32,2017,2018],{"class":187},"    MB",[32,2020,2021],{"class":38},"                     \u002F\u002F 1 \u003C\u003C 20\n",[32,2023,2024,2027],{"class":34,"line":684},[32,2025,2026],{"class":187},"    GB",[32,2028,2029],{"class":38},"                     \u002F\u002F 1 \u003C\u003C 30\n",[32,2031,2032,2035],{"class":34,"line":690},[32,2033,2034],{"class":187},"    TB",[32,2036,2037],{"class":38},"                     \u002F\u002F 1 \u003C\u003C 40\n",[32,2039,2040,2043],{"class":34,"line":696},[32,2041,2042],{"class":187},"    PB",[32,2044,2045],{"class":38},"                     \u002F\u002F 1 \u003C\u003C 50\n",[32,2047,2049],{"class":34,"line":2048},37,[32,2050,200],{"class":125},[32,2052,2054],{"class":34,"line":2053},38,[32,2055,94],{"emptyLinePlaceholder":93},[32,2057,2059],{"class":34,"line":2058},39,[32,2060,2061],{"class":38},"\u002F\u002F --- iota in expressions (state machine states) ---\n",[32,2063,2065,2067,2070],{"class":34,"line":2064},40,[32,2066,931],{"class":100},[32,2068,2069],{"class":104}," State",[32,2071,1729],{"class":100},[32,2073,2075,2077],{"class":34,"line":2074},41,[32,2076,1215],{"class":100},[32,2078,126],{"class":125},[32,2080,2082,2085,2087,2089,2091],{"class":34,"line":2081},42,[32,2083,2084],{"class":187},"    StateIdle",[32,2086,2069],{"class":104},[32,2088,1239],{"class":100},[32,2090,1747],{"class":187},[32,2092,2093],{"class":38},"     \u002F\u002F 0\n",[32,2095,2097,2100],{"class":34,"line":2096},43,[32,2098,2099],{"class":187},"    StateConnecting",[32,2101,2102],{"class":38},"            \u002F\u002F 1\n",[32,2104,2106,2109],{"class":34,"line":2105},44,[32,2107,2108],{"class":187},"    StateConnected",[32,2110,2111],{"class":38},"             \u002F\u002F 2\n",[32,2113,2115,2118],{"class":34,"line":2114},45,[32,2116,2117],{"class":187},"    StateDisconnecting",[32,2119,2120],{"class":38},"         \u002F\u002F 3\n",[32,2122,2124,2127,2129,2131,2134],{"class":34,"line":2123},46,[32,2125,2126],{"class":187},"    StateError",[32,2128,1878],{"class":100},[32,2130,1251],{"class":100},[32,2132,2133],{"class":187},"1",[32,2135,2136],{"class":38},"         \u002F\u002F explicit value, iota continues below\n",[32,2138,2140],{"class":34,"line":2139},47,[32,2141,200],{"class":125},[32,2143,2145],{"class":34,"line":2144},48,[32,2146,94],{"emptyLinePlaceholder":93},[32,2148,2150],{"class":34,"line":2149},49,[32,2151,2152],{"class":38},"\u002F\u002F --- iota for array index alignment ---\n",[32,2154,2156,2158],{"class":34,"line":2155},50,[32,2157,1215],{"class":100},[32,2159,126],{"class":125},[32,2161,2163,2166,2168],{"class":34,"line":2162},51,[32,2164,2165],{"class":187},"    ColorRed",[32,2167,1239],{"class":100},[32,2169,2170],{"class":187}," iota\n",[32,2172,2174],{"class":34,"line":2173},52,[32,2175,2176],{"class":187},"    ColorGreen\n",[32,2178,2180],{"class":34,"line":2179},53,[32,2181,2182],{"class":187},"    ColorBlue\n",[32,2184,2186,2189],{"class":34,"line":2185},54,[32,2187,2188],{"class":187},"    ColorCount",[32,2190,2191],{"class":38},"  \u002F\u002F 3 — use as array size: [ColorCount]string\n",[32,2193,2195],{"class":34,"line":2194},55,[32,2196,200],{"class":125},[32,2198,2200,2202,2205,2207,2210,2213,2216,2219,2221,2224,2226,2229],{"class":34,"line":2199},56,[32,2201,122],{"class":100},[32,2203,2204],{"class":125}," colorNames ",[32,2206,135],{"class":100},[32,2208,2209],{"class":125}," [ColorCount]",[32,2211,2212],{"class":100},"string",[32,2214,2215],{"class":125},"{",[32,2217,2218],{"class":164},"\"red\"",[32,2220,861],{"class":125},[32,2222,2223],{"class":164},"\"green\"",[32,2225,861],{"class":125},[32,2227,2228],{"class":164},"\"blue\"",[32,2230,335],{"class":125},[337,2232,2234,2235,2238],{"id":2233},"adding-string-to-enums","Adding ",[29,2236,2237],{},"String()"," to enums",[19,2240,2241],{"language":21},[23,2242,2244],{"className":25,"code":2243,"language":21,"meta":27,"style":27},"\u002F\u002F Go has no built-in enum string representation. Use `stringer` or manual.\n\n\u002F\u002F Manual approach — explicit, no code generation:\ntype State int\nconst (\n    StateIdle State = iota\n    StateConnecting\n    StateConnected\n)\nvar stateNames = [...]string{\"idle\", \"connecting\", \"connected\"}\nfunc (s State) String() string {\n    if s \u003C 0 || int(s) >= len(stateNames) {\n        return fmt.Sprintf(\"State(%d)\", s)\n    }\n    return stateNames[s]\n}\n\n\u002F\u002F `go generate` + `stringer` tool approach:\n\u002F\u002Fgo:generate stringer -type=State -output=state_string.go\n\u002F\u002F Produces a fast String() method — recommended for large enums.\n",[29,2245,2246,2251,2255,2260,2268,2274,2284,2289,2294,2298,2335,2358,2385,2410,2414,2421,2425,2429,2434,2439],{"__ignoreMap":27},[32,2247,2248],{"class":34,"line":35},[32,2249,2250],{"class":38},"\u002F\u002F Go has no built-in enum string representation. Use `stringer` or manual.\n",[32,2252,2253],{"class":34,"line":42},[32,2254,94],{"emptyLinePlaceholder":93},[32,2256,2257],{"class":34,"line":48},[32,2258,2259],{"class":38},"\u002F\u002F Manual approach — explicit, no code generation:\n",[32,2261,2262,2264,2266],{"class":34,"line":54},[32,2263,931],{"class":100},[32,2265,2069],{"class":104},[32,2267,1729],{"class":100},[32,2269,2270,2272],{"class":34,"line":60},[32,2271,1215],{"class":100},[32,2273,126],{"class":125},[32,2275,2276,2278,2280,2282],{"class":34,"line":66},[32,2277,2084],{"class":187},[32,2279,2069],{"class":104},[32,2281,1239],{"class":100},[32,2283,2170],{"class":187},[32,2285,2286],{"class":34,"line":72},[32,2287,2288],{"class":187},"    StateConnecting\n",[32,2290,2291],{"class":34,"line":78},[32,2292,2293],{"class":187},"    StateConnected\n",[32,2295,2296],{"class":34,"line":84},[32,2297,200],{"class":125},[32,2299,2300,2302,2305,2307,2310,2313,2316,2318,2320,2323,2325,2328,2330,2333],{"class":34,"line":90},[32,2301,122],{"class":100},[32,2303,2304],{"class":125}," stateNames ",[32,2306,135],{"class":100},[32,2308,2309],{"class":125}," [",[32,2311,2312],{"class":100},"...",[32,2314,2315],{"class":125},"]",[32,2317,2212],{"class":100},[32,2319,2215],{"class":125},[32,2321,2322],{"class":164},"\"idle\"",[32,2324,861],{"class":125},[32,2326,2327],{"class":164},"\"connecting\"",[32,2329,861],{"class":125},[32,2331,2332],{"class":164},"\"connected\"",[32,2334,335],{"class":125},[32,2336,2337,2339,2341,2344,2347,2349,2352,2354,2356],{"class":34,"line":97},[32,2338,211],{"class":100},[32,2340,2001],{"class":125},[32,2342,2343],{"class":1087},"s ",[32,2345,2346],{"class":104},"State",[32,2348,191],{"class":125},[32,2350,2351],{"class":104},"String",[32,2353,359],{"class":125},[32,2355,2212],{"class":100},[32,2357,275],{"class":125},[32,2359,2360,2362,2364,2366,2368,2371,2373,2376,2379,2382],{"class":34,"line":108},[32,2361,263],{"class":100},[32,2363,1020],{"class":125},[32,2365,518],{"class":100},[32,2367,512],{"class":187},[32,2369,2370],{"class":100}," ||",[32,2372,1292],{"class":100},[32,2374,2375],{"class":125},"(s) ",[32,2377,2378],{"class":100},">=",[32,2380,2381],{"class":104}," len",[32,2383,2384],{"class":125},"(stateNames) {\n",[32,2386,2387,2390,2393,2396,2398,2401,2404,2407],{"class":34,"line":113},[32,2388,2389],{"class":100},"        return",[32,2391,2392],{"class":125}," fmt.",[32,2394,2395],{"class":104},"Sprintf",[32,2397,141],{"class":125},[32,2399,2400],{"class":164},"\"State(",[32,2402,2403],{"class":187},"%d",[32,2405,2406],{"class":164},")\"",[32,2408,2409],{"class":125},", s)\n",[32,2411,2412],{"class":34,"line":119},[32,2413,287],{"class":125},[32,2415,2416,2418],{"class":34,"line":129},[32,2417,441],{"class":100},[32,2419,2420],{"class":125}," stateNames[s]\n",[32,2422,2423],{"class":34,"line":156},[32,2424,335],{"class":125},[32,2426,2427],{"class":34,"line":171},[32,2428,94],{"emptyLinePlaceholder":93},[32,2430,2431],{"class":34,"line":197},[32,2432,2433],{"class":38},"\u002F\u002F `go generate` + `stringer` tool approach:\n",[32,2435,2436],{"class":34,"line":203},[32,2437,2438],{"class":38},"\u002F\u002Fgo:generate stringer -type=State -output=state_string.go\n",[32,2440,2441],{"class":34,"line":208},[32,2442,2443],{"class":38},"\u002F\u002F Produces a fast String() method — recommended for large enums.\n",[14,2445,2447],{"id":2446},"named-types-compile-time-safety","Named Types — Compile-Time Safety",[19,2449,2450],{"language":21},[23,2451,2453],{"className":25,"code":2452,"language":21,"meta":27,"style":27},"\u002F\u002F A `type` declaration creates a NEW type with the same underlying type.\n\u002F\u002F Named types are NOT assignable to their underlying type without conversion.\n\ntype UserID int64\ntype AccountID int64\n\nfunc namedTypeSafety() {\n    var uid UserID = 42\n    var aid AccountID = 100\n\n    \u002F\u002F ❌ Compile error: cannot use uid (type UserID) as type AccountID\n    \u002F\u002F _ = uid + aid\n\n    \u002F\u002F ✅ Must convert explicitly — this is the safety feature:\n    combined := int64(uid) + int64(aid)  \u002F\u002F ok — both converted to int64\n    _ = combined\n\n    \u002F\u002F Methods on named types:\n    fmt.Println(uid)  \u002F\u002F calls UserID.String() if defined, else prints the number\n}\n\n\u002F\u002F Domain modeling with named types — prevents entire classes of bugs:\ntype (\n    Celsius    float64\n    Fahrenheit float64\n    Kelvin     float64\n)\n\nfunc (c Celsius) ToF() Fahrenheit { return Fahrenheit(c*9\u002F5 + 32) }\nfunc (c Celsius) ToK() Kelvin     { return Kelvin(c + 273.15) }\nfunc (c Celsius) String() string  { return fmt.Sprintf(\"%.1f°C\", c) }\n\n\u002F\u002F ⚠️ Named types share operations with their underlying type:\n\u002F\u002F   Celsius(100) > Celsius(50)  \u002F\u002F ✅ comparison works (float64 comparison)\n\u002F\u002F   Celsius(100) + Celsius(50)  \u002F\u002F ✅ arithmetic works (float64 arithmetic)\n\u002F\u002F   Celsius(100) + 50.0         \u002F\u002F ❌ untyped 50.0 works, but typed float64 doesn't\n",[29,2454,2455,2460,2465,2469,2479,2488,2492,2501,2516,2531,2535,2540,2545,2549,2554,2577,2586,2590,2595,2607,2611,2615,2620,2626,2634,2642,2650,2654,2658,2711,2749,2790,2794,2799,2807,2815],{"__ignoreMap":27},[32,2456,2457],{"class":34,"line":35},[32,2458,2459],{"class":38},"\u002F\u002F A `type` declaration creates a NEW type with the same underlying type.\n",[32,2461,2462],{"class":34,"line":42},[32,2463,2464],{"class":38},"\u002F\u002F Named types are NOT assignable to their underlying type without conversion.\n",[32,2466,2467],{"class":34,"line":48},[32,2468,94],{"emptyLinePlaceholder":93},[32,2470,2471,2473,2476],{"class":34,"line":54},[32,2472,931],{"class":100},[32,2474,2475],{"class":104}," UserID",[32,2477,2478],{"class":100}," int64\n",[32,2480,2481,2483,2486],{"class":34,"line":60},[32,2482,931],{"class":100},[32,2484,2485],{"class":104}," AccountID",[32,2487,2478],{"class":100},[32,2489,2490],{"class":34,"line":66},[32,2491,94],{"emptyLinePlaceholder":93},[32,2493,2494,2496,2499],{"class":34,"line":72},[32,2495,211],{"class":100},[32,2497,2498],{"class":104}," namedTypeSafety",[32,2500,217],{"class":125},[32,2502,2503,2505,2508,2511,2513],{"class":34,"line":78},[32,2504,491],{"class":100},[32,2506,2507],{"class":125}," uid ",[32,2509,2510],{"class":104},"UserID",[32,2512,1239],{"class":100},[32,2514,2515],{"class":187}," 42\n",[32,2517,2518,2520,2523,2526,2528],{"class":34,"line":84},[32,2519,491],{"class":100},[32,2521,2522],{"class":125}," aid ",[32,2524,2525],{"class":104},"AccountID",[32,2527,1239],{"class":100},[32,2529,2530],{"class":187}," 100\n",[32,2532,2533],{"class":34,"line":90},[32,2534,94],{"emptyLinePlaceholder":93},[32,2536,2537],{"class":34,"line":97},[32,2538,2539],{"class":38},"    \u002F\u002F ❌ Compile error: cannot use uid (type UserID) as type AccountID\n",[32,2541,2542],{"class":34,"line":108},[32,2543,2544],{"class":38},"    \u002F\u002F _ = uid + aid\n",[32,2546,2547],{"class":34,"line":113},[32,2548,94],{"emptyLinePlaceholder":93},[32,2550,2551],{"class":34,"line":119},[32,2552,2553],{"class":38},"    \u002F\u002F ✅ Must convert explicitly — this is the safety feature:\n",[32,2555,2556,2559,2561,2563,2566,2569,2571,2574],{"class":34,"line":129},[32,2557,2558],{"class":125},"    combined ",[32,2560,232],{"class":100},[32,2562,1428],{"class":100},[32,2564,2565],{"class":125},"(uid) ",[32,2567,2568],{"class":100},"+",[32,2570,1428],{"class":100},[32,2572,2573],{"class":125},"(aid)  ",[32,2575,2576],{"class":38},"\u002F\u002F ok — both converted to int64\n",[32,2578,2579,2581,2583],{"class":34,"line":156},[32,2580,324],{"class":125},[32,2582,135],{"class":100},[32,2584,2585],{"class":125}," combined\n",[32,2587,2588],{"class":34,"line":171},[32,2589,94],{"emptyLinePlaceholder":93},[32,2591,2592],{"class":34,"line":197},[32,2593,2594],{"class":38},"    \u002F\u002F Methods on named types:\n",[32,2596,2597,2599,2601,2604],{"class":34,"line":203},[32,2598,428],{"class":125},[32,2600,413],{"class":104},[32,2602,2603],{"class":125},"(uid)  ",[32,2605,2606],{"class":38},"\u002F\u002F calls UserID.String() if defined, else prints the number\n",[32,2608,2609],{"class":34,"line":208},[32,2610,335],{"class":125},[32,2612,2613],{"class":34,"line":220},[32,2614,94],{"emptyLinePlaceholder":93},[32,2616,2617],{"class":34,"line":226},[32,2618,2619],{"class":38},"\u002F\u002F Domain modeling with named types — prevents entire classes of bugs:\n",[32,2621,2622,2624],{"class":34,"line":238},[32,2623,931],{"class":100},[32,2625,126],{"class":125},[32,2627,2628,2631],{"class":34,"line":260},[32,2629,2630],{"class":104},"    Celsius",[32,2632,2633],{"class":100},"    float64\n",[32,2635,2636,2639],{"class":34,"line":278},[32,2637,2638],{"class":104},"    Fahrenheit",[32,2640,2641],{"class":100}," float64\n",[32,2643,2644,2647],{"class":34,"line":284},[32,2645,2646],{"class":104},"    Kelvin",[32,2648,2649],{"class":100},"     float64\n",[32,2651,2652],{"class":34,"line":290},[32,2653,200],{"class":125},[32,2655,2656],{"class":34,"line":295},[32,2657,94],{"emptyLinePlaceholder":93},[32,2659,2660,2662,2664,2667,2670,2672,2675,2677,2680,2683,2686,2689,2692,2694,2697,2700,2703,2705,2708],{"class":34,"line":301},[32,2661,211],{"class":100},[32,2663,2001],{"class":125},[32,2665,2666],{"class":1087},"c ",[32,2668,2669],{"class":104},"Celsius",[32,2671,191],{"class":125},[32,2673,2674],{"class":104},"ToF",[32,2676,359],{"class":125},[32,2678,2679],{"class":104},"Fahrenheit",[32,2681,2682],{"class":125}," { ",[32,2684,2685],{"class":100},"return",[32,2687,2688],{"class":104}," Fahrenheit",[32,2690,2691],{"class":125},"(c",[32,2693,961],{"class":100},[32,2695,2696],{"class":187},"9",[32,2698,2699],{"class":100},"\u002F",[32,2701,2702],{"class":187},"5",[32,2704,1624],{"class":100},[32,2706,2707],{"class":187}," 32",[32,2709,2710],{"class":125},") }\n",[32,2712,2713,2715,2717,2719,2721,2723,2726,2728,2731,2734,2736,2739,2742,2744,2747],{"class":34,"line":321},[32,2714,211],{"class":100},[32,2716,2001],{"class":125},[32,2718,2666],{"class":1087},[32,2720,2669],{"class":104},[32,2722,191],{"class":125},[32,2724,2725],{"class":104},"ToK",[32,2727,359],{"class":125},[32,2729,2730],{"class":104},"Kelvin",[32,2732,2733],{"class":125},"     { ",[32,2735,2685],{"class":100},[32,2737,2738],{"class":104}," Kelvin",[32,2740,2741],{"class":125},"(c ",[32,2743,2568],{"class":100},[32,2745,2746],{"class":187}," 273.15",[32,2748,2710],{"class":125},[32,2750,2751,2753,2755,2757,2759,2761,2763,2765,2767,2770,2772,2774,2776,2778,2781,2784,2787],{"class":34,"line":332},[32,2752,211],{"class":100},[32,2754,2001],{"class":125},[32,2756,2666],{"class":1087},[32,2758,2669],{"class":104},[32,2760,191],{"class":125},[32,2762,2351],{"class":104},[32,2764,359],{"class":125},[32,2766,2212],{"class":100},[32,2768,2769],{"class":125},"  { ",[32,2771,2685],{"class":100},[32,2773,2392],{"class":125},[32,2775,2395],{"class":104},[32,2777,141],{"class":125},[32,2779,2780],{"class":164},"\"",[32,2782,2783],{"class":187},"%.1f",[32,2785,2786],{"class":164},"°C\"",[32,2788,2789],{"class":125},", c) }\n",[32,2791,2792],{"class":34,"line":659},[32,2793,94],{"emptyLinePlaceholder":93},[32,2795,2796],{"class":34,"line":679},[32,2797,2798],{"class":38},"\u002F\u002F ⚠️ Named types share operations with their underlying type:\n",[32,2800,2801,2804],{"class":34,"line":684},[32,2802,2803],{"class":38},"\u002F\u002F   Celsius(100) > Celsius(50)",[32,2805,2806],{"class":38},"  \u002F\u002F ✅ comparison works (float64 comparison)\n",[32,2808,2809,2812],{"class":34,"line":690},[32,2810,2811],{"class":38},"\u002F\u002F   Celsius(100) + Celsius(50)",[32,2813,2814],{"class":38},"  \u002F\u002F ✅ arithmetic works (float64 arithmetic)\n",[32,2816,2817,2820],{"class":34,"line":696},[32,2818,2819],{"class":38},"\u002F\u002F   Celsius(100) + 50.0",[32,2821,2822],{"class":38},"         \u002F\u002F ❌ untyped 50.0 works, but typed float64 doesn't\n",[14,2824,2826],{"id":2825},"type-inference-rules","Type Inference Rules",[19,2828,2829],{"language":21},[23,2830,2832],{"className":25,"code":2831,"language":21,"meta":27,"style":27},"func typeInference() {\n    var i = 42          \u002F\u002F int   (default for integer literals)\n    var f = 3.14        \u002F\u002F float64 (default for float literals)\n    var s = \"hello\"     \u002F\u002F string\n    var b = true        \u002F\u002F bool\n    var r = 'A'         \u002F\u002F rune (int32) — single quotes = rune literal\n\n    \u002F\u002F Inferred from function return type:\n    var ctx = context.Background()  \u002F\u002F context.Context\n\n    \u002F\u002F ⚠️ Numeric literal defaults:\n    \u002F\u002F   integer → int\n    \u002F\u002F   float   → float64\n    \u002F\u002F   rune    → rune (int32)\n    \u002F\u002F   There's NO way to make `x := 42` infer int64 — use `var x int64 = 42`\n\n    \u002F\u002F Inferred from composite literal:\n    m := map[string]int{\"a\": 1}  \u002F\u002F map[string]int\n    sl := []int{1, 2, 3}         \u002F\u002F []int\n    st := struct{ X int }{X: 5}  \u002F\u002F anonymous struct\n\n    \u002F\u002F ⚠️ nil has no type — can't infer:\n    \u002F\u002F var x = nil  \u002F\u002F ❌ compile error: use of untyped nil\n    var p *int = nil  \u002F\u002F ✅ explicit type\n    _ = p\n}\n",[29,2833,2834,2843,2857,2871,2885,2899,2920,2924,2929,2949,2953,2958,2963,2968,2973,2978,2982,2987,3022,3054,3078,3082,3087,3095,3112,3121],{"__ignoreMap":27},[32,2835,2836,2838,2841],{"class":34,"line":35},[32,2837,211],{"class":100},[32,2839,2840],{"class":104}," typeInference",[32,2842,217],{"class":125},[32,2844,2845,2847,2849,2851,2854],{"class":34,"line":42},[32,2846,491],{"class":100},[32,2848,507],{"class":125},[32,2850,135],{"class":100},[32,2852,2853],{"class":187}," 42",[32,2855,2856],{"class":38},"          \u002F\u002F int   (default for integer literals)\n",[32,2858,2859,2861,2863,2865,2868],{"class":34,"line":48},[32,2860,491],{"class":100},[32,2862,1376],{"class":125},[32,2864,135],{"class":100},[32,2866,2867],{"class":187}," 3.14",[32,2869,2870],{"class":38},"        \u002F\u002F float64 (default for float literals)\n",[32,2872,2873,2875,2877,2879,2882],{"class":34,"line":54},[32,2874,491],{"class":100},[32,2876,1020],{"class":125},[32,2878,135],{"class":100},[32,2880,2881],{"class":164}," \"hello\"",[32,2883,2884],{"class":38},"     \u002F\u002F string\n",[32,2886,2887,2889,2892,2894,2896],{"class":34,"line":60},[32,2888,491],{"class":100},[32,2890,2891],{"class":125}," b ",[32,2893,135],{"class":100},[32,2895,385],{"class":187},[32,2897,2898],{"class":38},"        \u002F\u002F bool\n",[32,2900,2901,2903,2906,2908,2911,2914,2917],{"class":34,"line":66},[32,2902,491],{"class":100},[32,2904,2905],{"class":125}," r ",[32,2907,135],{"class":100},[32,2909,2910],{"class":164}," '",[32,2912,2913],{"class":187},"A",[32,2915,2916],{"class":164},"'",[32,2918,2919],{"class":38},"         \u002F\u002F rune (int32) — single quotes = rune literal\n",[32,2921,2922],{"class":34,"line":72},[32,2923,94],{"emptyLinePlaceholder":93},[32,2925,2926],{"class":34,"line":78},[32,2927,2928],{"class":38},"    \u002F\u002F Inferred from function return type:\n",[32,2930,2931,2933,2936,2938,2941,2944,2946],{"class":34,"line":84},[32,2932,491],{"class":100},[32,2934,2935],{"class":125}," ctx ",[32,2937,135],{"class":100},[32,2939,2940],{"class":125}," context.",[32,2942,2943],{"class":104},"Background",[32,2945,582],{"class":125},[32,2947,2948],{"class":38},"\u002F\u002F context.Context\n",[32,2950,2951],{"class":34,"line":90},[32,2952,94],{"emptyLinePlaceholder":93},[32,2954,2955],{"class":34,"line":97},[32,2956,2957],{"class":38},"    \u002F\u002F ⚠️ Numeric literal defaults:\n",[32,2959,2960],{"class":34,"line":108},[32,2961,2962],{"class":38},"    \u002F\u002F   integer → int\n",[32,2964,2965],{"class":34,"line":113},[32,2966,2967],{"class":38},"    \u002F\u002F   float   → float64\n",[32,2969,2970],{"class":34,"line":119},[32,2971,2972],{"class":38},"    \u002F\u002F   rune    → rune (int32)\n",[32,2974,2975],{"class":34,"line":129},[32,2976,2977],{"class":38},"    \u002F\u002F   There's NO way to make `x := 42` infer int64 — use `var x int64 = 42`\n",[32,2979,2980],{"class":34,"line":156},[32,2981,94],{"emptyLinePlaceholder":93},[32,2983,2984],{"class":34,"line":171},[32,2985,2986],{"class":38},"    \u002F\u002F Inferred from composite literal:\n",[32,2988,2989,2992,2994,2997,3000,3002,3004,3006,3008,3011,3014,3016,3019],{"class":34,"line":197},[32,2990,2991],{"class":125},"    m ",[32,2993,232],{"class":100},[32,2995,2996],{"class":100}," map",[32,2998,2999],{"class":125},"[",[32,3001,2212],{"class":100},[32,3003,2315],{"class":125},[32,3005,362],{"class":100},[32,3007,2215],{"class":125},[32,3009,3010],{"class":164},"\"a\"",[32,3012,3013],{"class":125},": ",[32,3015,2133],{"class":187},[32,3017,3018],{"class":125},"}  ",[32,3020,3021],{"class":38},"\u002F\u002F map[string]int\n",[32,3023,3024,3027,3029,3032,3034,3036,3038,3040,3043,3045,3048,3051],{"class":34,"line":203},[32,3025,3026],{"class":125},"    sl ",[32,3028,232],{"class":100},[32,3030,3031],{"class":125}," []",[32,3033,362],{"class":100},[32,3035,2215],{"class":125},[32,3037,2133],{"class":187},[32,3039,861],{"class":125},[32,3041,3042],{"class":187},"2",[32,3044,861],{"class":125},[32,3046,3047],{"class":187},"3",[32,3049,3050],{"class":125},"}         ",[32,3052,3053],{"class":38},"\u002F\u002F []int\n",[32,3055,3056,3059,3061,3063,3066,3068,3071,3073,3075],{"class":34,"line":208},[32,3057,3058],{"class":125},"    st ",[32,3060,232],{"class":100},[32,3062,147],{"class":100},[32,3064,3065],{"class":125},"{ X ",[32,3067,362],{"class":100},[32,3069,3070],{"class":125}," }{X: ",[32,3072,2702],{"class":187},[32,3074,3018],{"class":125},[32,3076,3077],{"class":38},"\u002F\u002F anonymous struct\n",[32,3079,3080],{"class":34,"line":220},[32,3081,94],{"emptyLinePlaceholder":93},[32,3083,3084],{"class":34,"line":226},[32,3085,3086],{"class":38},"    \u002F\u002F ⚠️ nil has no type — can't infer:\n",[32,3088,3089,3092],{"class":34,"line":238},[32,3090,3091],{"class":38},"    \u002F\u002F var x = nil",[32,3093,3094],{"class":38},"  \u002F\u002F ❌ compile error: use of untyped nil\n",[32,3096,3097,3099,3102,3105,3107,3109],{"class":34,"line":260},[32,3098,491],{"class":100},[32,3100,3101],{"class":125}," p ",[32,3103,3104],{"class":100},"*int",[32,3106,1239],{"class":100},[32,3108,272],{"class":187},[32,3110,3111],{"class":38},"  \u002F\u002F ✅ explicit type\n",[32,3113,3114,3116,3118],{"class":34,"line":278},[32,3115,324],{"class":125},[32,3117,135],{"class":100},[32,3119,3120],{"class":125}," p\n",[32,3122,3123],{"class":34,"line":284},[32,3124,335],{"class":125},[14,3126,3128,3129],{"id":3127},"the-blank-identifier-_","The Blank Identifier ",[29,3130,3131],{},"_",[19,3133,3134],{"language":21},[23,3135,3137],{"className":25,"code":3136,"language":21,"meta":27,"style":27},"\u002F\u002F `_` discards a value. It's a write-only identifier — you can't read it.\n\n\u002F\u002F 1. Discard unwanted return values:\n_, err := os.Open(\"file.txt\")  \u002F\u002F don't care about the file, just the error\nfor _, v := range items {       \u002F\u002F don't care about the index\n    _ = v\n}\n\n\u002F\u002F 2. Discard an assignment to suppress \"unused variable\" error:\nfunc _suppress() {\n    x := expensiveComputation()\n    _ = x  \u002F\u002F suppress unused error — but this is a code smell, prefer to use x\n}\n\n\u002F\u002F 3. Import for side effects (blank import):\nimport _ \"github.com\u002Flib\u002Fpq\"  \u002F\u002F runs pq's init() to register the postgres driver\n\n\u002F\u002F 4. Interface satisfaction check (compile-time assertion):\nvar _ io.Reader = (*MyReader)(nil)  \u002F\u002F fails to compile if *MyReader doesn't satisfy io.Reader\n\n\u002F\u002F 5. Explicitly ignore a channel receive:\n\u003C-done  \u002F\u002F wait for done signal, discard the value\n",[29,3138,3139,3144,3148,3153,3176,3194,3203,3207,3211,3216,3225,3236,3248,3252,3256,3261,3279,3283,3288,3322,3326,3331],{"__ignoreMap":27},[32,3140,3141],{"class":34,"line":35},[32,3142,3143],{"class":38},"\u002F\u002F `_` discards a value. It's a write-only identifier — you can't read it.\n",[32,3145,3146],{"class":34,"line":42},[32,3147,94],{"emptyLinePlaceholder":93},[32,3149,3150],{"class":34,"line":48},[32,3151,3152],{"class":38},"\u002F\u002F 1. Discard unwanted return values:\n",[32,3154,3155,3158,3160,3163,3166,3168,3171,3173],{"class":34,"line":54},[32,3156,3157],{"class":125},"_, err ",[32,3159,232],{"class":100},[32,3161,3162],{"class":125}," os.",[32,3164,3165],{"class":104},"Open",[32,3167,141],{"class":125},[32,3169,3170],{"class":164},"\"file.txt\"",[32,3172,254],{"class":125},[32,3174,3175],{"class":38},"\u002F\u002F don't care about the file, just the error\n",[32,3177,3178,3181,3184,3186,3188,3191],{"class":34,"line":60},[32,3179,3180],{"class":100},"for",[32,3182,3183],{"class":125}," _, v ",[32,3185,232],{"class":100},[32,3187,571],{"class":100},[32,3189,3190],{"class":125}," items {       ",[32,3192,3193],{"class":38},"\u002F\u002F don't care about the index\n",[32,3195,3196,3198,3200],{"class":34,"line":66},[32,3197,324],{"class":125},[32,3199,135],{"class":100},[32,3201,3202],{"class":125}," v\n",[32,3204,3205],{"class":34,"line":72},[32,3206,335],{"class":125},[32,3208,3209],{"class":34,"line":78},[32,3210,94],{"emptyLinePlaceholder":93},[32,3212,3213],{"class":34,"line":84},[32,3214,3215],{"class":38},"\u002F\u002F 2. Discard an assignment to suppress \"unused variable\" error:\n",[32,3217,3218,3220,3223],{"class":34,"line":90},[32,3219,211],{"class":100},[32,3221,3222],{"class":104}," _suppress",[32,3224,217],{"class":125},[32,3226,3227,3229,3231,3234],{"class":34,"line":97},[32,3228,369],{"class":125},[32,3230,232],{"class":100},[32,3232,3233],{"class":104}," expensiveComputation",[32,3235,499],{"class":125},[32,3237,3238,3240,3242,3245],{"class":34,"line":108},[32,3239,324],{"class":125},[32,3241,135],{"class":100},[32,3243,3244],{"class":125}," x  ",[32,3246,3247],{"class":38},"\u002F\u002F suppress unused error — but this is a code smell, prefer to use x\n",[32,3249,3250],{"class":34,"line":113},[32,3251,335],{"class":125},[32,3253,3254],{"class":34,"line":119},[32,3255,94],{"emptyLinePlaceholder":93},[32,3257,3258],{"class":34,"line":129},[32,3259,3260],{"class":38},"\u002F\u002F 3. Import for side effects (blank import):\n",[32,3262,3263,3266,3269,3271,3274,3276],{"class":34,"line":156},[32,3264,3265],{"class":100},"import",[32,3267,3268],{"class":125}," _ ",[32,3270,2780],{"class":164},[32,3272,3273],{"class":104},"github.com\u002Flib\u002Fpq",[32,3275,2780],{"class":164},[32,3277,3278],{"class":38},"  \u002F\u002F runs pq's init() to register the postgres driver\n",[32,3280,3281],{"class":34,"line":171},[32,3282,94],{"emptyLinePlaceholder":93},[32,3284,3285],{"class":34,"line":197},[32,3286,3287],{"class":38},"\u002F\u002F 4. Interface satisfaction check (compile-time assertion):\n",[32,3289,3290,3292,3294,3297,3299,3302,3304,3306,3308,3311,3314,3317,3319],{"class":34,"line":203},[32,3291,122],{"class":100},[32,3293,3268],{"class":125},[32,3295,3296],{"class":104},"io",[32,3298,967],{"class":125},[32,3300,3301],{"class":104},"Reader",[32,3303,1239],{"class":100},[32,3305,2001],{"class":125},[32,3307,961],{"class":100},[32,3309,3310],{"class":104},"MyReader",[32,3312,3313],{"class":125},")(",[32,3315,3316],{"class":187},"nil",[32,3318,254],{"class":125},[32,3320,3321],{"class":38},"\u002F\u002F fails to compile if *MyReader doesn't satisfy io.Reader\n",[32,3323,3324],{"class":34,"line":208},[32,3325,94],{"emptyLinePlaceholder":93},[32,3327,3328],{"class":34,"line":220},[32,3329,3330],{"class":38},"\u002F\u002F 5. Explicitly ignore a channel receive:\n",[32,3332,3333,3336,3339],{"class":34,"line":226},[32,3334,3335],{"class":100},"\u003C-",[32,3337,3338],{"class":125},"done  ",[32,3340,3341],{"class":38},"\u002F\u002F wait for done signal, discard the value\n",[14,3343,3345],{"id":3344},"tips-tricks","💡 Tips & Tricks",[3347,3348,3349,3366,3382,3392,3401,3430],"ul",{},[3350,3351,3352,3013,3356,3359,3360,3362,3363,3365],"li",{},[3353,3354,3355],"strong",{},"Safety",[29,3357,3358],{},"type UserID int64"," prevents passing a ",[29,3361,2510],{}," where an ",[29,3364,2525],{}," is expected — the compiler catches the bug. Use named types for all domain IDs, currency amounts, and measurement units. The zero cost (no runtime overhead) makes this a no-brainer.",[3350,3367,3368,3371,3372,861,3375,861,3378,3381],{},[3353,3369,3370],{},"Idiom",": design structs so the zero value is immediately usable — ",[29,3373,3374],{},"sync.Mutex{}",[29,3376,3377],{},"bytes.Buffer{}",[29,3379,3380],{},"http.Server{}"," all work without initialization. If a field has no sensible zero value, make it unexported and require a constructor.",[3350,3383,3384,3387,3388,3391],{},[3353,3385,3386],{},"Performance",": untyped constants avoid conversion overhead — ",[29,3389,3390],{},"const Size = 1024"," compiles to a literal instruction with zero conversion. Typed constants may need an implicit conversion at each use site.",[3350,3393,3394,3396,3397,3400],{},[3353,3395,3370],{},": use ",[29,3398,3399],{},"var _ Interface = (*Type)(nil)"," at package scope to assert interface satisfaction at compile time — catches breakage when a method signature changes.",[3350,3402,3403,3013,3406,3409,3410,3413,3414,3417,3418,3421,3422,3425,3426,3429],{},[3353,3404,3405],{},"Debug",[29,3407,3408],{},"go vet -shadow"," (or ",[29,3411,3412],{},"golangci-lint"," with ",[29,3415,3416],{},"shadow"," enabled) catches variable shadowing — ",[29,3419,3420],{},"x := 10"," inside an ",[29,3423,3424],{},"if"," block that shadows an outer ",[29,3427,3428],{},"x",". Enable in CI.",[3350,3431,3432,3013,3434,3413,3436,3439,3440,3442,3443,3445,3446,3449],{},[3353,3433,3370],{},[29,3435,1697],{},[29,3437,3438],{},"1 \u003C\u003C iota"," is the clean way to define bit flags — each flag gets a distinct power-of-2 value. Compose with ",[29,3441,1884],{}," (OR), test with ",[29,3444,1944],{}," (AND), remove with ",[29,3447,3448],{},"&^"," (AND NOT).",[14,3451,3453],{"id":3452},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[3347,3455,3456,3473,3493,3525,3541,3554,3568,3584,3605,3617],{},[3350,3457,3458,3013,3463,3466,3467,3470,3471,967],{},[3353,3459,3460,3462],{},[29,3461,232],{}," requires at least one new variable",[29,3464,3465],{},"x, y := 1, 2"," then ",[29,3468,3469],{},"x, y := 3, 4"," → compile error (no new variable). Use ",[29,3472,135],{},[3350,3474,3475,3013,3480,3483,3484,3486,3487,3489,3490,3492],{},[3353,3476,3477,3479],{},[29,3478,232],{}," in a new scope shadows",[29,3481,3482],{},"if true { x := 5 }"," declares a new ",[29,3485,3428],{},", not reassigning outer ",[29,3488,3428],{},". Use ",[29,3491,135],{}," to modify the outer variable.",[3350,3494,3495,3013,3498,3501,3502,3505,3506,3509,3510,3513,3514,3517,3518,3513,3521,3524],{},[3353,3496,3497],{},"nil slice vs empty slice",[29,3499,3500],{},"var s []int"," (nil, ",[29,3503,3504],{},"s == nil"," true) vs ",[29,3507,3508],{},"s := []int{}"," (non-nil, empty). ",[29,3511,3512],{},"json.Marshal(nil)"," → ",[29,3515,3516],{},"null","; ",[29,3519,3520],{},"json.Marshal([]int{})",[29,3522,3523],{},"[]",". APIs may treat these differently.",[3350,3526,3527,3013,3530,3513,3533,3536,3537,3540],{},[3353,3528,3529],{},"nil interface vs nil concrete value",[29,3531,3532],{},"var p *int = nil; var i any = p; i == nil",[29,3534,3535],{},"false",". The interface holds ",[29,3538,3539],{},"(*int, nil)",", not a nil interface. See chapter 12.",[3350,3542,3543,3013,3546,3549,3550,3553],{},[3353,3544,3545],{},"Untyped constant overflow",[29,3547,3548],{},"const Big = 1 \u003C\u003C 100"," is fine (arbitrary precision), but ",[29,3551,3552],{},"var x int = Big"," → compile error (overflows int). Untyped constants only overflow when assigned to a type.",[3350,3555,3556,3013,3562,3564,3565,967],{},[3353,3557,3558,3561],{},[29,3559,3560],{},"var x = nil"," is illegal",[29,3563,3316],{}," has no type, so type inference fails. Use ",[29,3566,3567],{},"var x *int = nil",[3350,3569,3570,3013,3573,3576,3577,3579,3580,3583],{},[3353,3571,3572],{},"Named types and literals",[29,3574,3575],{},"var c Celsius = 25.0"," works (literal is untyped, adapts to ",[29,3578,2669],{},"), but ",[29,3581,3582],{},"var c Celsius = float64(25.0)"," → compile error (typed value needs conversion).",[3350,3585,3586,3591,3592,3594,3595,3597,3598,3600,3601,3604],{},[3353,3587,3588,3590],{},[29,3589,1697],{}," increments per line",": in a ",[29,3593,1215],{}," block, ",[29,3596,1697],{}," is 0 on the first line, 1 on the second — even if a line doesn't use ",[29,3599,1697],{},". ",[29,3602,3603],{},"const ( A = iota; B = 10; C = iota )"," → A=0, B=10, C=2 (not 1).",[3350,3606,3607,3013,3610,3613,3614,3616],{},[3353,3608,3609],{},"Constants can't reference runtime values",[29,3611,3612],{},"const Now = time.Now()"," → compile error. Use ",[29,3615,122],{}," for runtime-computed values.",[3350,3618,3619,3013,3626,3629,3630,3633,3634,3637],{},[3353,3620,3621,3622,3625],{},"Zero value of ",[29,3623,3624],{},"time.Duration"," is 0",[29,3627,3628],{},"var d time.Duration"," → 0 (not \"no duration\"). ",[29,3631,3632],{},"0 * time.Second"," = 0ns. This is meaningful — check ",[29,3635,3636],{},"d == 0"," to detect \"unset\".",[14,3639,3641],{"id":3640},"quick-quiz","🧠 Quick Quiz",[19,3643,3644,3718],{"language":21},[23,3645,3647],{"className":25,"code":3646,"language":21,"meta":27,"style":27},"const x = 1 \u003C\u003C 62\nvar y int = x\nvar z int64 = x\nvar w float64 = x\n\nfmt.Println(y, z, w)\n",[29,3648,3649,3665,3678,3691,3704,3708],{"__ignoreMap":27},[32,3650,3651,3653,3656,3658,3660,3662],{"class":34,"line":35},[32,3652,1215],{"class":100},[32,3654,3655],{"class":187}," x",[32,3657,1239],{"class":100},[32,3659,1242],{"class":187},[32,3661,1245],{"class":100},[32,3663,3664],{"class":187}," 62\n",[32,3666,3667,3669,3672,3674,3676],{"class":34,"line":42},[32,3668,122],{"class":100},[32,3670,3671],{"class":125}," y ",[32,3673,362],{"class":100},[32,3675,1239],{"class":100},[32,3677,1599],{"class":125},[32,3679,3680,3682,3685,3687,3689],{"class":34,"line":48},[32,3681,122],{"class":100},[32,3683,3684],{"class":125}," z ",[32,3686,1361],{"class":100},[32,3688,1239],{"class":100},[32,3690,1599],{"class":125},[32,3692,3693,3695,3698,3700,3702],{"class":34,"line":54},[32,3694,122],{"class":100},[32,3696,3697],{"class":125}," w ",[32,3699,1379],{"class":100},[32,3701,1239],{"class":100},[32,3703,1599],{"class":125},[32,3705,3706],{"class":34,"line":60},[32,3707,94],{"emptyLinePlaceholder":93},[32,3709,3710,3713,3715],{"class":34,"line":66},[32,3711,3712],{"class":125},"fmt.",[32,3714,413],{"class":104},[32,3716,3717],{"class":125},"(y, z, w)\n",[1920,3719,3720],{},"What happens?",[3722,3723,3724,3728,3731,3739,3745,3766],"details",{},[3725,3726,3727],"summary",{},"Answer",[1920,3729,3730],{},"All three assignments compile and work:",[23,3732,3737],{"className":3733,"code":3735,"language":3736},[3734],"language-text","4611686018427387904 4611686018427387904 4.611686018427388e+18\n","text",[29,3738,3735],{"__ignoreMap":27},[1920,3740,3741,3744],{},[29,3742,3743],{},"1 \u003C\u003C 62"," = 4,611,686,018,427,387,904, which fits in:",[3347,3746,3747,3752,3757],{},[3350,3748,3749,3751],{},[29,3750,362],{}," (64-bit: max 2^63-1) ✅",[3350,3753,3754,3756],{},[29,3755,1361],{}," (max 2^63-1) ✅",[3350,3758,3759,3761,3762,3765],{},[29,3760,1379],{}," (can represent integers up to 2^53 exactly; beyond that, precision loss) — ",[29,3763,3764],{},"w"," prints in scientific notation with rounding",[1920,3767,3768,3769,3771,3772,3775,3776,3779,3780,3782,3783,3785,3786,3788],{},"The key: ",[29,3770,3428],{}," is an ",[3353,3773,3774],{},"untyped constant"," with arbitrary precision. It adapts to each type's context. If it were ",[29,3777,3778],{},"const x = 1 \u003C\u003C 65",", the ",[29,3781,362],{}," and ",[29,3784,1361],{}," assignments would fail (overflow) but ",[29,3787,1379],{}," would still work (float64 can represent large exponents).",[14,3790,3792],{"id":3791},"whats-next","📚 What's Next",[1920,3794,3795,3796,3801],{},"→ ",[3797,3798,3800],"a",{"href":3799},"\u002Fgo\u002F04-basic-types-and-conversions","04 — Basic Types & Conversions"," — integer overflow behavior, float64 precision, rune vs byte, string internals, and safe conversion patterns.",[3803,3804,3805],"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 .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}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 .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":27,"searchDepth":42,"depth":42,"links":3807},[3808,3812,3815,3818,3823,3824,3825,3827,3828,3829,3830],{"id":16,"depth":42,"text":17,"children":3809},[3810],{"id":339,"depth":48,"text":3811},":= rules and the shadowing trap",{"id":701,"depth":42,"text":702,"children":3813},[3814],{"id":918,"depth":48,"text":919},{"id":1178,"depth":42,"text":1179,"children":3816},[3817],{"id":1458,"depth":48,"text":1459},{"id":1694,"depth":42,"text":3819,"children":3820},"iota — Beyond Simple Enums",[3821],{"id":2233,"depth":48,"text":3822},"Adding String() to enums",{"id":2446,"depth":42,"text":2447},{"id":2825,"depth":42,"text":2826},{"id":3127,"depth":42,"text":3826},"The Blank Identifier _",{"id":3344,"depth":42,"text":3345},{"id":3452,"depth":42,"text":3453},{"id":3640,"depth":42,"text":3641},{"id":3791,"depth":42,"text":3792},"Zero-value semantics, untyped constant precision, iota bit-flag patterns, named-type safety, and the shadowing trap — with production code.","md",{},"\u002Fgo\u002F03-variables-constants-and-types",{"title":5,"description":3831},"go\u002F03-variables-constants-and-types","CTqoxqiWTz5hyZjta8tBTC0WtmfL5FnXp37sdIM4iNE",1789924648243]