[{"data":1,"prerenderedAt":3296},["ShallowReactive",2],{"page-\u002Fgo\u002F04-basic-types-and-conversions":3},{"id":4,"title":5,"body":6,"description":3289,"extension":3290,"meta":3291,"navigation":63,"path":3292,"seo":3293,"stem":3294,"__hash__":3295},"content\u002Fgo\u002F04-basic-types-and-conversions.md","04 — Basic Types & Conversions",{"type":7,"value":8,"toc":3267},"minimark",[9,13,18,32,36,393,398,779,783,1201,1205,1531,1535,1830,1837,2025,2029,2239,2247,2424,2428,2743,2747,2859,2863,3095,3099,3183,3251,3255,3263],[10,11,5],"h1",{"id":12},"_04-basic-types-conversions",[14,15,17],"h2",{"id":16},"numeric-type-map","Numeric Type Map",[19,20,22],"code-wrapper",{"language":21},"text",[23,24,29],"pre",{"className":25,"code":27,"language":21,"meta":28},[26],"language-text","┌──────────────────────────────────────────────────────────────────────────┐\n│ Signed   │ int   int8   int16   int32   int64                          │\n│ Unsigned │ uint  uint8  uint16  uint32  uint64  uintptr                 │\n│ Float    │ float32  float64                                          │\n│ Complex  │ complex64  complex128                                      │\n│ Aliases  │ byte = uint8    rune = int32                               │\n└──────────────────────────────────────────────────────────────────────────┘\n\nPlatform sizes:\n  int\u002Fuint     → 32-bit on 32-bit OS, 64-bit on 64-bit OS (NEVER assume 64)\n  float64      → IEEE 754 double precision (53-bit mantissa, 11-bit exponent)\n  uintptr      → integer type large enough to hold a pointer (for unsafe code)\n","",[30,31,27],"code",{"__ignoreMap":28},[14,33,35],{"id":34},"integer-overflow-silent-and-deadly","Integer Overflow — Silent and Deadly",[19,37,39],{"language":38},"go",[23,40,43],{"className":41,"code":42,"language":38,"meta":28,"style":28},"language-go shiki shiki-themes github-light github-dark","package main\n\nimport (\n    \"fmt\"\n    \"math\u002Fbits\"\n)\n\nfunc overflowDemo() {\n    \u002F\u002F Signed overflow wraps (two's complement):\n    var i int8 = 127\n    i++                          \u002F\u002F -128 (wrapped from max to min)\n    fmt.Println(i)               \u002F\u002F -128\n\n    \u002F\u002F Unsigned overflow wraps to 0:\n    var u uint8 = 255\n    u++                          \u002F\u002F 0\n    fmt.Println(u)               \u002F\u002F 0\n\n    \u002F\u002F ❌ ANTI-PATTERN: trusting integer arithmetic in security-critical code\n    func addUnchecked(a, b int) int {\n        return a + b  \u002F\u002F silent overflow — can wrap to negative, bypass bounds checks\n    }\n\n    \u002F\u002F ✅ CORRECT: use math\u002Fbits for overflow detection\n    sum, carry := bits.Add64(uint64(a), uint64(b), 0)  \u002F\u002F carry=1 if overflow\n    if carry == 1 {\n        return 0, errors.New(\"integer overflow\")\n    }\n    _ = sum\n}\n",[30,44,45,58,65,75,88,98,104,109,121,128,147,159,174,179,185,201,212,225,230,236,259,277,283,288,294,332,349,370,375,387],{"__ignoreMap":28},[46,47,50,54],"span",{"class":48,"line":49},"line",1,[46,51,53],{"class":52},"svdQ7","package",[46,55,57],{"class":56},"sIsaT"," main\n",[46,59,61],{"class":48,"line":60},2,[46,62,64],{"emptyLinePlaceholder":63},true,"\n",[46,66,68,71],{"class":48,"line":67},3,[46,69,70],{"class":52},"import",[46,72,74],{"class":73},"ssxIu"," (\n",[46,76,78,82,85],{"class":48,"line":77},4,[46,79,81],{"class":80},"sJ6F3","    \"",[46,83,84],{"class":56},"fmt",[46,86,87],{"class":80},"\"\n",[46,89,91,93,96],{"class":48,"line":90},5,[46,92,81],{"class":80},[46,94,95],{"class":56},"math\u002Fbits",[46,97,87],{"class":80},[46,99,101],{"class":48,"line":100},6,[46,102,103],{"class":73},")\n",[46,105,107],{"class":48,"line":106},7,[46,108,64],{"emptyLinePlaceholder":63},[46,110,112,115,118],{"class":48,"line":111},8,[46,113,114],{"class":52},"func",[46,116,117],{"class":56}," overflowDemo",[46,119,120],{"class":73},"() {\n",[46,122,124],{"class":48,"line":123},9,[46,125,127],{"class":126},"sdCPZ","    \u002F\u002F Signed overflow wraps (two's complement):\n",[46,129,131,134,137,140,143],{"class":48,"line":130},10,[46,132,133],{"class":52},"    var",[46,135,136],{"class":73}," i ",[46,138,139],{"class":52},"int8",[46,141,142],{"class":52}," =",[46,144,146],{"class":145},"snvgF"," 127\n",[46,148,150,153,156],{"class":48,"line":149},11,[46,151,152],{"class":73},"    i",[46,154,155],{"class":52},"++",[46,157,158],{"class":126},"                          \u002F\u002F -128 (wrapped from max to min)\n",[46,160,162,165,168,171],{"class":48,"line":161},12,[46,163,164],{"class":73},"    fmt.",[46,166,167],{"class":56},"Println",[46,169,170],{"class":73},"(i)               ",[46,172,173],{"class":126},"\u002F\u002F -128\n",[46,175,177],{"class":48,"line":176},13,[46,178,64],{"emptyLinePlaceholder":63},[46,180,182],{"class":48,"line":181},14,[46,183,184],{"class":126},"    \u002F\u002F Unsigned overflow wraps to 0:\n",[46,186,188,190,193,196,198],{"class":48,"line":187},15,[46,189,133],{"class":52},[46,191,192],{"class":73}," u ",[46,194,195],{"class":52},"uint8",[46,197,142],{"class":52},[46,199,200],{"class":145}," 255\n",[46,202,204,207,209],{"class":48,"line":203},16,[46,205,206],{"class":73},"    u",[46,208,155],{"class":52},[46,210,211],{"class":126},"                          \u002F\u002F 0\n",[46,213,215,217,219,222],{"class":48,"line":214},17,[46,216,164],{"class":73},[46,218,167],{"class":56},[46,220,221],{"class":73},"(u)               ",[46,223,224],{"class":126},"\u002F\u002F 0\n",[46,226,228],{"class":48,"line":227},18,[46,229,64],{"emptyLinePlaceholder":63},[46,231,233],{"class":48,"line":232},19,[46,234,235],{"class":126},"    \u002F\u002F ❌ ANTI-PATTERN: trusting integer arithmetic in security-critical code\n",[46,237,239,242,245,248,251,254,256],{"class":48,"line":238},20,[46,240,241],{"class":52},"    func",[46,243,244],{"class":56}," addUnchecked",[46,246,247],{"class":73},"(a, b ",[46,249,250],{"class":52},"int",[46,252,253],{"class":73},") ",[46,255,250],{"class":52},[46,257,258],{"class":73}," {\n",[46,260,262,265,268,271,274],{"class":48,"line":261},21,[46,263,264],{"class":52},"        return",[46,266,267],{"class":73}," a ",[46,269,270],{"class":52},"+",[46,272,273],{"class":73}," b  ",[46,275,276],{"class":126},"\u002F\u002F silent overflow — can wrap to negative, bypass bounds checks\n",[46,278,280],{"class":48,"line":279},22,[46,281,282],{"class":73},"    }\n",[46,284,286],{"class":48,"line":285},23,[46,287,64],{"emptyLinePlaceholder":63},[46,289,291],{"class":48,"line":290},24,[46,292,293],{"class":126},"    \u002F\u002F ✅ CORRECT: use math\u002Fbits for overflow detection\n",[46,295,297,300,303,306,309,312,315,318,320,323,326,329],{"class":48,"line":296},25,[46,298,299],{"class":73},"    sum, carry ",[46,301,302],{"class":52},":=",[46,304,305],{"class":73}," bits.",[46,307,308],{"class":56},"Add64",[46,310,311],{"class":73},"(",[46,313,314],{"class":52},"uint64",[46,316,317],{"class":73},"(a), ",[46,319,314],{"class":52},[46,321,322],{"class":73},"(b), ",[46,324,325],{"class":145},"0",[46,327,328],{"class":73},")  ",[46,330,331],{"class":126},"\u002F\u002F carry=1 if overflow\n",[46,333,335,338,341,344,347],{"class":48,"line":334},26,[46,336,337],{"class":52},"    if",[46,339,340],{"class":73}," carry ",[46,342,343],{"class":52},"==",[46,345,346],{"class":145}," 1",[46,348,258],{"class":73},[46,350,352,354,357,360,363,365,368],{"class":48,"line":351},27,[46,353,264],{"class":52},[46,355,356],{"class":145}," 0",[46,358,359],{"class":73},", errors.",[46,361,362],{"class":56},"New",[46,364,311],{"class":73},[46,366,367],{"class":80},"\"integer overflow\"",[46,369,103],{"class":73},[46,371,373],{"class":48,"line":372},28,[46,374,282],{"class":73},[46,376,378,381,384],{"class":48,"line":377},29,[46,379,380],{"class":73},"    _ ",[46,382,383],{"class":52},"=",[46,385,386],{"class":73}," sum\n",[46,388,390],{"class":48,"line":389},30,[46,391,392],{"class":73},"}\n",[394,395,397],"h3",{"id":396},"production-overflow-safe-arithmetic","Production overflow-safe arithmetic",[19,399,400],{"language":38},[23,401,403],{"className":41,"code":402,"language":38,"meta":28,"style":28},"package money\n\nimport \"errors\"\n\n\u002F\u002F SafeAdd adds two int64s, returning an error on overflow.\n\u002F\u002F Use in financial, capacity, and size calculations where silent\n\u002F\u002F overflow would cause data loss or security vulnerabilities.\nfunc SafeAdd(a, b int64) (int64, error) {\n    if b > 0 {\n        if a > math.MaxInt64-b {  \u002F\u002F positive overflow: a + b > MaxInt64\n            return 0, errors.New(\"money: integer overflow\")\n        }\n    } else {\n        if a \u003C math.MinInt64-b {  \u002F\u002F negative overflow: a + b \u003C MinInt64\n            return 0, errors.New(\"money: integer overflow\")\n        }\n    }\n    return a + b, nil\n}\n\n\u002F\u002F SafeMul multiplies two int64s with overflow check.\nfunc SafeMul(a, b int64) (int64, error) {\n    if a == 0 || b == 0 {\n        return 0, nil\n    }\n    r := a * b\n    if r\u002Fa != b {  \u002F\u002F standard overflow detection trick\n        return 0, errors.New(\"money: integer overflow in multiply\")\n    }\n    return r, nil\n}\n\n\u002F\u002F For arbitrary precision — use math\u002Fbig:\n\u002F\u002F import \"math\u002Fbig\"\n\u002F\u002F result := new(big.Int).Mul(big.NewInt(a), big.NewInt(b))\n",[30,404,405,412,416,428,432,437,442,447,483,497,518,536,541,551,570,586,590,594,609,613,617,622,649,670,680,684,699,721,738,742,751,756,761,767,773],{"__ignoreMap":28},[46,406,407,409],{"class":48,"line":49},[46,408,53],{"class":52},[46,410,411],{"class":56}," money\n",[46,413,414],{"class":48,"line":60},[46,415,64],{"emptyLinePlaceholder":63},[46,417,418,420,423,426],{"class":48,"line":67},[46,419,70],{"class":52},[46,421,422],{"class":80}," \"",[46,424,425],{"class":56},"errors",[46,427,87],{"class":80},[46,429,430],{"class":48,"line":77},[46,431,64],{"emptyLinePlaceholder":63},[46,433,434],{"class":48,"line":90},[46,435,436],{"class":126},"\u002F\u002F SafeAdd adds two int64s, returning an error on overflow.\n",[46,438,439],{"class":48,"line":100},[46,440,441],{"class":126},"\u002F\u002F Use in financial, capacity, and size calculations where silent\n",[46,443,444],{"class":48,"line":106},[46,445,446],{"class":126},"\u002F\u002F overflow would cause data loss or security vulnerabilities.\n",[46,448,449,451,454,456,460,463,466,469,472,475,477,480],{"class":48,"line":111},[46,450,114],{"class":52},[46,452,453],{"class":56}," SafeAdd",[46,455,311],{"class":73},[46,457,459],{"class":458},"sCrzJ","a",[46,461,462],{"class":73},", ",[46,464,465],{"class":458},"b",[46,467,468],{"class":52}," int64",[46,470,471],{"class":73},") (",[46,473,474],{"class":52},"int64",[46,476,462],{"class":73},[46,478,479],{"class":52},"error",[46,481,482],{"class":73},") {\n",[46,484,485,487,490,493,495],{"class":48,"line":123},[46,486,337],{"class":52},[46,488,489],{"class":73}," b ",[46,491,492],{"class":52},">",[46,494,356],{"class":145},[46,496,258],{"class":73},[46,498,499,502,504,506,509,512,515],{"class":48,"line":130},[46,500,501],{"class":52},"        if",[46,503,267],{"class":73},[46,505,492],{"class":52},[46,507,508],{"class":73}," math.MaxInt64",[46,510,511],{"class":52},"-",[46,513,514],{"class":73},"b {  ",[46,516,517],{"class":126},"\u002F\u002F positive overflow: a + b > MaxInt64\n",[46,519,520,523,525,527,529,531,534],{"class":48,"line":149},[46,521,522],{"class":52},"            return",[46,524,356],{"class":145},[46,526,359],{"class":73},[46,528,362],{"class":56},[46,530,311],{"class":73},[46,532,533],{"class":80},"\"money: integer overflow\"",[46,535,103],{"class":73},[46,537,538],{"class":48,"line":161},[46,539,540],{"class":73},"        }\n",[46,542,543,546,549],{"class":48,"line":176},[46,544,545],{"class":73},"    } ",[46,547,548],{"class":52},"else",[46,550,258],{"class":73},[46,552,553,555,557,560,563,565,567],{"class":48,"line":181},[46,554,501],{"class":52},[46,556,267],{"class":73},[46,558,559],{"class":52},"\u003C",[46,561,562],{"class":73}," math.MinInt64",[46,564,511],{"class":52},[46,566,514],{"class":73},[46,568,569],{"class":126},"\u002F\u002F negative overflow: a + b \u003C MinInt64\n",[46,571,572,574,576,578,580,582,584],{"class":48,"line":187},[46,573,522],{"class":52},[46,575,356],{"class":145},[46,577,359],{"class":73},[46,579,362],{"class":56},[46,581,311],{"class":73},[46,583,533],{"class":80},[46,585,103],{"class":73},[46,587,588],{"class":48,"line":203},[46,589,540],{"class":73},[46,591,592],{"class":48,"line":214},[46,593,282],{"class":73},[46,595,596,599,601,603,606],{"class":48,"line":227},[46,597,598],{"class":52},"    return",[46,600,267],{"class":73},[46,602,270],{"class":52},[46,604,605],{"class":73}," b, ",[46,607,608],{"class":145},"nil\n",[46,610,611],{"class":48,"line":232},[46,612,392],{"class":73},[46,614,615],{"class":48,"line":238},[46,616,64],{"emptyLinePlaceholder":63},[46,618,619],{"class":48,"line":261},[46,620,621],{"class":126},"\u002F\u002F SafeMul multiplies two int64s with overflow check.\n",[46,623,624,626,629,631,633,635,637,639,641,643,645,647],{"class":48,"line":279},[46,625,114],{"class":52},[46,627,628],{"class":56}," SafeMul",[46,630,311],{"class":73},[46,632,459],{"class":458},[46,634,462],{"class":73},[46,636,465],{"class":458},[46,638,468],{"class":52},[46,640,471],{"class":73},[46,642,474],{"class":52},[46,644,462],{"class":73},[46,646,479],{"class":52},[46,648,482],{"class":73},[46,650,651,653,655,657,659,662,664,666,668],{"class":48,"line":285},[46,652,337],{"class":52},[46,654,267],{"class":73},[46,656,343],{"class":52},[46,658,356],{"class":145},[46,660,661],{"class":52}," ||",[46,663,489],{"class":73},[46,665,343],{"class":52},[46,667,356],{"class":145},[46,669,258],{"class":73},[46,671,672,674,676,678],{"class":48,"line":290},[46,673,264],{"class":52},[46,675,356],{"class":145},[46,677,462],{"class":73},[46,679,608],{"class":145},[46,681,682],{"class":48,"line":296},[46,683,282],{"class":73},[46,685,686,689,691,693,696],{"class":48,"line":334},[46,687,688],{"class":73},"    r ",[46,690,302],{"class":52},[46,692,267],{"class":73},[46,694,695],{"class":52},"*",[46,697,698],{"class":73}," b\n",[46,700,701,703,706,709,712,715,718],{"class":48,"line":351},[46,702,337],{"class":52},[46,704,705],{"class":73}," r",[46,707,708],{"class":52},"\u002F",[46,710,711],{"class":73},"a ",[46,713,714],{"class":52},"!=",[46,716,717],{"class":73}," b {  ",[46,719,720],{"class":126},"\u002F\u002F standard overflow detection trick\n",[46,722,723,725,727,729,731,733,736],{"class":48,"line":372},[46,724,264],{"class":52},[46,726,356],{"class":145},[46,728,359],{"class":73},[46,730,362],{"class":56},[46,732,311],{"class":73},[46,734,735],{"class":80},"\"money: integer overflow in multiply\"",[46,737,103],{"class":73},[46,739,740],{"class":48,"line":377},[46,741,282],{"class":73},[46,743,744,746,749],{"class":48,"line":389},[46,745,598],{"class":52},[46,747,748],{"class":73}," r, ",[46,750,608],{"class":145},[46,752,754],{"class":48,"line":753},31,[46,755,392],{"class":73},[46,757,759],{"class":48,"line":758},32,[46,760,64],{"emptyLinePlaceholder":63},[46,762,764],{"class":48,"line":763},33,[46,765,766],{"class":126},"\u002F\u002F For arbitrary precision — use math\u002Fbig:\n",[46,768,770],{"class":48,"line":769},34,[46,771,772],{"class":126},"\u002F\u002F import \"math\u002Fbig\"\n",[46,774,776],{"class":48,"line":775},35,[46,777,778],{"class":126},"\u002F\u002F result := new(big.Int).Mul(big.NewInt(a), big.NewInt(b))\n",[14,780,782],{"id":781},"ieee-754-float64-precision-traps","IEEE 754 Float64 — Precision Traps",[19,784,785],{"language":38},[23,786,788],{"className":41,"code":787,"language":38,"meta":28,"style":28},"package main\n\nimport (\n    \"fmt\"\n    \"math\"\n)\n\nfunc floatTraps() {\n    \u002F\u002F 1. The classic: 0.1 + 0.2 ≠ 0.3\n    fmt.Println(0.1 + 0.2 == 0.3)  \u002F\u002F false\n    fmt.Printf(\"%.20f\\n\", 0.1+0.2) \u002F\u002F 0.30000000000000004441\n\n    \u002F\u002F 2. Comparing floats — use an epsilon:\n    func almostEqual(a, b float64) bool {\n        return math.Abs(a-b) \u003C= 1e-9 * math.Max(math.Abs(a), math.Abs(b))\n    }\n\n    \u002F\u002F 3. NaN doesn't equal itself:\n    nan := math.NaN()\n    fmt.Println(nan == nan)  \u002F\u002F false — use math.IsNaN()\n\n    \u002F\u002F 4. Inf comparisons:\n    fmt.Println(math.Inf(1) > 1e308)  \u002F\u002F true\n    fmt.Println(math.Inf(1) == math.Inf(1))  \u002F\u002F true (unlike NaN)\n\n    \u002F\u002F 5. Integer precision limit: float64 can represent integers\n    \u002F\u002F    exactly up to 2^53. Beyond that, precision is lost:\n    fmt.Println(float64(1\u003C\u003C53))     \u002F\u002F 9007199254740992 (exact)\n    fmt.Println(float64(1\u003C\u003C53 + 1)) \u002F\u002F 9007199254740992 (SAME — rounded!)\n    fmt.Println(float64(1\u003C\u003C53 + 2)) \u002F\u002F 9007199254740994 (exact, +2 is representable)\n}\n",[30,789,790,796,800,806,814,823,827,831,840,845,873,904,908,913,932,982,986,990,995,1010,1027,1031,1036,1069,1101,1105,1110,1115,1141,1169,1197],{"__ignoreMap":28},[46,791,792,794],{"class":48,"line":49},[46,793,53],{"class":52},[46,795,57],{"class":56},[46,797,798],{"class":48,"line":60},[46,799,64],{"emptyLinePlaceholder":63},[46,801,802,804],{"class":48,"line":67},[46,803,70],{"class":52},[46,805,74],{"class":73},[46,807,808,810,812],{"class":48,"line":77},[46,809,81],{"class":80},[46,811,84],{"class":56},[46,813,87],{"class":80},[46,815,816,818,821],{"class":48,"line":90},[46,817,81],{"class":80},[46,819,820],{"class":56},"math",[46,822,87],{"class":80},[46,824,825],{"class":48,"line":100},[46,826,103],{"class":73},[46,828,829],{"class":48,"line":106},[46,830,64],{"emptyLinePlaceholder":63},[46,832,833,835,838],{"class":48,"line":111},[46,834,114],{"class":52},[46,836,837],{"class":56}," floatTraps",[46,839,120],{"class":73},[46,841,842],{"class":48,"line":123},[46,843,844],{"class":126},"    \u002F\u002F 1. The classic: 0.1 + 0.2 ≠ 0.3\n",[46,846,847,849,851,853,856,859,862,865,868,870],{"class":48,"line":130},[46,848,164],{"class":73},[46,850,167],{"class":56},[46,852,311],{"class":73},[46,854,855],{"class":145},"0.1",[46,857,858],{"class":52}," +",[46,860,861],{"class":145}," 0.2",[46,863,864],{"class":52}," ==",[46,866,867],{"class":145}," 0.3",[46,869,328],{"class":73},[46,871,872],{"class":126},"\u002F\u002F false\n",[46,874,875,877,880,882,885,888,890,892,894,896,899,901],{"class":48,"line":149},[46,876,164],{"class":73},[46,878,879],{"class":56},"Printf",[46,881,311],{"class":73},[46,883,884],{"class":80},"\"",[46,886,887],{"class":145},"%.20f\\n",[46,889,884],{"class":80},[46,891,462],{"class":73},[46,893,855],{"class":145},[46,895,270],{"class":52},[46,897,898],{"class":145},"0.2",[46,900,253],{"class":73},[46,902,903],{"class":126},"\u002F\u002F 0.30000000000000004441\n",[46,905,906],{"class":48,"line":161},[46,907,64],{"emptyLinePlaceholder":63},[46,909,910],{"class":48,"line":176},[46,911,912],{"class":126},"    \u002F\u002F 2. Comparing floats — use an epsilon:\n",[46,914,915,917,920,922,925,927,930],{"class":48,"line":181},[46,916,241],{"class":52},[46,918,919],{"class":56}," almostEqual",[46,921,247],{"class":73},[46,923,924],{"class":52},"float64",[46,926,253],{"class":73},[46,928,929],{"class":52},"bool",[46,931,258],{"class":73},[46,933,934,936,939,942,945,947,950,953,955,958,961,964,966,969,972,974,977,979],{"class":48,"line":187},[46,935,264],{"class":52},[46,937,938],{"class":73}," math.",[46,940,941],{"class":56},"Abs",[46,943,944],{"class":73},"(a",[46,946,511],{"class":52},[46,948,949],{"class":73},"b) ",[46,951,952],{"class":52},"\u003C=",[46,954,346],{"class":145},[46,956,957],{"class":52},"e-",[46,959,960],{"class":145},"9",[46,962,963],{"class":52}," *",[46,965,938],{"class":73},[46,967,968],{"class":56},"Max",[46,970,971],{"class":73},"(math.",[46,973,941],{"class":56},[46,975,976],{"class":73},"(a), math.",[46,978,941],{"class":56},[46,980,981],{"class":73},"(b))\n",[46,983,984],{"class":48,"line":203},[46,985,282],{"class":73},[46,987,988],{"class":48,"line":214},[46,989,64],{"emptyLinePlaceholder":63},[46,991,992],{"class":48,"line":227},[46,993,994],{"class":126},"    \u002F\u002F 3. NaN doesn't equal itself:\n",[46,996,997,1000,1002,1004,1007],{"class":48,"line":232},[46,998,999],{"class":73},"    nan ",[46,1001,302],{"class":52},[46,1003,938],{"class":73},[46,1005,1006],{"class":56},"NaN",[46,1008,1009],{"class":73},"()\n",[46,1011,1012,1014,1016,1019,1021,1024],{"class":48,"line":238},[46,1013,164],{"class":73},[46,1015,167],{"class":56},[46,1017,1018],{"class":73},"(nan ",[46,1020,343],{"class":52},[46,1022,1023],{"class":73}," nan)  ",[46,1025,1026],{"class":126},"\u002F\u002F false — use math.IsNaN()\n",[46,1028,1029],{"class":48,"line":261},[46,1030,64],{"emptyLinePlaceholder":63},[46,1032,1033],{"class":48,"line":279},[46,1034,1035],{"class":126},"    \u002F\u002F 4. Inf comparisons:\n",[46,1037,1038,1040,1042,1044,1047,1049,1052,1054,1056,1058,1061,1064,1066],{"class":48,"line":285},[46,1039,164],{"class":73},[46,1041,167],{"class":56},[46,1043,971],{"class":73},[46,1045,1046],{"class":56},"Inf",[46,1048,311],{"class":73},[46,1050,1051],{"class":145},"1",[46,1053,253],{"class":73},[46,1055,492],{"class":52},[46,1057,346],{"class":145},[46,1059,1060],{"class":52},"e",[46,1062,1063],{"class":145},"308",[46,1065,328],{"class":73},[46,1067,1068],{"class":126},"\u002F\u002F true\n",[46,1070,1071,1073,1075,1077,1079,1081,1083,1085,1087,1089,1091,1093,1095,1098],{"class":48,"line":290},[46,1072,164],{"class":73},[46,1074,167],{"class":56},[46,1076,971],{"class":73},[46,1078,1046],{"class":56},[46,1080,311],{"class":73},[46,1082,1051],{"class":145},[46,1084,253],{"class":73},[46,1086,343],{"class":52},[46,1088,938],{"class":73},[46,1090,1046],{"class":56},[46,1092,311],{"class":73},[46,1094,1051],{"class":145},[46,1096,1097],{"class":73},"))  ",[46,1099,1100],{"class":126},"\u002F\u002F true (unlike NaN)\n",[46,1102,1103],{"class":48,"line":296},[46,1104,64],{"emptyLinePlaceholder":63},[46,1106,1107],{"class":48,"line":334},[46,1108,1109],{"class":126},"    \u002F\u002F 5. Integer precision limit: float64 can represent integers\n",[46,1111,1112],{"class":48,"line":351},[46,1113,1114],{"class":126},"    \u002F\u002F    exactly up to 2^53. Beyond that, precision is lost:\n",[46,1116,1117,1119,1121,1123,1125,1127,1129,1132,1135,1138],{"class":48,"line":372},[46,1118,164],{"class":73},[46,1120,167],{"class":56},[46,1122,311],{"class":73},[46,1124,924],{"class":52},[46,1126,311],{"class":73},[46,1128,1051],{"class":145},[46,1130,1131],{"class":52},"\u003C\u003C",[46,1133,1134],{"class":145},"53",[46,1136,1137],{"class":73},"))     ",[46,1139,1140],{"class":126},"\u002F\u002F 9007199254740992 (exact)\n",[46,1142,1143,1145,1147,1149,1151,1153,1155,1157,1159,1161,1163,1166],{"class":48,"line":377},[46,1144,164],{"class":73},[46,1146,167],{"class":56},[46,1148,311],{"class":73},[46,1150,924],{"class":52},[46,1152,311],{"class":73},[46,1154,1051],{"class":145},[46,1156,1131],{"class":52},[46,1158,1134],{"class":145},[46,1160,858],{"class":52},[46,1162,346],{"class":145},[46,1164,1165],{"class":73},")) ",[46,1167,1168],{"class":126},"\u002F\u002F 9007199254740992 (SAME — rounded!)\n",[46,1170,1171,1173,1175,1177,1179,1181,1183,1185,1187,1189,1192,1194],{"class":48,"line":389},[46,1172,164],{"class":73},[46,1174,167],{"class":56},[46,1176,311],{"class":73},[46,1178,924],{"class":52},[46,1180,311],{"class":73},[46,1182,1051],{"class":145},[46,1184,1131],{"class":52},[46,1186,1134],{"class":145},[46,1188,858],{"class":52},[46,1190,1191],{"class":145}," 2",[46,1193,1165],{"class":73},[46,1195,1196],{"class":126},"\u002F\u002F 9007199254740994 (exact, +2 is representable)\n",[46,1198,1199],{"class":48,"line":753},[46,1200,392],{"class":73},[394,1202,1204],{"id":1203},"money-never-use-float64","Money — never use float64",[19,1206,1207],{"language":38},[23,1208,1210],{"className":41,"code":1209,"language":38,"meta":28,"style":28},"\u002F\u002F ❌ ANTI-PATTERN: float64 for money\nfunc badTotal(prices []float64) float64 {\n    total := 0.0\n    for _, p := range prices {\n        total += p  \u002F\u002F accumulating rounding errors\n    }\n    return total\n}\n\u002F\u002F badTotal([]float64{0.10, 0.20, 0.30}) → 0.6000000000000001\n\n\u002F\u002F ✅ CORRECT: use shopspring\u002Fdecimal or math\u002Fbig for exact decimal math\n\u002F\u002F\n\u002F\u002F import \"github.com\u002Fshopspring\u002Fdecimal\"\n\u002F\u002F func goodTotal(prices []decimal.Decimal) decimal.Decimal {\n\u002F\u002F     total := decimal.Zero\n\u002F\u002F     for _, p := range prices {\n\u002F\u002F         total = total.Add(p)  \u002F\u002F exact base-10 arithmetic\n\u002F\u002F     }\n\u002F\u002F     return total\n\u002F\u002F }\n\n\u002F\u002F ✅ Or store money as integer cents (simplest, no deps):\ntype Cents int64  \u002F\u002F $1.00 = 100 cents — never lose precision\n\nfunc totalCents(prices []Cents) Cents {\n    var total Cents\n    for _, p := range prices {\n        total += p  \u002F\u002F integer arithmetic — exact\n    }\n    return total\n}\n\nfunc (c Cents) String() string {\n    return fmt.Sprintf(\"$%d.%02d\", c\u002F100, c%100)  \u002F\u002F $12.34\n}\n",[30,1211,1212,1217,1240,1250,1266,1280,1284,1291,1295,1300,1304,1309,1314,1319,1324,1329,1334,1342,1347,1352,1357,1361,1366,1379,1383,1405,1415,1427,1438,1442,1448,1452,1456,1481,1527],{"__ignoreMap":28},[46,1213,1214],{"class":48,"line":49},[46,1215,1216],{"class":126},"\u002F\u002F ❌ ANTI-PATTERN: float64 for money\n",[46,1218,1219,1221,1224,1226,1229,1232,1234,1236,1238],{"class":48,"line":60},[46,1220,114],{"class":52},[46,1222,1223],{"class":56}," badTotal",[46,1225,311],{"class":73},[46,1227,1228],{"class":458},"prices",[46,1230,1231],{"class":73}," []",[46,1233,924],{"class":52},[46,1235,253],{"class":73},[46,1237,924],{"class":52},[46,1239,258],{"class":73},[46,1241,1242,1245,1247],{"class":48,"line":67},[46,1243,1244],{"class":73},"    total ",[46,1246,302],{"class":52},[46,1248,1249],{"class":145}," 0.0\n",[46,1251,1252,1255,1258,1260,1263],{"class":48,"line":77},[46,1253,1254],{"class":52},"    for",[46,1256,1257],{"class":73}," _, p ",[46,1259,302],{"class":52},[46,1261,1262],{"class":52}," range",[46,1264,1265],{"class":73}," prices {\n",[46,1267,1268,1271,1274,1277],{"class":48,"line":90},[46,1269,1270],{"class":73},"        total ",[46,1272,1273],{"class":52},"+=",[46,1275,1276],{"class":73}," p  ",[46,1278,1279],{"class":126},"\u002F\u002F accumulating rounding errors\n",[46,1281,1282],{"class":48,"line":100},[46,1283,282],{"class":73},[46,1285,1286,1288],{"class":48,"line":106},[46,1287,598],{"class":52},[46,1289,1290],{"class":73}," total\n",[46,1292,1293],{"class":48,"line":111},[46,1294,392],{"class":73},[46,1296,1297],{"class":48,"line":123},[46,1298,1299],{"class":126},"\u002F\u002F badTotal([]float64{0.10, 0.20, 0.30}) → 0.6000000000000001\n",[46,1301,1302],{"class":48,"line":130},[46,1303,64],{"emptyLinePlaceholder":63},[46,1305,1306],{"class":48,"line":149},[46,1307,1308],{"class":126},"\u002F\u002F ✅ CORRECT: use shopspring\u002Fdecimal or math\u002Fbig for exact decimal math\n",[46,1310,1311],{"class":48,"line":161},[46,1312,1313],{"class":126},"\u002F\u002F\n",[46,1315,1316],{"class":48,"line":176},[46,1317,1318],{"class":126},"\u002F\u002F import \"github.com\u002Fshopspring\u002Fdecimal\"\n",[46,1320,1321],{"class":48,"line":181},[46,1322,1323],{"class":126},"\u002F\u002F func goodTotal(prices []decimal.Decimal) decimal.Decimal {\n",[46,1325,1326],{"class":48,"line":187},[46,1327,1328],{"class":126},"\u002F\u002F     total := decimal.Zero\n",[46,1330,1331],{"class":48,"line":203},[46,1332,1333],{"class":126},"\u002F\u002F     for _, p := range prices {\n",[46,1335,1336,1339],{"class":48,"line":214},[46,1337,1338],{"class":126},"\u002F\u002F         total = total.Add(p)",[46,1340,1341],{"class":126},"  \u002F\u002F exact base-10 arithmetic\n",[46,1343,1344],{"class":48,"line":227},[46,1345,1346],{"class":126},"\u002F\u002F     }\n",[46,1348,1349],{"class":48,"line":232},[46,1350,1351],{"class":126},"\u002F\u002F     return total\n",[46,1353,1354],{"class":48,"line":238},[46,1355,1356],{"class":126},"\u002F\u002F }\n",[46,1358,1359],{"class":48,"line":261},[46,1360,64],{"emptyLinePlaceholder":63},[46,1362,1363],{"class":48,"line":279},[46,1364,1365],{"class":126},"\u002F\u002F ✅ Or store money as integer cents (simplest, no deps):\n",[46,1367,1368,1371,1374,1376],{"class":48,"line":285},[46,1369,1370],{"class":52},"type",[46,1372,1373],{"class":56}," Cents",[46,1375,468],{"class":52},[46,1377,1378],{"class":126},"  \u002F\u002F $1.00 = 100 cents — never lose precision\n",[46,1380,1381],{"class":48,"line":290},[46,1382,64],{"emptyLinePlaceholder":63},[46,1384,1385,1387,1390,1392,1394,1396,1399,1401,1403],{"class":48,"line":296},[46,1386,114],{"class":52},[46,1388,1389],{"class":56}," totalCents",[46,1391,311],{"class":73},[46,1393,1228],{"class":458},[46,1395,1231],{"class":73},[46,1397,1398],{"class":56},"Cents",[46,1400,253],{"class":73},[46,1402,1398],{"class":56},[46,1404,258],{"class":73},[46,1406,1407,1409,1412],{"class":48,"line":334},[46,1408,133],{"class":52},[46,1410,1411],{"class":73}," total ",[46,1413,1414],{"class":56},"Cents\n",[46,1416,1417,1419,1421,1423,1425],{"class":48,"line":351},[46,1418,1254],{"class":52},[46,1420,1257],{"class":73},[46,1422,302],{"class":52},[46,1424,1262],{"class":52},[46,1426,1265],{"class":73},[46,1428,1429,1431,1433,1435],{"class":48,"line":372},[46,1430,1270],{"class":73},[46,1432,1273],{"class":52},[46,1434,1276],{"class":73},[46,1436,1437],{"class":126},"\u002F\u002F integer arithmetic — exact\n",[46,1439,1440],{"class":48,"line":377},[46,1441,282],{"class":73},[46,1443,1444,1446],{"class":48,"line":389},[46,1445,598],{"class":52},[46,1447,1290],{"class":73},[46,1449,1450],{"class":48,"line":753},[46,1451,392],{"class":73},[46,1453,1454],{"class":48,"line":758},[46,1455,64],{"emptyLinePlaceholder":63},[46,1457,1458,1460,1463,1466,1468,1470,1473,1476,1479],{"class":48,"line":763},[46,1459,114],{"class":52},[46,1461,1462],{"class":73}," (",[46,1464,1465],{"class":458},"c ",[46,1467,1398],{"class":56},[46,1469,253],{"class":73},[46,1471,1472],{"class":56},"String",[46,1474,1475],{"class":73},"() ",[46,1477,1478],{"class":52},"string",[46,1480,258],{"class":73},[46,1482,1483,1485,1488,1491,1493,1496,1499,1502,1505,1507,1510,1512,1515,1517,1520,1522,1524],{"class":48,"line":769},[46,1484,598],{"class":52},[46,1486,1487],{"class":73}," fmt.",[46,1489,1490],{"class":56},"Sprintf",[46,1492,311],{"class":73},[46,1494,1495],{"class":80},"\"$",[46,1497,1498],{"class":145},"%d",[46,1500,1501],{"class":80},".",[46,1503,1504],{"class":145},"%02d",[46,1506,884],{"class":80},[46,1508,1509],{"class":73},", c",[46,1511,708],{"class":52},[46,1513,1514],{"class":145},"100",[46,1516,1509],{"class":73},[46,1518,1519],{"class":52},"%",[46,1521,1514],{"class":145},[46,1523,328],{"class":73},[46,1525,1526],{"class":126},"\u002F\u002F $12.34\n",[46,1528,1529],{"class":48,"line":775},[46,1530,392],{"class":73},[14,1532,1534],{"id":1533},"string-internals-the-memory-layout","String Internals — The Memory Layout",[19,1536,1537],{"language":38},[23,1538,1540],{"className":41,"code":1539,"language":38,"meta":28,"style":28},"\u002F\u002F A Go string is a 2-word header: {pointer to data, length}\n\u002F\u002F   - The data is READ-ONLY (stored in read-only memory or the string table)\n\u002F\u002F   - The pointer can be nil (empty string) — but \"\" has a non-nil ptr in practice\n\u002F\u002F   - len(s) is the BYTE count, NOT the character count\n\n\u002F\u002F ┌─────────────────────────────────────────────────┐\n\u002F\u002F │ string header (16 bytes on 64-bit)             │\n\u002F\u002F │   ┌──────────┬──────────┐                      │\n\u002F\u002F │   │ ptr      │ len      │                      │\n\u002F\u002F │   │ 8 bytes  │ 8 bytes  │                      │\n\u002F\u002F │   └──────────┴──────────┘                      │\n\u002F\u002F │        ↓                                        │\n\u002F\u002F │   [H][e][l][l][o][,][ ][ä][\\\\xb6]... (read-only)│\n\u002F\u002F │   'ä' is 2 bytes in UTF-8 (0xC3 0xA4)          │\n\u002F\u002F └─────────────────────────────────────────────────┘\n\nfunc stringInternals() {\n    s := \"Hello, 世界\"\n    fmt.Println(len(s))                    \u002F\u002F 13 (bytes: \"Hello, \" = 7, \"世\" = 3, \"界\" = 3)\n    fmt.Println(utf8.RuneCountInString(s)) \u002F\u002F 9 (characters)\n\n    \u002F\u002F Indexing gives bytes (uint8), not characters:\n    fmt.Println(s[0])     \u002F\u002F 72 (byte for 'H')\n    fmt.Println(s[7])     \u002F\u002F 228 (first byte of '世' — 0xE4)\n\n    \u002F\u002F ❌ Can't index a character in O(1) — UTF-8 is variable-width.\n    \u002F\u002F s[7] is a BYTE, not '世'. To get rune at position 7:\n    r, size := utf8.DecodeRuneInString(s[7:])\n    fmt.Printf(\"%c (size=%d)\\n\", r, size)  \u002F\u002F 世 (size=3)\n\n    \u002F\u002F Slicing by bytes — valid only at rune boundaries:\n    sub := s[:7]  \u002F\u002F \"Hello, \" — valid (7 is a rune boundary)\n    \u002F\u002F sub = s[:8]  \u002F\u002F invalid UTF-8 — cuts '世' mid-rune (no error, but broken)\n    _ = sub\n}\n",[30,1541,1542,1547,1552,1557,1562,1566,1571,1576,1581,1586,1591,1596,1601,1606,1611,1616,1620,1629,1639,1656,1674,1678,1683,1700,1716,1720,1725,1730,1750,1782,1786,1791,1809,1817,1826],{"__ignoreMap":28},[46,1543,1544],{"class":48,"line":49},[46,1545,1546],{"class":126},"\u002F\u002F A Go string is a 2-word header: {pointer to data, length}\n",[46,1548,1549],{"class":48,"line":60},[46,1550,1551],{"class":126},"\u002F\u002F   - The data is READ-ONLY (stored in read-only memory or the string table)\n",[46,1553,1554],{"class":48,"line":67},[46,1555,1556],{"class":126},"\u002F\u002F   - The pointer can be nil (empty string) — but \"\" has a non-nil ptr in practice\n",[46,1558,1559],{"class":48,"line":77},[46,1560,1561],{"class":126},"\u002F\u002F   - len(s) is the BYTE count, NOT the character count\n",[46,1563,1564],{"class":48,"line":90},[46,1565,64],{"emptyLinePlaceholder":63},[46,1567,1568],{"class":48,"line":100},[46,1569,1570],{"class":126},"\u002F\u002F ┌─────────────────────────────────────────────────┐\n",[46,1572,1573],{"class":48,"line":106},[46,1574,1575],{"class":126},"\u002F\u002F │ string header (16 bytes on 64-bit)             │\n",[46,1577,1578],{"class":48,"line":111},[46,1579,1580],{"class":126},"\u002F\u002F │   ┌──────────┬──────────┐                      │\n",[46,1582,1583],{"class":48,"line":123},[46,1584,1585],{"class":126},"\u002F\u002F │   │ ptr      │ len      │                      │\n",[46,1587,1588],{"class":48,"line":130},[46,1589,1590],{"class":126},"\u002F\u002F │   │ 8 bytes  │ 8 bytes  │                      │\n",[46,1592,1593],{"class":48,"line":149},[46,1594,1595],{"class":126},"\u002F\u002F │   └──────────┴──────────┘                      │\n",[46,1597,1598],{"class":48,"line":161},[46,1599,1600],{"class":126},"\u002F\u002F │        ↓                                        │\n",[46,1602,1603],{"class":48,"line":176},[46,1604,1605],{"class":126},"\u002F\u002F │   [H][e][l][l][o][,][ ][ä][\\\\xb6]... (read-only)│\n",[46,1607,1608],{"class":48,"line":181},[46,1609,1610],{"class":126},"\u002F\u002F │   'ä' is 2 bytes in UTF-8 (0xC3 0xA4)          │\n",[46,1612,1613],{"class":48,"line":187},[46,1614,1615],{"class":126},"\u002F\u002F └─────────────────────────────────────────────────┘\n",[46,1617,1618],{"class":48,"line":203},[46,1619,64],{"emptyLinePlaceholder":63},[46,1621,1622,1624,1627],{"class":48,"line":214},[46,1623,114],{"class":52},[46,1625,1626],{"class":56}," stringInternals",[46,1628,120],{"class":73},[46,1630,1631,1634,1636],{"class":48,"line":227},[46,1632,1633],{"class":73},"    s ",[46,1635,302],{"class":52},[46,1637,1638],{"class":80}," \"Hello, 世界\"\n",[46,1640,1641,1643,1645,1647,1650,1653],{"class":48,"line":232},[46,1642,164],{"class":73},[46,1644,167],{"class":56},[46,1646,311],{"class":73},[46,1648,1649],{"class":56},"len",[46,1651,1652],{"class":73},"(s))                    ",[46,1654,1655],{"class":126},"\u002F\u002F 13 (bytes: \"Hello, \" = 7, \"世\" = 3, \"界\" = 3)\n",[46,1657,1658,1660,1662,1665,1668,1671],{"class":48,"line":238},[46,1659,164],{"class":73},[46,1661,167],{"class":56},[46,1663,1664],{"class":73},"(utf8.",[46,1666,1667],{"class":56},"RuneCountInString",[46,1669,1670],{"class":73},"(s)) ",[46,1672,1673],{"class":126},"\u002F\u002F 9 (characters)\n",[46,1675,1676],{"class":48,"line":261},[46,1677,64],{"emptyLinePlaceholder":63},[46,1679,1680],{"class":48,"line":279},[46,1681,1682],{"class":126},"    \u002F\u002F Indexing gives bytes (uint8), not characters:\n",[46,1684,1685,1687,1689,1692,1694,1697],{"class":48,"line":285},[46,1686,164],{"class":73},[46,1688,167],{"class":56},[46,1690,1691],{"class":73},"(s[",[46,1693,325],{"class":145},[46,1695,1696],{"class":73},"])     ",[46,1698,1699],{"class":126},"\u002F\u002F 72 (byte for 'H')\n",[46,1701,1702,1704,1706,1708,1711,1713],{"class":48,"line":290},[46,1703,164],{"class":73},[46,1705,167],{"class":56},[46,1707,1691],{"class":73},[46,1709,1710],{"class":145},"7",[46,1712,1696],{"class":73},[46,1714,1715],{"class":126},"\u002F\u002F 228 (first byte of '世' — 0xE4)\n",[46,1717,1718],{"class":48,"line":296},[46,1719,64],{"emptyLinePlaceholder":63},[46,1721,1722],{"class":48,"line":334},[46,1723,1724],{"class":126},"    \u002F\u002F ❌ Can't index a character in O(1) — UTF-8 is variable-width.\n",[46,1726,1727],{"class":48,"line":351},[46,1728,1729],{"class":126},"    \u002F\u002F s[7] is a BYTE, not '世'. To get rune at position 7:\n",[46,1731,1732,1735,1737,1740,1743,1745,1747],{"class":48,"line":372},[46,1733,1734],{"class":73},"    r, size ",[46,1736,302],{"class":52},[46,1738,1739],{"class":73}," utf8.",[46,1741,1742],{"class":56},"DecodeRuneInString",[46,1744,1691],{"class":73},[46,1746,1710],{"class":145},[46,1748,1749],{"class":73},":])\n",[46,1751,1752,1754,1756,1758,1760,1763,1766,1768,1771,1774,1776,1779],{"class":48,"line":377},[46,1753,164],{"class":73},[46,1755,879],{"class":56},[46,1757,311],{"class":73},[46,1759,884],{"class":80},[46,1761,1762],{"class":145},"%c",[46,1764,1765],{"class":80}," (size=",[46,1767,1498],{"class":145},[46,1769,1770],{"class":80},")",[46,1772,1773],{"class":145},"\\n",[46,1775,884],{"class":80},[46,1777,1778],{"class":73},", r, size)  ",[46,1780,1781],{"class":126},"\u002F\u002F 世 (size=3)\n",[46,1783,1784],{"class":48,"line":389},[46,1785,64],{"emptyLinePlaceholder":63},[46,1787,1788],{"class":48,"line":753},[46,1789,1790],{"class":126},"    \u002F\u002F Slicing by bytes — valid only at rune boundaries:\n",[46,1792,1793,1796,1798,1801,1803,1806],{"class":48,"line":758},[46,1794,1795],{"class":73},"    sub ",[46,1797,302],{"class":52},[46,1799,1800],{"class":73}," s[:",[46,1802,1710],{"class":145},[46,1804,1805],{"class":73},"]  ",[46,1807,1808],{"class":126},"\u002F\u002F \"Hello, \" — valid (7 is a rune boundary)\n",[46,1810,1811,1814],{"class":48,"line":763},[46,1812,1813],{"class":126},"    \u002F\u002F sub = s[:8]",[46,1815,1816],{"class":126},"  \u002F\u002F invalid UTF-8 — cuts '世' mid-rune (no error, but broken)\n",[46,1818,1819,1821,1823],{"class":48,"line":769},[46,1820,380],{"class":73},[46,1822,383],{"class":52},[46,1824,1825],{"class":73}," sub\n",[46,1827,1828],{"class":48,"line":775},[46,1829,392],{"class":73},[394,1831,1833,1836],{"id":1832},"range-over-strings-free-utf-8-decoding",[30,1834,1835],{},"range"," over strings — free UTF-8 decoding",[19,1838,1839],{"language":38},[23,1840,1842],{"className":41,"code":1841,"language":38,"meta":28,"style":28},"func rangeString() {\n    s := \"Go=go\"\n\n    \u002F\u002F range decodes UTF-8 and yields (byte_offset, rune):\n    for i, r := range s {\n        fmt.Printf(\"offset=%d rune=%c (U+%04X)\\n\", i, r, r)\n    }\n    \u002F\u002F offset=0 rune=G (U+0047)\n    \u002F\u002F offset=1 rune=o (U+006F)\n    \u002F\u002F offset=2 rune== (U+003D)\n    \u002F\u002F offset=3 rune=世 (U+4E16)  ← offset jumps by 3 bytes (UTF-8 width of 世)\n    \u002F\u002F offset=6 rune=界 (U+754C)\n\n    \u002F\u002F ⚠️ The index is the BYTE offset, not the character index.\n    \u002F\u002F If you need character index, use a counter:\n    charIdx := 0\n    for _, r := range s {\n        fmt.Printf(\"char[%d]=%c\\n\", charIdx, r)\n        charIdx++\n    }\n}\n",[30,1843,1844,1853,1862,1866,1871,1885,1919,1923,1928,1933,1938,1943,1948,1952,1957,1962,1972,1985,2009,2017,2021],{"__ignoreMap":28},[46,1845,1846,1848,1851],{"class":48,"line":49},[46,1847,114],{"class":52},[46,1849,1850],{"class":56}," rangeString",[46,1852,120],{"class":73},[46,1854,1855,1857,1859],{"class":48,"line":60},[46,1856,1633],{"class":73},[46,1858,302],{"class":52},[46,1860,1861],{"class":80}," \"Go=go\"\n",[46,1863,1864],{"class":48,"line":67},[46,1865,64],{"emptyLinePlaceholder":63},[46,1867,1868],{"class":48,"line":77},[46,1869,1870],{"class":126},"    \u002F\u002F range decodes UTF-8 and yields (byte_offset, rune):\n",[46,1872,1873,1875,1878,1880,1882],{"class":48,"line":90},[46,1874,1254],{"class":52},[46,1876,1877],{"class":73}," i, r ",[46,1879,302],{"class":52},[46,1881,1262],{"class":52},[46,1883,1884],{"class":73}," s {\n",[46,1886,1887,1890,1892,1894,1897,1899,1902,1904,1907,1910,1912,1914,1916],{"class":48,"line":100},[46,1888,1889],{"class":73},"        fmt.",[46,1891,879],{"class":56},[46,1893,311],{"class":73},[46,1895,1896],{"class":80},"\"offset=",[46,1898,1498],{"class":145},[46,1900,1901],{"class":80}," rune=",[46,1903,1762],{"class":145},[46,1905,1906],{"class":80}," (U+",[46,1908,1909],{"class":145},"%04X",[46,1911,1770],{"class":80},[46,1913,1773],{"class":145},[46,1915,884],{"class":80},[46,1917,1918],{"class":73},", i, r, r)\n",[46,1920,1921],{"class":48,"line":106},[46,1922,282],{"class":73},[46,1924,1925],{"class":48,"line":111},[46,1926,1927],{"class":126},"    \u002F\u002F offset=0 rune=G (U+0047)\n",[46,1929,1930],{"class":48,"line":123},[46,1931,1932],{"class":126},"    \u002F\u002F offset=1 rune=o (U+006F)\n",[46,1934,1935],{"class":48,"line":130},[46,1936,1937],{"class":126},"    \u002F\u002F offset=2 rune== (U+003D)\n",[46,1939,1940],{"class":48,"line":149},[46,1941,1942],{"class":126},"    \u002F\u002F offset=3 rune=世 (U+4E16)  ← offset jumps by 3 bytes (UTF-8 width of 世)\n",[46,1944,1945],{"class":48,"line":161},[46,1946,1947],{"class":126},"    \u002F\u002F offset=6 rune=界 (U+754C)\n",[46,1949,1950],{"class":48,"line":176},[46,1951,64],{"emptyLinePlaceholder":63},[46,1953,1954],{"class":48,"line":181},[46,1955,1956],{"class":126},"    \u002F\u002F ⚠️ The index is the BYTE offset, not the character index.\n",[46,1958,1959],{"class":48,"line":187},[46,1960,1961],{"class":126},"    \u002F\u002F If you need character index, use a counter:\n",[46,1963,1964,1967,1969],{"class":48,"line":203},[46,1965,1966],{"class":73},"    charIdx ",[46,1968,302],{"class":52},[46,1970,1971],{"class":145}," 0\n",[46,1973,1974,1976,1979,1981,1983],{"class":48,"line":214},[46,1975,1254],{"class":52},[46,1977,1978],{"class":73}," _, r ",[46,1980,302],{"class":52},[46,1982,1262],{"class":52},[46,1984,1884],{"class":73},[46,1986,1987,1989,1991,1993,1996,1998,2001,2004,2006],{"class":48,"line":227},[46,1988,1889],{"class":73},[46,1990,879],{"class":56},[46,1992,311],{"class":73},[46,1994,1995],{"class":80},"\"char[",[46,1997,1498],{"class":145},[46,1999,2000],{"class":80},"]=",[46,2002,2003],{"class":145},"%c\\n",[46,2005,884],{"class":80},[46,2007,2008],{"class":73},", charIdx, r)\n",[46,2010,2011,2014],{"class":48,"line":232},[46,2012,2013],{"class":73},"        charIdx",[46,2015,2016],{"class":52},"++\n",[46,2018,2019],{"class":48,"line":238},[46,2020,282],{"class":73},[46,2022,2023],{"class":48,"line":261},[46,2024,392],{"class":73},[14,2026,2028],{"id":2027},"conversions-the-cost-table","Conversions — The Cost Table",[19,2030,2031],{"language":38},[23,2032,2034],{"className":41,"code":2033,"language":38,"meta":28,"style":28},"\u002F\u002F ┌──────────────────────────────────────────────────────────────────────┐\n\u002F\u002F │ Conversion           │ Allocates? │ Notes                            │\n\u002F\u002F │ ──────────────────── │ ────────── │ ──────────────────────────────── │\n\u002F\u002F │ int → float64        │ No         │ CPU instruction (CVTSI2SD)      │\n\u002F\u002F │ float64 → int        │ No         │ Truncates toward zero            │\n\u002F\u002F │ int → string         │ Yes        │ string(65) = \"A\" (code point!)   │\n\u002F\u002F │ []byte ↔ string      │ Yes        │ Copies (strings are immutable)   │\n\u002F\u002F │ []rune ↔ string      │ Yes        │ Decodes\u002Fencodes UTF-8            │\n\u002F\u002F │ []byte → []rune      │ Yes        │ Decodes UTF-8                    │\n\u002F\u002F │ T → *T (with &)      │ No         │ Address-of operator              │\n\u002F\u002F │ []T → []U (diff T)   │ Yes        │ Element-by-element copy          │\n\u002F\u002F └──────────────────────────────────────────────────────────────────────┘\n\n\u002F\u002F The []byte ↔ string copy is the #1 hidden allocation in Go programs.\n\u002F\u002F It's necessary because strings are immutable (read-only memory) but\n\u002F\u002F []byte is mutable — they can't share storage safely.\n\nfunc conversionCosts() {\n    s := \"hello\"\n\n    \u002F\u002F ❌ Each conversion allocates a copy:\n    b := []byte(s)    \u002F\u002F allocates 5 bytes + slice header\n    s2 := string(b)   \u002F\u002F allocates 5 bytes + string header\n    _ = s2\n\n    \u002F\u002F ✅ For comparison, use strings\u002Fbytes packages (no conversion needed):\n    \u002F\u002F strings.Contains(s, \"ell\")     — works on string directly\n    \u002F\u002F bytes.Contains(b, []byte(\"ell\")) — works on []byte directly\n\n    \u002F\u002F ✅ For zero-copy (Go 1.20+, unsafe — only when you control the data):\n    \u002F\u002F import \"unsafe\"\n    \u002F\u002F b := unsafe.Slice(unsafe.StringData(s), len(s))  \u002F\u002F []byte sharing s's memory\n    \u002F\u002F ⚠️ Only safe if you NEVER modify b (modifying corrupts the read-only string table)\n}\n",[30,2035,2036,2041,2046,2051,2056,2061,2066,2071,2076,2081,2086,2091,2096,2100,2105,2110,2115,2119,2128,2137,2141,2146,2164,2180,2189,2193,2198,2203,2208,2212,2217,2222,2230,2235],{"__ignoreMap":28},[46,2037,2038],{"class":48,"line":49},[46,2039,2040],{"class":126},"\u002F\u002F ┌──────────────────────────────────────────────────────────────────────┐\n",[46,2042,2043],{"class":48,"line":60},[46,2044,2045],{"class":126},"\u002F\u002F │ Conversion           │ Allocates? │ Notes                            │\n",[46,2047,2048],{"class":48,"line":67},[46,2049,2050],{"class":126},"\u002F\u002F │ ──────────────────── │ ────────── │ ──────────────────────────────── │\n",[46,2052,2053],{"class":48,"line":77},[46,2054,2055],{"class":126},"\u002F\u002F │ int → float64        │ No         │ CPU instruction (CVTSI2SD)      │\n",[46,2057,2058],{"class":48,"line":90},[46,2059,2060],{"class":126},"\u002F\u002F │ float64 → int        │ No         │ Truncates toward zero            │\n",[46,2062,2063],{"class":48,"line":100},[46,2064,2065],{"class":126},"\u002F\u002F │ int → string         │ Yes        │ string(65) = \"A\" (code point!)   │\n",[46,2067,2068],{"class":48,"line":106},[46,2069,2070],{"class":126},"\u002F\u002F │ []byte ↔ string      │ Yes        │ Copies (strings are immutable)   │\n",[46,2072,2073],{"class":48,"line":111},[46,2074,2075],{"class":126},"\u002F\u002F │ []rune ↔ string      │ Yes        │ Decodes\u002Fencodes UTF-8            │\n",[46,2077,2078],{"class":48,"line":123},[46,2079,2080],{"class":126},"\u002F\u002F │ []byte → []rune      │ Yes        │ Decodes UTF-8                    │\n",[46,2082,2083],{"class":48,"line":130},[46,2084,2085],{"class":126},"\u002F\u002F │ T → *T (with &)      │ No         │ Address-of operator              │\n",[46,2087,2088],{"class":48,"line":149},[46,2089,2090],{"class":126},"\u002F\u002F │ []T → []U (diff T)   │ Yes        │ Element-by-element copy          │\n",[46,2092,2093],{"class":48,"line":161},[46,2094,2095],{"class":126},"\u002F\u002F └──────────────────────────────────────────────────────────────────────┘\n",[46,2097,2098],{"class":48,"line":176},[46,2099,64],{"emptyLinePlaceholder":63},[46,2101,2102],{"class":48,"line":181},[46,2103,2104],{"class":126},"\u002F\u002F The []byte ↔ string copy is the #1 hidden allocation in Go programs.\n",[46,2106,2107],{"class":48,"line":187},[46,2108,2109],{"class":126},"\u002F\u002F It's necessary because strings are immutable (read-only memory) but\n",[46,2111,2112],{"class":48,"line":203},[46,2113,2114],{"class":126},"\u002F\u002F []byte is mutable — they can't share storage safely.\n",[46,2116,2117],{"class":48,"line":214},[46,2118,64],{"emptyLinePlaceholder":63},[46,2120,2121,2123,2126],{"class":48,"line":227},[46,2122,114],{"class":52},[46,2124,2125],{"class":56}," conversionCosts",[46,2127,120],{"class":73},[46,2129,2130,2132,2134],{"class":48,"line":232},[46,2131,1633],{"class":73},[46,2133,302],{"class":52},[46,2135,2136],{"class":80}," \"hello\"\n",[46,2138,2139],{"class":48,"line":238},[46,2140,64],{"emptyLinePlaceholder":63},[46,2142,2143],{"class":48,"line":261},[46,2144,2145],{"class":126},"    \u002F\u002F ❌ Each conversion allocates a copy:\n",[46,2147,2148,2151,2153,2155,2158,2161],{"class":48,"line":279},[46,2149,2150],{"class":73},"    b ",[46,2152,302],{"class":52},[46,2154,1231],{"class":73},[46,2156,2157],{"class":52},"byte",[46,2159,2160],{"class":73},"(s)    ",[46,2162,2163],{"class":126},"\u002F\u002F allocates 5 bytes + slice header\n",[46,2165,2166,2169,2171,2174,2177],{"class":48,"line":285},[46,2167,2168],{"class":73},"    s2 ",[46,2170,302],{"class":52},[46,2172,2173],{"class":52}," string",[46,2175,2176],{"class":73},"(b)   ",[46,2178,2179],{"class":126},"\u002F\u002F allocates 5 bytes + string header\n",[46,2181,2182,2184,2186],{"class":48,"line":290},[46,2183,380],{"class":73},[46,2185,383],{"class":52},[46,2187,2188],{"class":73}," s2\n",[46,2190,2191],{"class":48,"line":296},[46,2192,64],{"emptyLinePlaceholder":63},[46,2194,2195],{"class":48,"line":334},[46,2196,2197],{"class":126},"    \u002F\u002F ✅ For comparison, use strings\u002Fbytes packages (no conversion needed):\n",[46,2199,2200],{"class":48,"line":351},[46,2201,2202],{"class":126},"    \u002F\u002F strings.Contains(s, \"ell\")     — works on string directly\n",[46,2204,2205],{"class":48,"line":372},[46,2206,2207],{"class":126},"    \u002F\u002F bytes.Contains(b, []byte(\"ell\")) — works on []byte directly\n",[46,2209,2210],{"class":48,"line":377},[46,2211,64],{"emptyLinePlaceholder":63},[46,2213,2214],{"class":48,"line":389},[46,2215,2216],{"class":126},"    \u002F\u002F ✅ For zero-copy (Go 1.20+, unsafe — only when you control the data):\n",[46,2218,2219],{"class":48,"line":753},[46,2220,2221],{"class":126},"    \u002F\u002F import \"unsafe\"\n",[46,2223,2224,2227],{"class":48,"line":758},[46,2225,2226],{"class":126},"    \u002F\u002F b := unsafe.Slice(unsafe.StringData(s), len(s))",[46,2228,2229],{"class":126},"  \u002F\u002F []byte sharing s's memory\n",[46,2231,2232],{"class":48,"line":763},[46,2233,2234],{"class":126},"    \u002F\u002F ⚠️ Only safe if you NEVER modify b (modifying corrupts the read-only string table)\n",[46,2236,2237],{"class":48,"line":769},[46,2238,392],{"class":73},[394,2240,2242,2243,2246],{"id":2241},"the-stringint-gotcha","The ",[30,2244,2245],{},"string(int)"," gotcha",[19,2248,2249],{"language":38},[23,2250,2252],{"className":41,"code":2251,"language":38,"meta":28,"style":28},"func stringIntGotcha() {\n    \u002F\u002F string(number) converts to a string containing that Unicode CODE POINT,\n    \u002F\u002F NOT the decimal representation of the number:\n    s := string(65)     \u002F\u002F \"A\" (code point 65 = 'A')\n    fmt.Println(s)      \u002F\u002F A\n\n    s2 := string(65290) \u002F\u002F \"％\" (fullwidth percent sign, U+FF05)\n    fmt.Println(s2)\n\n    \u002F\u002F ❌ Common mistake: expecting \"65\"\n    \u002F\u002F ✅ Use strconv for number-to-string:\n    correct := strconv.Itoa(65)       \u002F\u002F \"65\"\n    correct2 := strconv.FormatInt(65, 10)  \u002F\u002F \"65\"\n    fmt.Println(correct, correct2)\n\n    \u002F\u002F go vet catches this: \"conversion from int to string yields a string of\n    \u002F\u002F one rune, not a string of digits\" (vet's default check since Go 1.15)\n}\n",[30,2253,2254,2263,2268,2273,2292,2304,2308,2326,2335,2339,2344,2349,2372,2397,2406,2410,2415,2420],{"__ignoreMap":28},[46,2255,2256,2258,2261],{"class":48,"line":49},[46,2257,114],{"class":52},[46,2259,2260],{"class":56}," stringIntGotcha",[46,2262,120],{"class":73},[46,2264,2265],{"class":48,"line":60},[46,2266,2267],{"class":126},"    \u002F\u002F string(number) converts to a string containing that Unicode CODE POINT,\n",[46,2269,2270],{"class":48,"line":67},[46,2271,2272],{"class":126},"    \u002F\u002F NOT the decimal representation of the number:\n",[46,2274,2275,2277,2279,2281,2283,2286,2289],{"class":48,"line":77},[46,2276,1633],{"class":73},[46,2278,302],{"class":52},[46,2280,2173],{"class":52},[46,2282,311],{"class":73},[46,2284,2285],{"class":145},"65",[46,2287,2288],{"class":73},")     ",[46,2290,2291],{"class":126},"\u002F\u002F \"A\" (code point 65 = 'A')\n",[46,2293,2294,2296,2298,2301],{"class":48,"line":90},[46,2295,164],{"class":73},[46,2297,167],{"class":56},[46,2299,2300],{"class":73},"(s)      ",[46,2302,2303],{"class":126},"\u002F\u002F A\n",[46,2305,2306],{"class":48,"line":100},[46,2307,64],{"emptyLinePlaceholder":63},[46,2309,2310,2312,2314,2316,2318,2321,2323],{"class":48,"line":106},[46,2311,2168],{"class":73},[46,2313,302],{"class":52},[46,2315,2173],{"class":52},[46,2317,311],{"class":73},[46,2319,2320],{"class":145},"65290",[46,2322,253],{"class":73},[46,2324,2325],{"class":126},"\u002F\u002F \"％\" (fullwidth percent sign, U+FF05)\n",[46,2327,2328,2330,2332],{"class":48,"line":111},[46,2329,164],{"class":73},[46,2331,167],{"class":56},[46,2333,2334],{"class":73},"(s2)\n",[46,2336,2337],{"class":48,"line":123},[46,2338,64],{"emptyLinePlaceholder":63},[46,2340,2341],{"class":48,"line":130},[46,2342,2343],{"class":126},"    \u002F\u002F ❌ Common mistake: expecting \"65\"\n",[46,2345,2346],{"class":48,"line":149},[46,2347,2348],{"class":126},"    \u002F\u002F ✅ Use strconv for number-to-string:\n",[46,2350,2351,2354,2356,2359,2362,2364,2366,2369],{"class":48,"line":161},[46,2352,2353],{"class":73},"    correct ",[46,2355,302],{"class":52},[46,2357,2358],{"class":73}," strconv.",[46,2360,2361],{"class":56},"Itoa",[46,2363,311],{"class":73},[46,2365,2285],{"class":145},[46,2367,2368],{"class":73},")       ",[46,2370,2371],{"class":126},"\u002F\u002F \"65\"\n",[46,2373,2374,2377,2379,2381,2384,2386,2388,2390,2393,2395],{"class":48,"line":176},[46,2375,2376],{"class":73},"    correct2 ",[46,2378,302],{"class":52},[46,2380,2358],{"class":73},[46,2382,2383],{"class":56},"FormatInt",[46,2385,311],{"class":73},[46,2387,2285],{"class":145},[46,2389,462],{"class":73},[46,2391,2392],{"class":145},"10",[46,2394,328],{"class":73},[46,2396,2371],{"class":126},[46,2398,2399,2401,2403],{"class":48,"line":181},[46,2400,164],{"class":73},[46,2402,167],{"class":56},[46,2404,2405],{"class":73},"(correct, correct2)\n",[46,2407,2408],{"class":48,"line":187},[46,2409,64],{"emptyLinePlaceholder":63},[46,2411,2412],{"class":48,"line":203},[46,2413,2414],{"class":126},"    \u002F\u002F go vet catches this: \"conversion from int to string yields a string of\n",[46,2416,2417],{"class":48,"line":214},[46,2418,2419],{"class":126},"    \u002F\u002F one rune, not a string of digits\" (vet's default check since Go 1.15)\n",[46,2421,2422],{"class":48,"line":227},[46,2423,392],{"class":73},[14,2425,2427],{"id":2426},"string-building-zero-allocation-patterns","String Building — Zero-Allocation Patterns",[19,2429,2430],{"language":38},[23,2431,2433],{"className":41,"code":2432,"language":38,"meta":28,"style":28},"\u002F\u002F ❌ ANTI-PATTERN: string concatenation in a loop (O(n²) allocations)\nfunc badConcat(words []string) string {\n    s := \"\"\n    for _, w := range words {\n        s += w  \u002F\u002F each += allocates a new string (old + new copied)\n    }\n    return s\n}\n\n\u002F\u002F ✅ CORRECT: strings.Builder (Go 1.10+) — amortized O(n), minimal allocations\nfunc goodConcat(words []string) string {\n    var b strings.Builder\n    b.Grow(64)  \u002F\u002F pre-grow to avoid reallocation (estimate total size)\n    for _, w := range words {\n        b.WriteString(w)\n    }\n    return b.String()  \u002F\u002F single allocation for the final string\n}\n\n\u002F\u002F ✅ For joining with a separator: strings.Join (uses Builder internally)\njoined := strings.Join(words, \", \")\n\n\u002F\u002F ✅ For byte manipulation without string conversion: bytes.Buffer\nfunc byteConcat(parts [][]byte) []byte {\n    var buf bytes.Buffer\n    for _, p := range parts {\n        buf.Write(p)\n    }\n    return buf.Bytes()\n}\n",[30,2434,2435,2440,2462,2471,2485,2498,2502,2509,2513,2517,2522,2543,2557,2575,2587,2598,2602,2617,2621,2625,2630,2651,2655,2660,2684,2699,2712,2723,2727,2739],{"__ignoreMap":28},[46,2436,2437],{"class":48,"line":49},[46,2438,2439],{"class":126},"\u002F\u002F ❌ ANTI-PATTERN: string concatenation in a loop (O(n²) allocations)\n",[46,2441,2442,2444,2447,2449,2452,2454,2456,2458,2460],{"class":48,"line":60},[46,2443,114],{"class":52},[46,2445,2446],{"class":56}," badConcat",[46,2448,311],{"class":73},[46,2450,2451],{"class":458},"words",[46,2453,1231],{"class":73},[46,2455,1478],{"class":52},[46,2457,253],{"class":73},[46,2459,1478],{"class":52},[46,2461,258],{"class":73},[46,2463,2464,2466,2468],{"class":48,"line":67},[46,2465,1633],{"class":73},[46,2467,302],{"class":52},[46,2469,2470],{"class":80}," \"\"\n",[46,2472,2473,2475,2478,2480,2482],{"class":48,"line":77},[46,2474,1254],{"class":52},[46,2476,2477],{"class":73}," _, w ",[46,2479,302],{"class":52},[46,2481,1262],{"class":52},[46,2483,2484],{"class":73}," words {\n",[46,2486,2487,2490,2492,2495],{"class":48,"line":90},[46,2488,2489],{"class":73},"        s ",[46,2491,1273],{"class":52},[46,2493,2494],{"class":73}," w  ",[46,2496,2497],{"class":126},"\u002F\u002F each += allocates a new string (old + new copied)\n",[46,2499,2500],{"class":48,"line":100},[46,2501,282],{"class":73},[46,2503,2504,2506],{"class":48,"line":106},[46,2505,598],{"class":52},[46,2507,2508],{"class":73}," s\n",[46,2510,2511],{"class":48,"line":111},[46,2512,392],{"class":73},[46,2514,2515],{"class":48,"line":123},[46,2516,64],{"emptyLinePlaceholder":63},[46,2518,2519],{"class":48,"line":130},[46,2520,2521],{"class":126},"\u002F\u002F ✅ CORRECT: strings.Builder (Go 1.10+) — amortized O(n), minimal allocations\n",[46,2523,2524,2526,2529,2531,2533,2535,2537,2539,2541],{"class":48,"line":149},[46,2525,114],{"class":52},[46,2527,2528],{"class":56}," goodConcat",[46,2530,311],{"class":73},[46,2532,2451],{"class":458},[46,2534,1231],{"class":73},[46,2536,1478],{"class":52},[46,2538,253],{"class":73},[46,2540,1478],{"class":52},[46,2542,258],{"class":73},[46,2544,2545,2547,2549,2552,2554],{"class":48,"line":161},[46,2546,133],{"class":52},[46,2548,489],{"class":73},[46,2550,2551],{"class":56},"strings",[46,2553,1501],{"class":73},[46,2555,2556],{"class":56},"Builder\n",[46,2558,2559,2562,2565,2567,2570,2572],{"class":48,"line":176},[46,2560,2561],{"class":73},"    b.",[46,2563,2564],{"class":56},"Grow",[46,2566,311],{"class":73},[46,2568,2569],{"class":145},"64",[46,2571,328],{"class":73},[46,2573,2574],{"class":126},"\u002F\u002F pre-grow to avoid reallocation (estimate total size)\n",[46,2576,2577,2579,2581,2583,2585],{"class":48,"line":181},[46,2578,1254],{"class":52},[46,2580,2477],{"class":73},[46,2582,302],{"class":52},[46,2584,1262],{"class":52},[46,2586,2484],{"class":73},[46,2588,2589,2592,2595],{"class":48,"line":187},[46,2590,2591],{"class":73},"        b.",[46,2593,2594],{"class":56},"WriteString",[46,2596,2597],{"class":73},"(w)\n",[46,2599,2600],{"class":48,"line":203},[46,2601,282],{"class":73},[46,2603,2604,2606,2609,2611,2614],{"class":48,"line":214},[46,2605,598],{"class":52},[46,2607,2608],{"class":73}," b.",[46,2610,1472],{"class":56},[46,2612,2613],{"class":73},"()  ",[46,2615,2616],{"class":126},"\u002F\u002F single allocation for the final string\n",[46,2618,2619],{"class":48,"line":227},[46,2620,392],{"class":73},[46,2622,2623],{"class":48,"line":232},[46,2624,64],{"emptyLinePlaceholder":63},[46,2626,2627],{"class":48,"line":238},[46,2628,2629],{"class":126},"\u002F\u002F ✅ For joining with a separator: strings.Join (uses Builder internally)\n",[46,2631,2632,2635,2637,2640,2643,2646,2649],{"class":48,"line":261},[46,2633,2634],{"class":73},"joined ",[46,2636,302],{"class":52},[46,2638,2639],{"class":73}," strings.",[46,2641,2642],{"class":56},"Join",[46,2644,2645],{"class":73},"(words, ",[46,2647,2648],{"class":80},"\", \"",[46,2650,103],{"class":73},[46,2652,2653],{"class":48,"line":279},[46,2654,64],{"emptyLinePlaceholder":63},[46,2656,2657],{"class":48,"line":285},[46,2658,2659],{"class":126},"\u002F\u002F ✅ For byte manipulation without string conversion: bytes.Buffer\n",[46,2661,2662,2664,2667,2669,2672,2675,2677,2680,2682],{"class":48,"line":290},[46,2663,114],{"class":52},[46,2665,2666],{"class":56}," byteConcat",[46,2668,311],{"class":73},[46,2670,2671],{"class":458},"parts",[46,2673,2674],{"class":73}," [][]",[46,2676,2157],{"class":52},[46,2678,2679],{"class":73},") []",[46,2681,2157],{"class":52},[46,2683,258],{"class":73},[46,2685,2686,2688,2691,2694,2696],{"class":48,"line":296},[46,2687,133],{"class":52},[46,2689,2690],{"class":73}," buf ",[46,2692,2693],{"class":56},"bytes",[46,2695,1501],{"class":73},[46,2697,2698],{"class":56},"Buffer\n",[46,2700,2701,2703,2705,2707,2709],{"class":48,"line":334},[46,2702,1254],{"class":52},[46,2704,1257],{"class":73},[46,2706,302],{"class":52},[46,2708,1262],{"class":52},[46,2710,2711],{"class":73}," parts {\n",[46,2713,2714,2717,2720],{"class":48,"line":351},[46,2715,2716],{"class":73},"        buf.",[46,2718,2719],{"class":56},"Write",[46,2721,2722],{"class":73},"(p)\n",[46,2724,2725],{"class":48,"line":372},[46,2726,282],{"class":73},[46,2728,2729,2731,2734,2737],{"class":48,"line":377},[46,2730,598],{"class":52},[46,2732,2733],{"class":73}," buf.",[46,2735,2736],{"class":56},"Bytes",[46,2738,1009],{"class":73},[46,2740,2741],{"class":48,"line":389},[46,2742,392],{"class":73},[14,2744,2746],{"id":2745},"tips-tricks","💡 Tips & Tricks",[2748,2749,2750,2769,2785,2809,2828,2846],"ul",{},[2751,2752,2753,2757,2758,2761,2762,2764,2765,2768],"li",{},[2754,2755,2756],"strong",{},"Performance",": ",[30,2759,2760],{},"strings.Builder.Grow(n)"," pre-allocates the internal slice — call it when you know the approximate output size. Without ",[30,2763,2564],{},", the builder doubles its buffer, causing log(n) reallocations. ",[30,2766,2767],{},"b.Grow(1024)"," before writing 1000 bytes avoids 4-5 reallocations.",[2751,2770,2771,2774,2775,2778,2779,2781,2782,2784],{},[2754,2772,2773],{},"Safety",": use ",[30,2776,2777],{},"math\u002Fbig.Int"," for cryptographic operations, file sizes, or any value that might exceed ",[30,2780,474],{}," (2^63-1). ",[30,2783,474],{}," max = ~9.2 quintillion — sufficient for most apps, but file offsets on 18-exabyte storage or nanosecond timestamps overflow.",[2751,2786,2787,2757,2790,2793,2794,2797,2798,708,2801,2804,2805,2808],{},[2754,2788,2789],{},"Idiom",[30,2791,2792],{},"strconv.Itoa"," for int→string, ",[30,2795,2796],{},"strconv.Atoi"," for string→int — both are faster than ",[30,2799,2800],{},"fmt.Sprintf",[30,2802,2803],{},"fmt.Sscanf",". ",[30,2806,2807],{},"strconv.ParseInt(s, 10, 64)"," gives control over base and bit size.",[2751,2810,2811,2757,2813,2816,2817,2820,2821,2824,2825,1501],{},[2754,2812,2756],{},[30,2814,2815],{},"bytes.Equal(a, b)"," is faster than ",[30,2818,2819],{},"string(a) == string(b)"," — it compares bytes directly without allocating string conversions. Same for ",[30,2822,2823],{},"bytes.Compare"," vs ",[30,2826,2827],{},"strings.Compare",[2751,2829,2830,2757,2833,2835,2836,708,2839,2841,2842,2845],{},[2754,2831,2832],{},"Portability",[30,2834,250],{}," is 32-bit on 32-bit platforms. If you serialize data (binary formats, network protocols), always use ",[30,2837,2838],{},"int32",[30,2840,474],{}," with explicit sizes. ",[30,2843,2844],{},"encoding\u002Fbinary"," enforces fixed-width types.",[2751,2847,2848,2757,2851,2854,2855,2858],{},[2754,2849,2850],{},"Debug",[30,2852,2853],{},"fmt.Sprintf(\"%x\", s)"," prints a string as hex bytes — useful for debugging encoding issues. ",[30,2856,2857],{},"fmt.Sprintf(\"%q\", s)"," prints with quotes and escapes non-printable bytes — shows invalid UTF-8 clearly.",[14,2860,2862],{"id":2861},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[2748,2864,2865,2888,2904,2929,2937,2957,2973,2991,3004,3022,3043,3068],{},[2751,2866,2867,2757,2873,2876,2877,2880,2881,2884,2885,2887],{},[2754,2868,2869,2872],{},[30,2870,2871],{},"len(s)"," is bytes, not characters",[30,2874,2875],{},"len(\"世\")"," = 3, not 1. Use ",[30,2878,2879],{},"utf8.RuneCountInString(s)"," for character count. ",[30,2882,2883],{},"len()"," is O(1) (reads the header); ",[30,2886,1667],{}," is O(n).",[2751,2889,2890,2896,2897,2899,2900,2903],{},[2754,2891,2892,2895],{},[30,2893,2894],{},"s[i]"," is a byte, not a character",": indexing multi-byte UTF-8 at an arbitrary position gives a partial rune. Use ",[30,2898,1835],{}," or ",[30,2901,2902],{},"utf8.DecodeRuneInString"," for character access.",[2751,2905,2906,2909,2910,2913,2914,2917,2918,708,2921,2924,2925,2928],{},[2754,2907,2908],{},"Integer overflow wraps silently",": no panic — ",[30,2911,2912],{},"byte(255) + 1"," = 0, ",[30,2915,2916],{},"int8(127) + 1"," = -128. Use ",[30,2919,2920],{},"math\u002Fbits.Add64",[30,2922,2923],{},"Mul64"," for overflow detection, or ",[30,2926,2927],{},"math\u002Fbig"," for arbitrary precision.",[2751,2930,2931,2936],{},[2754,2932,2933],{},[30,2934,2935],{},"0.1 + 0.2 ≠ 0.3",": IEEE 754 double can't represent 0.1 exactly. Use a decimal library for money, or store as integer cents.",[2751,2938,2939,2757,2944,2947,2948,2951,2952,2954,2955,1501],{},[2754,2940,2941,2943],{},[30,2942,924],{}," can't represent all integers beyond 2^53",[30,2945,2946],{},"float64(1\u003C\u003C53+1)"," == ",[30,2949,2950],{},"float64(1\u003C\u003C53)",". For large integer IDs, use ",[30,2953,474],{},", not ",[30,2956,924],{},[2751,2958,2959,2964,2965,2968,2969,2972],{},[2754,2960,2961],{},[30,2962,2963],{},"NaN != NaN",": the only value in Go that doesn't equal itself. Use ",[30,2966,2967],{},"math.IsNaN()"," to test. JSON marshals NaN as an error (use ",[30,2970,2971],{},"json.Marshal"," carefully with floats).",[2751,2974,2975,2757,2981,2983,2984,2986,2987,2990],{},[2754,2976,2977,2980],{},[30,2978,2979],{},"string(65)"," = \"A\", not \"65\"",[30,2982,2245],{}," gives the Unicode code point. Use ",[30,2985,2792],{}," for digits. ",[30,2988,2989],{},"go vet"," warns about this.",[2751,2992,2993,2757,2996,2999,3000,3003],{},[2754,2994,2995],{},"Strings are immutable",[30,2997,2998],{},"s[0] = 'x'"," is a compile error. Convert to ",[30,3001,3002],{},"[]byte",", modify, convert back (two allocations).",[2751,3005,3006,3016,3017,708,3019,3021],{},[2754,3007,3008,3011,3012,3015],{},[30,3009,3010],{},"[]byte(s)"," and ",[30,3013,3014],{},"string(b)"," each allocate",": they copy the data because strings are read-only. Avoid in hot paths — use ",[30,3018,2693],{},[30,3020,2551],{}," package functions that work on the native type.",[2751,3023,3024,3029,3030,3033,3034,3036,3037,3039,3040,3042],{},[2754,3025,3026,3028],{},[30,3027,250],{}," size is platform-dependent",": 32-bit on 32-bit, 64-bit on 64-bit. ",[30,3031,3032],{},"unsafe.Sizeof(int(0))"," = 4 or 8. Never assume ",[30,3035,250],{}," = ",[30,3038,474],{}," — use ",[30,3041,474],{}," explicitly for fixed-width.",[2751,3044,3045,2757,3048,3051,3052,3055,3056,3059,3060,3063,3064,3067],{},[2754,3046,3047],{},"Truncating conversions",[30,3049,3050],{},"int(3.9)"," = 3 (truncates toward zero, not rounding). ",[30,3053,3054],{},"byte(300)"," = 44 (wraps). ",[30,3057,3058],{},"int(-3.9)"," = -3. Use ",[30,3061,3062],{},"math.Round"," for rounding: ",[30,3065,3066],{},"int(math.Round(3.9))"," = 4.",[2751,3069,3070,2757,3076,3078,3079,3083,3084,3087,3088,3090,3091,3094],{},[2754,3071,3072,3075],{},[30,3073,3074],{},"uintptr"," is not a pointer",[30,3077,3074],{}," is an integer that holds a pointer's ",[3080,3081,3082],"em",{},"value",", but the GC doesn't treat it as a pointer — converting ",[30,3085,3086],{},"*T → uintptr"," can cause the object to be collected. Only use ",[30,3089,3074],{}," with ",[30,3092,3093],{},"unsafe"," for syscall arguments.",[14,3096,3098],{"id":3097},"quick-quiz","🧠 Quick Quiz",[19,3100,3101,3179],{"language":38},[23,3102,3104],{"className":41,"code":3103,"language":38,"meta":28,"style":28},"s := \"café\"\nb := []byte(s)\nb[len(b)-1] = 't'\nfmt.Println(s)\nfmt.Println(string(b))\n",[30,3105,3106,3116,3130,3158,3167],{"__ignoreMap":28},[46,3107,3108,3111,3113],{"class":48,"line":49},[46,3109,3110],{"class":73},"s ",[46,3112,302],{"class":52},[46,3114,3115],{"class":80}," \"café\"\n",[46,3117,3118,3121,3123,3125,3127],{"class":48,"line":60},[46,3119,3120],{"class":73},"b ",[46,3122,302],{"class":52},[46,3124,1231],{"class":73},[46,3126,2157],{"class":52},[46,3128,3129],{"class":73},"(s)\n",[46,3131,3132,3135,3137,3140,3142,3144,3147,3149,3152,3155],{"class":48,"line":67},[46,3133,3134],{"class":73},"b[",[46,3136,1649],{"class":56},[46,3138,3139],{"class":73},"(b)",[46,3141,511],{"class":52},[46,3143,1051],{"class":145},[46,3145,3146],{"class":73},"] ",[46,3148,383],{"class":52},[46,3150,3151],{"class":80}," '",[46,3153,3154],{"class":145},"t",[46,3156,3157],{"class":80},"'\n",[46,3159,3160,3163,3165],{"class":48,"line":77},[46,3161,3162],{"class":73},"fmt.",[46,3164,167],{"class":56},[46,3166,3129],{"class":73},[46,3168,3169,3171,3173,3175,3177],{"class":48,"line":90},[46,3170,3162],{"class":73},[46,3172,167],{"class":56},[46,3174,311],{"class":73},[46,3176,1478],{"class":52},[46,3178,981],{"class":73},[3180,3181,3182],"p",{},"What's printed?",[3184,3185,3186,3190,3196,3224,3242],"details",{},[3187,3188,3189],"summary",{},"Answer",[23,3191,3194],{"className":3192,"code":3193,"language":21},[26],"café\ncaft\n",[30,3195,3193],{"__ignoreMap":28},[3180,3197,3198,3201,3202,3205,3206,3208,3209,3212,3213,3215,3216,2804,3218,3220,3221,1501],{},[30,3199,3200],{},"s"," is still ",[30,3203,3204],{},"\"café\""," — strings are immutable, and ",[30,3207,3010],{}," ",[2754,3210,3211],{},"copies"," the data. Modifying ",[30,3214,465],{}," doesn't affect ",[30,3217,3200],{},[30,3219,3014],{}," creates a new string from the modified bytes: ",[30,3222,3223],{},"\"caft\"",[3180,3225,3226,3227,3230,3231,3233,3234,3237,3238,3241],{},"But wait — \"é\" is 2 bytes in UTF-8 (0xC3 0xA9). ",[30,3228,3229],{},"b[len(b)-1]"," modifies the last byte (0xA9 → 0x74 = 't'), leaving 0xC3 intact. ",[30,3232,3014],{}," now contains ",[30,3235,3236],{},"0xC3 0x74"," — which is invalid UTF-8 (0xC3 starts a 2-byte sequence but 0x74 is not a continuation byte). ",[30,3239,3240],{},"fmt.Println"," may print \"caf\\u00f3\" or garbage depending on the terminal.",[3180,3243,3244,3245,3247,3248,1501],{},"The lesson: modifying ",[30,3246,3002],{}," of a string at byte positions can break UTF-8. If you need to modify characters, work in ",[30,3249,3250],{},"[]rune",[14,3252,3254],{"id":3253},"whats-next","📚 What's Next",[3180,3256,3257,3258,3262],{},"→ ",[459,3259,3261],{"href":3260},"\u002Fgo\u002F05-functions","05 — Functions"," — multiple returns, closures, defer mechanics, variadic functions, and function types as values.",[3264,3265,3266],"style",{},"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 .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}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":28,"searchDepth":60,"depth":60,"links":3268},[3269,3270,3273,3276,3280,3284,3285,3286,3287,3288],{"id":16,"depth":60,"text":17},{"id":34,"depth":60,"text":35,"children":3271},[3272],{"id":396,"depth":67,"text":397},{"id":781,"depth":60,"text":782,"children":3274},[3275],{"id":1203,"depth":67,"text":1204},{"id":1533,"depth":60,"text":1534,"children":3277},[3278],{"id":1832,"depth":67,"text":3279},"range over strings — free UTF-8 decoding",{"id":2027,"depth":60,"text":2028,"children":3281},[3282],{"id":2241,"depth":67,"text":3283},"The string(int) gotcha",{"id":2426,"depth":60,"text":2427},{"id":2745,"depth":60,"text":2746},{"id":2861,"depth":60,"text":2862},{"id":3097,"depth":60,"text":3098},{"id":3253,"depth":60,"text":3254},"Integer overflow mechanics, IEEE 754 float precision traps, UTF-8 string internals, rune vs byte, and zero-allocation conversion patterns.","md",{},"\u002Fgo\u002F04-basic-types-and-conversions",{"title":5,"description":3289},"go\u002F04-basic-types-and-conversions","hPKGNaN6BwEgjnB9qFSArAb7gKhXz1vSJlEZ7KPHeZY",1789924648294]