[{"data":1,"prerenderedAt":3370},["ShallowReactive",2],{"page-\u002Fgo\u002F14-generics":3},{"id":4,"title":5,"body":6,"description":3363,"extension":3364,"meta":3365,"navigation":59,"path":3366,"seo":3367,"stem":3368,"__hash__":3369},"content\u002Fgo\u002F14-generics.md","14 — Generics",{"type":7,"value":8,"toc":3357},"minimark",[9,13,22,27,3268,3334,3338,3353],[10,11,5],"h1",{"id":12},"_14-generics",[14,15,16,17,21],"p",{},"Go 1.18 introduced generics — type parameters on functions and types. They enable type-safe, reusable code without ",[18,19,20],"code",{},"interface{}"," and type assertions.",[23,24,26],"h2",{"id":25},"generic-functions","Generic Functions",[28,29,31,396,403],"code-wrapper",{"language":30},"go",[32,33,37],"pre",{"className":34,"code":35,"language":30,"meta":36,"style":36},"language-go shiki shiki-themes github-light github-dark","\u002F\u002F [T, U any] declares type parameters. `any` is the constraint (no restrictions).\n\u002F\u002F Type arguments are inferred from the call in most cases.\n\nfunc Map[T, U any](s []T, fn func(T) U) []U {\n    result := make([]U, len(s))\n    for i, v := range s {\n        result[i] = fn(v)\n    }\n    return result\n}\n\n\u002F\u002F Usage — type args inferred:\ndoubled := Map([]int{1, 2, 3}, func(x int) int { return x * 2 })  \u002F\u002F [2 4 6]\nupper := Map([]string{\"a\", \"b\"}, strings.ToUpper)                  \u002F\u002F [\"A\" \"B\"]\n\n\u002F\u002F Explicit type args (when inference is ambiguous):\n_ = Map[int, string]([]int{1, 2}, func(x int) string { return fmt.Sprintf(\"%d\", x) })\n","",[18,38,39,48,54,61,126,151,168,183,189,198,204,209,215,285,317,322,328],{"__ignoreMap":36},[40,41,44],"span",{"class":42,"line":43},"line",1,[40,45,47],{"class":46},"sdCPZ","\u002F\u002F [T, U any] declares type parameters. `any` is the constraint (no restrictions).\n",[40,49,51],{"class":42,"line":50},2,[40,52,53],{"class":46},"\u002F\u002F Type arguments are inferred from the call in most cases.\n",[40,55,57],{"class":42,"line":56},3,[40,58,60],{"emptyLinePlaceholder":59},true,"\n",[40,62,64,68,72,76,80,83,86,89,92,95,98,100,102,105,108,111,113,116,118,121,123],{"class":42,"line":63},4,[40,65,67],{"class":66},"svdQ7","func",[40,69,71],{"class":70},"sIsaT"," Map",[40,73,75],{"class":74},"ssxIu","[",[40,77,79],{"class":78},"sCrzJ","T",[40,81,82],{"class":74},", ",[40,84,85],{"class":78},"U",[40,87,88],{"class":70}," any",[40,90,91],{"class":74},"](",[40,93,94],{"class":78},"s",[40,96,97],{"class":74}," []",[40,99,79],{"class":70},[40,101,82],{"class":74},[40,103,104],{"class":78},"fn",[40,106,107],{"class":66}," func",[40,109,110],{"class":74},"(",[40,112,79],{"class":70},[40,114,115],{"class":74},") ",[40,117,85],{"class":70},[40,119,120],{"class":74},") []",[40,122,85],{"class":70},[40,124,125],{"class":74}," {\n",[40,127,129,132,135,138,141,143,145,148],{"class":42,"line":128},5,[40,130,131],{"class":74},"    result ",[40,133,134],{"class":66},":=",[40,136,137],{"class":70}," make",[40,139,140],{"class":74},"([]",[40,142,85],{"class":70},[40,144,82],{"class":74},[40,146,147],{"class":70},"len",[40,149,150],{"class":74},"(s))\n",[40,152,154,157,160,162,165],{"class":42,"line":153},6,[40,155,156],{"class":66},"    for",[40,158,159],{"class":74}," i, v ",[40,161,134],{"class":66},[40,163,164],{"class":66}," range",[40,166,167],{"class":74}," s {\n",[40,169,171,174,177,180],{"class":42,"line":170},7,[40,172,173],{"class":74},"        result[i] ",[40,175,176],{"class":66},"=",[40,178,179],{"class":70}," fn",[40,181,182],{"class":74},"(v)\n",[40,184,186],{"class":42,"line":185},8,[40,187,188],{"class":74},"    }\n",[40,190,192,195],{"class":42,"line":191},9,[40,193,194],{"class":66},"    return",[40,196,197],{"class":74}," result\n",[40,199,201],{"class":42,"line":200},10,[40,202,203],{"class":74},"}\n",[40,205,207],{"class":42,"line":206},11,[40,208,60],{"emptyLinePlaceholder":59},[40,210,212],{"class":42,"line":211},12,[40,213,214],{"class":46},"\u002F\u002F Usage — type args inferred:\n",[40,216,218,221,223,225,227,230,233,237,239,242,244,247,250,252,254,257,260,262,264,267,270,273,276,279,282],{"class":42,"line":217},13,[40,219,220],{"class":74},"doubled ",[40,222,134],{"class":66},[40,224,71],{"class":70},[40,226,140],{"class":74},[40,228,229],{"class":66},"int",[40,231,232],{"class":74},"{",[40,234,236],{"class":235},"snvgF","1",[40,238,82],{"class":74},[40,240,241],{"class":235},"2",[40,243,82],{"class":74},[40,245,246],{"class":235},"3",[40,248,249],{"class":74},"}, ",[40,251,67],{"class":66},[40,253,110],{"class":74},[40,255,256],{"class":78},"x",[40,258,259],{"class":66}," int",[40,261,115],{"class":74},[40,263,229],{"class":66},[40,265,266],{"class":74}," { ",[40,268,269],{"class":66},"return",[40,271,272],{"class":74}," x ",[40,274,275],{"class":66},"*",[40,277,278],{"class":235}," 2",[40,280,281],{"class":74}," })  ",[40,283,284],{"class":46},"\u002F\u002F [2 4 6]\n",[40,286,288,291,293,295,297,300,302,306,308,311,314],{"class":42,"line":287},14,[40,289,290],{"class":74},"upper ",[40,292,134],{"class":66},[40,294,71],{"class":70},[40,296,140],{"class":74},[40,298,299],{"class":66},"string",[40,301,232],{"class":74},[40,303,305],{"class":304},"sJ6F3","\"a\"",[40,307,82],{"class":74},[40,309,310],{"class":304},"\"b\"",[40,312,313],{"class":74},"}, strings.ToUpper)                  ",[40,315,316],{"class":46},"\u002F\u002F [\"A\" \"B\"]\n",[40,318,320],{"class":42,"line":319},15,[40,321,60],{"emptyLinePlaceholder":59},[40,323,325],{"class":42,"line":324},16,[40,326,327],{"class":46},"\u002F\u002F Explicit type args (when inference is ambiguous):\n",[40,329,331,334,336,338,340,342,344,346,349,351,353,355,357,359,361,363,365,367,369,371,373,375,377,380,383,385,388,391,393],{"class":42,"line":330},17,[40,332,333],{"class":74},"_ ",[40,335,176],{"class":66},[40,337,71],{"class":70},[40,339,75],{"class":74},[40,341,229],{"class":66},[40,343,82],{"class":74},[40,345,299],{"class":66},[40,347,348],{"class":74},"]([]",[40,350,229],{"class":66},[40,352,232],{"class":74},[40,354,236],{"class":235},[40,356,82],{"class":74},[40,358,241],{"class":235},[40,360,249],{"class":74},[40,362,67],{"class":66},[40,364,110],{"class":74},[40,366,256],{"class":78},[40,368,259],{"class":66},[40,370,115],{"class":74},[40,372,299],{"class":66},[40,374,266],{"class":74},[40,376,269],{"class":66},[40,378,379],{"class":74}," fmt.",[40,381,382],{"class":70},"Sprintf",[40,384,110],{"class":74},[40,386,387],{"class":304},"\"",[40,389,390],{"class":235},"%d",[40,392,387],{"class":304},[40,394,395],{"class":74},", x) })\n",[23,397,399,400],{"id":398},"type-constraints-type-sets-and-t","Type Constraints — Type Sets and ",[18,401,402],{},"~T",[28,404,405,764,768],{"language":30},[32,406,408],{"className":34,"code":407,"language":30,"meta":36,"style":36},"\u002F\u002F Constraints are interfaces with TYPE SETS — a union of types.\n\u002F\u002F `~T` includes T AND any named type whose UNDERLYING type is T.\n\ntype Number interface {\n    int | int64 | float64\n}\n\n\u002F\u002F Without `~`, a named type like `type MyInt int` does NOT satisfy `int`:\ntype StrictInt interface{ int }\ntype TildeInt interface{ ~int }\n\ntype MyInt int\n\nfunc strict[T StrictInt](v T) T { return v }\nfunc tilde[T TildeInt](v T) T { return v }\n\nfunc constraintDemo() {\n    var x MyInt = 42\n    \u002F\u002F strict(x)   \u002F\u002F ❌ compile error: MyInt doesn't satisfy `int` (no ~)\n    _ = tilde(x)   \u002F\u002F ✅ MyInt satisfies `~int` (underlying type is int)\n    _ = x\n}\n\n\u002F\u002F ─── cmp.Ordered (Go 1.21+ standard constraint) ───\nimport \"cmp\"\n\nfunc Max[T cmp.Ordered](a, b T) T {\n    if a > b { return a }\n    return b\n}\n\u002F\u002F cmp.Ordered = all types supporting \u003C, \u003C=, >, >=:\n\u002F\u002F   ~int | ~int8 | ... | ~uint | ... | ~float32 | ~float64 | ~string\n",[18,409,410,415,420,424,437,453,457,461,466,483,499,503,513,517,549,578,582,592,609,618,634,644,649,654,660,675,680,719,739,747,752,758],{"__ignoreMap":36},[40,411,412],{"class":42,"line":43},[40,413,414],{"class":46},"\u002F\u002F Constraints are interfaces with TYPE SETS — a union of types.\n",[40,416,417],{"class":42,"line":50},[40,418,419],{"class":46},"\u002F\u002F `~T` includes T AND any named type whose UNDERLYING type is T.\n",[40,421,422],{"class":42,"line":56},[40,423,60],{"emptyLinePlaceholder":59},[40,425,426,429,432,435],{"class":42,"line":63},[40,427,428],{"class":66},"type",[40,430,431],{"class":70}," Number",[40,433,434],{"class":66}," interface",[40,436,125],{"class":74},[40,438,439,442,445,448,450],{"class":42,"line":128},[40,440,441],{"class":66},"    int",[40,443,444],{"class":66}," |",[40,446,447],{"class":66}," int64",[40,449,444],{"class":66},[40,451,452],{"class":66}," float64\n",[40,454,455],{"class":42,"line":153},[40,456,203],{"class":74},[40,458,459],{"class":42,"line":170},[40,460,60],{"emptyLinePlaceholder":59},[40,462,463],{"class":42,"line":185},[40,464,465],{"class":46},"\u002F\u002F Without `~`, a named type like `type MyInt int` does NOT satisfy `int`:\n",[40,467,468,470,473,475,478,480],{"class":42,"line":191},[40,469,428],{"class":66},[40,471,472],{"class":70}," StrictInt",[40,474,434],{"class":66},[40,476,477],{"class":74},"{ ",[40,479,229],{"class":66},[40,481,482],{"class":74}," }\n",[40,484,485,487,490,492,494,497],{"class":42,"line":200},[40,486,428],{"class":66},[40,488,489],{"class":70}," TildeInt",[40,491,434],{"class":66},[40,493,477],{"class":74},[40,495,496],{"class":66},"~int",[40,498,482],{"class":74},[40,500,501],{"class":42,"line":206},[40,502,60],{"emptyLinePlaceholder":59},[40,504,505,507,510],{"class":42,"line":211},[40,506,428],{"class":66},[40,508,509],{"class":70}," MyInt",[40,511,512],{"class":66}," int\n",[40,514,515],{"class":42,"line":217},[40,516,60],{"emptyLinePlaceholder":59},[40,518,519,521,524,526,528,530,532,535,538,540,542,544,546],{"class":42,"line":287},[40,520,67],{"class":66},[40,522,523],{"class":70}," strict",[40,525,75],{"class":74},[40,527,79],{"class":78},[40,529,472],{"class":70},[40,531,91],{"class":74},[40,533,534],{"class":78},"v",[40,536,537],{"class":70}," T",[40,539,115],{"class":74},[40,541,79],{"class":70},[40,543,266],{"class":74},[40,545,269],{"class":66},[40,547,548],{"class":74}," v }\n",[40,550,551,553,556,558,560,562,564,566,568,570,572,574,576],{"class":42,"line":319},[40,552,67],{"class":66},[40,554,555],{"class":70}," tilde",[40,557,75],{"class":74},[40,559,79],{"class":78},[40,561,489],{"class":70},[40,563,91],{"class":74},[40,565,534],{"class":78},[40,567,537],{"class":70},[40,569,115],{"class":74},[40,571,79],{"class":70},[40,573,266],{"class":74},[40,575,269],{"class":66},[40,577,548],{"class":74},[40,579,580],{"class":42,"line":324},[40,581,60],{"emptyLinePlaceholder":59},[40,583,584,586,589],{"class":42,"line":330},[40,585,67],{"class":66},[40,587,588],{"class":70}," constraintDemo",[40,590,591],{"class":74},"() {\n",[40,593,595,598,600,603,606],{"class":42,"line":594},18,[40,596,597],{"class":66},"    var",[40,599,272],{"class":74},[40,601,602],{"class":70},"MyInt",[40,604,605],{"class":66}," =",[40,607,608],{"class":235}," 42\n",[40,610,612,615],{"class":42,"line":611},19,[40,613,614],{"class":46},"    \u002F\u002F strict(x)",[40,616,617],{"class":46},"   \u002F\u002F ❌ compile error: MyInt doesn't satisfy `int` (no ~)\n",[40,619,621,624,626,628,631],{"class":42,"line":620},20,[40,622,623],{"class":74},"    _ ",[40,625,176],{"class":66},[40,627,555],{"class":70},[40,629,630],{"class":74},"(x)   ",[40,632,633],{"class":46},"\u002F\u002F ✅ MyInt satisfies `~int` (underlying type is int)\n",[40,635,637,639,641],{"class":42,"line":636},21,[40,638,623],{"class":74},[40,640,176],{"class":66},[40,642,643],{"class":74}," x\n",[40,645,647],{"class":42,"line":646},22,[40,648,203],{"class":74},[40,650,652],{"class":42,"line":651},23,[40,653,60],{"emptyLinePlaceholder":59},[40,655,657],{"class":42,"line":656},24,[40,658,659],{"class":46},"\u002F\u002F ─── cmp.Ordered (Go 1.21+ standard constraint) ───\n",[40,661,663,666,669,672],{"class":42,"line":662},25,[40,664,665],{"class":66},"import",[40,667,668],{"class":304}," \"",[40,670,671],{"class":70},"cmp",[40,673,674],{"class":304},"\"\n",[40,676,678],{"class":42,"line":677},26,[40,679,60],{"emptyLinePlaceholder":59},[40,681,683,685,688,690,692,695,698,701,703,706,708,711,713,715,717],{"class":42,"line":682},27,[40,684,67],{"class":66},[40,686,687],{"class":70}," Max",[40,689,75],{"class":74},[40,691,79],{"class":78},[40,693,694],{"class":70}," cmp",[40,696,697],{"class":74},".",[40,699,700],{"class":70},"Ordered",[40,702,91],{"class":74},[40,704,705],{"class":78},"a",[40,707,82],{"class":74},[40,709,710],{"class":78},"b",[40,712,537],{"class":70},[40,714,115],{"class":74},[40,716,79],{"class":70},[40,718,125],{"class":74},[40,720,722,725,728,731,734,736],{"class":42,"line":721},28,[40,723,724],{"class":66},"    if",[40,726,727],{"class":74}," a ",[40,729,730],{"class":66},">",[40,732,733],{"class":74}," b { ",[40,735,269],{"class":66},[40,737,738],{"class":74}," a }\n",[40,740,742,744],{"class":42,"line":741},29,[40,743,194],{"class":66},[40,745,746],{"class":74}," b\n",[40,748,750],{"class":42,"line":749},30,[40,751,203],{"class":74},[40,753,755],{"class":42,"line":754},31,[40,756,757],{"class":46},"\u002F\u002F cmp.Ordered = all types supporting \u003C, \u003C=, >, >=:\n",[40,759,761],{"class":42,"line":760},32,[40,762,763],{"class":46},"\u002F\u002F   ~int | ~int8 | ... | ~uint | ... | ~float32 | ~float64 | ~string\n",[23,765,767],{"id":766},"custom-constraints-with-methods","Custom Constraints with Methods",[28,769,770,1121,1125],{"language":30},[32,771,773],{"className":34,"code":772,"language":30,"meta":36,"style":36},"\u002F\u002F Constraints can require METHODS in addition to type sets.\n\u002F\u002F This combines \"has these methods\" with \"is one of these types.\"\n\n\u002F\u002F ─── Constraint requiring a String() method ───\ntype Stringer interface {\n    String() string\n}\n\nfunc Join[T Stringer](items []T, sep string) string {\n    var b strings.Builder\n    for i, item := range items {\n        if i > 0 { b.WriteString(sep) }\n        b.WriteString(item.String())  \u002F\u002F calls String() — type-safe, no assertion\n    }\n    return b.String()\n}\n\n\u002F\u002F ─── Constraint combining type set + method ───\ntype NumberWithStr interface {\n    ~int | ~float64\n    String() string\n}\n\n\u002F\u002F ─── The `comparable` constraint ───\n\u002F\u002F `comparable` allows types that support == and !=.\n\u002F\u002F Required for map keys and equality checks in generics.\n\nfunc Contains[T comparable](s []T, v T) bool {\n    for _, x := range s {\n        if x == v { return true }\n    }\n    return false\n}\n\n\u002F\u002F ⚠️ `comparable` does NOT include slices, maps, or functions\n\u002F\u002F (they're not comparable with ==). A struct containing a slice\n\u002F\u002F is also not comparable, even if all other fields are.\n",[18,774,775,780,785,789,794,805,816,820,824,860,875,889,911,930,934,946,950,954,959,970,980,988,992,996,1001,1006,1011,1015,1050,1063,1082,1086,1093,1098,1103,1109,1115],{"__ignoreMap":36},[40,776,777],{"class":42,"line":43},[40,778,779],{"class":46},"\u002F\u002F Constraints can require METHODS in addition to type sets.\n",[40,781,782],{"class":42,"line":50},[40,783,784],{"class":46},"\u002F\u002F This combines \"has these methods\" with \"is one of these types.\"\n",[40,786,787],{"class":42,"line":56},[40,788,60],{"emptyLinePlaceholder":59},[40,790,791],{"class":42,"line":63},[40,792,793],{"class":46},"\u002F\u002F ─── Constraint requiring a String() method ───\n",[40,795,796,798,801,803],{"class":42,"line":128},[40,797,428],{"class":66},[40,799,800],{"class":70}," Stringer",[40,802,434],{"class":66},[40,804,125],{"class":74},[40,806,807,810,813],{"class":42,"line":153},[40,808,809],{"class":70},"    String",[40,811,812],{"class":74},"() ",[40,814,815],{"class":66},"string\n",[40,817,818],{"class":42,"line":170},[40,819,203],{"class":74},[40,821,822],{"class":42,"line":185},[40,823,60],{"emptyLinePlaceholder":59},[40,825,826,828,831,833,835,837,839,842,844,846,848,851,854,856,858],{"class":42,"line":191},[40,827,67],{"class":66},[40,829,830],{"class":70}," Join",[40,832,75],{"class":74},[40,834,79],{"class":78},[40,836,800],{"class":70},[40,838,91],{"class":74},[40,840,841],{"class":78},"items",[40,843,97],{"class":74},[40,845,79],{"class":70},[40,847,82],{"class":74},[40,849,850],{"class":78},"sep",[40,852,853],{"class":66}," string",[40,855,115],{"class":74},[40,857,299],{"class":66},[40,859,125],{"class":74},[40,861,862,864,867,870,872],{"class":42,"line":200},[40,863,597],{"class":66},[40,865,866],{"class":74}," b ",[40,868,869],{"class":70},"strings",[40,871,697],{"class":74},[40,873,874],{"class":70},"Builder\n",[40,876,877,879,882,884,886],{"class":42,"line":206},[40,878,156],{"class":66},[40,880,881],{"class":74}," i, item ",[40,883,134],{"class":66},[40,885,164],{"class":66},[40,887,888],{"class":74}," items {\n",[40,890,891,894,897,899,902,905,908],{"class":42,"line":211},[40,892,893],{"class":66},"        if",[40,895,896],{"class":74}," i ",[40,898,730],{"class":66},[40,900,901],{"class":235}," 0",[40,903,904],{"class":74}," { b.",[40,906,907],{"class":70},"WriteString",[40,909,910],{"class":74},"(sep) }\n",[40,912,913,916,918,921,924,927],{"class":42,"line":217},[40,914,915],{"class":74},"        b.",[40,917,907],{"class":70},[40,919,920],{"class":74},"(item.",[40,922,923],{"class":70},"String",[40,925,926],{"class":74},"())  ",[40,928,929],{"class":46},"\u002F\u002F calls String() — type-safe, no assertion\n",[40,931,932],{"class":42,"line":287},[40,933,188],{"class":74},[40,935,936,938,941,943],{"class":42,"line":319},[40,937,194],{"class":66},[40,939,940],{"class":74}," b.",[40,942,923],{"class":70},[40,944,945],{"class":74},"()\n",[40,947,948],{"class":42,"line":324},[40,949,203],{"class":74},[40,951,952],{"class":42,"line":330},[40,953,60],{"emptyLinePlaceholder":59},[40,955,956],{"class":42,"line":594},[40,957,958],{"class":46},"\u002F\u002F ─── Constraint combining type set + method ───\n",[40,960,961,963,966,968],{"class":42,"line":611},[40,962,428],{"class":66},[40,964,965],{"class":70}," NumberWithStr",[40,967,434],{"class":66},[40,969,125],{"class":74},[40,971,972,975,977],{"class":42,"line":620},[40,973,974],{"class":66},"    ~int",[40,976,444],{"class":66},[40,978,979],{"class":66}," ~float64\n",[40,981,982,984,986],{"class":42,"line":636},[40,983,809],{"class":70},[40,985,812],{"class":74},[40,987,815],{"class":66},[40,989,990],{"class":42,"line":646},[40,991,203],{"class":74},[40,993,994],{"class":42,"line":651},[40,995,60],{"emptyLinePlaceholder":59},[40,997,998],{"class":42,"line":656},[40,999,1000],{"class":46},"\u002F\u002F ─── The `comparable` constraint ───\n",[40,1002,1003],{"class":42,"line":662},[40,1004,1005],{"class":46},"\u002F\u002F `comparable` allows types that support == and !=.\n",[40,1007,1008],{"class":42,"line":677},[40,1009,1010],{"class":46},"\u002F\u002F Required for map keys and equality checks in generics.\n",[40,1012,1013],{"class":42,"line":682},[40,1014,60],{"emptyLinePlaceholder":59},[40,1016,1017,1019,1022,1024,1026,1029,1031,1033,1035,1037,1039,1041,1043,1045,1048],{"class":42,"line":721},[40,1018,67],{"class":66},[40,1020,1021],{"class":70}," Contains",[40,1023,75],{"class":74},[40,1025,79],{"class":78},[40,1027,1028],{"class":70}," comparable",[40,1030,91],{"class":74},[40,1032,94],{"class":78},[40,1034,97],{"class":74},[40,1036,79],{"class":70},[40,1038,82],{"class":74},[40,1040,534],{"class":78},[40,1042,537],{"class":70},[40,1044,115],{"class":74},[40,1046,1047],{"class":66},"bool",[40,1049,125],{"class":74},[40,1051,1052,1054,1057,1059,1061],{"class":42,"line":741},[40,1053,156],{"class":66},[40,1055,1056],{"class":74}," _, x ",[40,1058,134],{"class":66},[40,1060,164],{"class":66},[40,1062,167],{"class":74},[40,1064,1065,1067,1069,1072,1075,1077,1080],{"class":42,"line":749},[40,1066,893],{"class":66},[40,1068,272],{"class":74},[40,1070,1071],{"class":66},"==",[40,1073,1074],{"class":74}," v { ",[40,1076,269],{"class":66},[40,1078,1079],{"class":235}," true",[40,1081,482],{"class":74},[40,1083,1084],{"class":42,"line":754},[40,1085,188],{"class":74},[40,1087,1088,1090],{"class":42,"line":760},[40,1089,194],{"class":66},[40,1091,1092],{"class":235}," false\n",[40,1094,1096],{"class":42,"line":1095},33,[40,1097,203],{"class":74},[40,1099,1101],{"class":42,"line":1100},34,[40,1102,60],{"emptyLinePlaceholder":59},[40,1104,1106],{"class":42,"line":1105},35,[40,1107,1108],{"class":46},"\u002F\u002F ⚠️ `comparable` does NOT include slices, maps, or functions\n",[40,1110,1112],{"class":42,"line":1111},36,[40,1113,1114],{"class":46},"\u002F\u002F (they're not comparable with ==). A struct containing a slice\n",[40,1116,1118],{"class":42,"line":1117},37,[40,1119,1120],{"class":46},"\u002F\u002F is also not comparable, even if all other fields are.\n",[23,1122,1124],{"id":1123},"generic-types","Generic Types",[28,1126,1127,1568,1572],{"language":30},[32,1128,1130],{"className":34,"code":1129,"language":30,"meta":36,"style":36},"\u002F\u002F Generic types have type parameters on the type declaration.\n\u002F\u002F Methods repeat the type parameter in the receiver.\n\ntype Stack[T any] struct {\n    items []T\n}\n\nfunc NewStack[T any]() *Stack[T] {\n    return &Stack[T]{}\n}\n\nfunc (s *Stack[T]) Push(v T) {\n    s.items = append(s.items, v)\n}\n\nfunc (s *Stack[T]) Pop() (T, bool) {\n    var zero T  \u002F\u002F zero value of T — works for any T\n    if len(s.items) == 0 {\n        return zero, false\n    }\n    v := s.items[len(s.items)-1]\n    s.items = s.items[:len(s.items)-1]\n    return v, true\n}\n\nfunc (s *Stack[T]) Len() int { return len(s.items) }\n\n\u002F\u002F Usage — type-safe, no assertions:\nintStack := NewStack[int]()\nintStack.Push(1)\nintStack.Push(2)\nv, _ := intStack.Pop()  \u002F\u002F v is int (not any)\n\u002F\u002F intStack.Push(\"hello\")  \u002F\u002F compile error: string ≠ int\n\nstrStack := NewStack[string]()\nstrStack.Push(\"hello\")\n",[18,1131,1132,1137,1142,1146,1167,1175,1179,1183,1211,1227,1231,1235,1268,1281,1285,1289,1321,1333,1349,1360,1364,1387,1406,1416,1420,1424,1458,1462,1467,1483,1497,1509,1527,1535,1539,1554],{"__ignoreMap":36},[40,1133,1134],{"class":42,"line":43},[40,1135,1136],{"class":46},"\u002F\u002F Generic types have type parameters on the type declaration.\n",[40,1138,1139],{"class":42,"line":50},[40,1140,1141],{"class":46},"\u002F\u002F Methods repeat the type parameter in the receiver.\n",[40,1143,1144],{"class":42,"line":56},[40,1145,60],{"emptyLinePlaceholder":59},[40,1147,1148,1150,1153,1155,1157,1159,1162,1165],{"class":42,"line":63},[40,1149,428],{"class":66},[40,1151,1152],{"class":70}," Stack",[40,1154,75],{"class":74},[40,1156,79],{"class":78},[40,1158,88],{"class":70},[40,1160,1161],{"class":74},"] ",[40,1163,1164],{"class":66},"struct",[40,1166,125],{"class":74},[40,1168,1169,1172],{"class":42,"line":128},[40,1170,1171],{"class":74},"    items []",[40,1173,1174],{"class":70},"T\n",[40,1176,1177],{"class":42,"line":153},[40,1178,203],{"class":74},[40,1180,1181],{"class":42,"line":170},[40,1182,60],{"emptyLinePlaceholder":59},[40,1184,1185,1187,1190,1192,1194,1196,1199,1201,1204,1206,1208],{"class":42,"line":185},[40,1186,67],{"class":66},[40,1188,1189],{"class":70}," NewStack",[40,1191,75],{"class":74},[40,1193,79],{"class":78},[40,1195,88],{"class":70},[40,1197,1198],{"class":74},"]() ",[40,1200,275],{"class":66},[40,1202,1203],{"class":70},"Stack",[40,1205,75],{"class":74},[40,1207,79],{"class":70},[40,1209,1210],{"class":74},"] {\n",[40,1212,1213,1215,1218,1220,1222,1224],{"class":42,"line":191},[40,1214,194],{"class":66},[40,1216,1217],{"class":66}," &",[40,1219,1203],{"class":70},[40,1221,75],{"class":74},[40,1223,79],{"class":70},[40,1225,1226],{"class":74},"]{}\n",[40,1228,1229],{"class":42,"line":200},[40,1230,203],{"class":74},[40,1232,1233],{"class":42,"line":206},[40,1234,60],{"emptyLinePlaceholder":59},[40,1236,1237,1239,1242,1245,1247,1249,1251,1253,1256,1259,1261,1263,1265],{"class":42,"line":211},[40,1238,67],{"class":66},[40,1240,1241],{"class":74}," (",[40,1243,1244],{"class":78},"s ",[40,1246,275],{"class":66},[40,1248,1203],{"class":70},[40,1250,75],{"class":74},[40,1252,79],{"class":70},[40,1254,1255],{"class":74},"]) ",[40,1257,1258],{"class":70},"Push",[40,1260,110],{"class":74},[40,1262,534],{"class":78},[40,1264,537],{"class":70},[40,1266,1267],{"class":74},") {\n",[40,1269,1270,1273,1275,1278],{"class":42,"line":217},[40,1271,1272],{"class":74},"    s.items ",[40,1274,176],{"class":66},[40,1276,1277],{"class":70}," append",[40,1279,1280],{"class":74},"(s.items, v)\n",[40,1282,1283],{"class":42,"line":287},[40,1284,203],{"class":74},[40,1286,1287],{"class":42,"line":319},[40,1288,60],{"emptyLinePlaceholder":59},[40,1290,1291,1293,1295,1297,1299,1301,1303,1305,1307,1310,1313,1315,1317,1319],{"class":42,"line":324},[40,1292,67],{"class":66},[40,1294,1241],{"class":74},[40,1296,1244],{"class":78},[40,1298,275],{"class":66},[40,1300,1203],{"class":70},[40,1302,75],{"class":74},[40,1304,79],{"class":70},[40,1306,1255],{"class":74},[40,1308,1309],{"class":70},"Pop",[40,1311,1312],{"class":74},"() (",[40,1314,79],{"class":70},[40,1316,82],{"class":74},[40,1318,1047],{"class":66},[40,1320,1267],{"class":74},[40,1322,1323,1325,1328,1330],{"class":42,"line":330},[40,1324,597],{"class":66},[40,1326,1327],{"class":74}," zero ",[40,1329,79],{"class":70},[40,1331,1332],{"class":46},"  \u002F\u002F zero value of T — works for any T\n",[40,1334,1335,1337,1340,1343,1345,1347],{"class":42,"line":594},[40,1336,724],{"class":66},[40,1338,1339],{"class":70}," len",[40,1341,1342],{"class":74},"(s.items) ",[40,1344,1071],{"class":66},[40,1346,901],{"class":235},[40,1348,125],{"class":74},[40,1350,1351,1354,1357],{"class":42,"line":611},[40,1352,1353],{"class":66},"        return",[40,1355,1356],{"class":74}," zero, ",[40,1358,1359],{"class":235},"false\n",[40,1361,1362],{"class":42,"line":620},[40,1363,188],{"class":74},[40,1365,1366,1369,1371,1374,1376,1379,1382,1384],{"class":42,"line":636},[40,1367,1368],{"class":74},"    v ",[40,1370,134],{"class":66},[40,1372,1373],{"class":74}," s.items[",[40,1375,147],{"class":70},[40,1377,1378],{"class":74},"(s.items)",[40,1380,1381],{"class":66},"-",[40,1383,236],{"class":235},[40,1385,1386],{"class":74},"]\n",[40,1388,1389,1391,1393,1396,1398,1400,1402,1404],{"class":42,"line":646},[40,1390,1272],{"class":74},[40,1392,176],{"class":66},[40,1394,1395],{"class":74}," s.items[:",[40,1397,147],{"class":70},[40,1399,1378],{"class":74},[40,1401,1381],{"class":66},[40,1403,236],{"class":235},[40,1405,1386],{"class":74},[40,1407,1408,1410,1413],{"class":42,"line":651},[40,1409,194],{"class":66},[40,1411,1412],{"class":74}," v, ",[40,1414,1415],{"class":235},"true\n",[40,1417,1418],{"class":42,"line":656},[40,1419,203],{"class":74},[40,1421,1422],{"class":42,"line":662},[40,1423,60],{"emptyLinePlaceholder":59},[40,1425,1426,1428,1430,1432,1434,1436,1438,1440,1442,1445,1447,1449,1451,1453,1455],{"class":42,"line":677},[40,1427,67],{"class":66},[40,1429,1241],{"class":74},[40,1431,1244],{"class":78},[40,1433,275],{"class":66},[40,1435,1203],{"class":70},[40,1437,75],{"class":74},[40,1439,79],{"class":70},[40,1441,1255],{"class":74},[40,1443,1444],{"class":70},"Len",[40,1446,812],{"class":74},[40,1448,229],{"class":66},[40,1450,266],{"class":74},[40,1452,269],{"class":66},[40,1454,1339],{"class":70},[40,1456,1457],{"class":74},"(s.items) }\n",[40,1459,1460],{"class":42,"line":682},[40,1461,60],{"emptyLinePlaceholder":59},[40,1463,1464],{"class":42,"line":721},[40,1465,1466],{"class":46},"\u002F\u002F Usage — type-safe, no assertions:\n",[40,1468,1469,1472,1474,1476,1478,1480],{"class":42,"line":741},[40,1470,1471],{"class":74},"intStack ",[40,1473,134],{"class":66},[40,1475,1189],{"class":70},[40,1477,75],{"class":74},[40,1479,229],{"class":66},[40,1481,1482],{"class":74},"]()\n",[40,1484,1485,1488,1490,1492,1494],{"class":42,"line":749},[40,1486,1487],{"class":74},"intStack.",[40,1489,1258],{"class":70},[40,1491,110],{"class":74},[40,1493,236],{"class":235},[40,1495,1496],{"class":74},")\n",[40,1498,1499,1501,1503,1505,1507],{"class":42,"line":754},[40,1500,1487],{"class":74},[40,1502,1258],{"class":70},[40,1504,110],{"class":74},[40,1506,241],{"class":235},[40,1508,1496],{"class":74},[40,1510,1511,1514,1516,1519,1521,1524],{"class":42,"line":760},[40,1512,1513],{"class":74},"v, _ ",[40,1515,134],{"class":66},[40,1517,1518],{"class":74}," intStack.",[40,1520,1309],{"class":70},[40,1522,1523],{"class":74},"()  ",[40,1525,1526],{"class":46},"\u002F\u002F v is int (not any)\n",[40,1528,1529,1532],{"class":42,"line":1095},[40,1530,1531],{"class":46},"\u002F\u002F intStack.Push(\"hello\")",[40,1533,1534],{"class":46},"  \u002F\u002F compile error: string ≠ int\n",[40,1536,1537],{"class":42,"line":1100},[40,1538,60],{"emptyLinePlaceholder":59},[40,1540,1541,1544,1546,1548,1550,1552],{"class":42,"line":1105},[40,1542,1543],{"class":74},"strStack ",[40,1545,134],{"class":66},[40,1547,1189],{"class":70},[40,1549,75],{"class":74},[40,1551,299],{"class":66},[40,1553,1482],{"class":74},[40,1555,1556,1559,1561,1563,1566],{"class":42,"line":1111},[40,1557,1558],{"class":74},"strStack.",[40,1560,1258],{"class":70},[40,1562,110],{"class":74},[40,1564,1565],{"class":304},"\"hello\"",[40,1567,1496],{"class":74},[23,1569,1571],{"id":1570},"generic-type-with-multiple-type-parameters","Generic Type with Multiple Type Parameters",[28,1573,1574,2111,2123],{"language":30},[32,1575,1577],{"className":34,"code":1576,"language":30,"meta":36,"style":36},"\u002F\u002F A generic map with default values:\n\ntype Map[K comparable, V any] struct {\n    data map[K]V\n}\n\nfunc NewMap[K comparable, V any]() *Map[K, V] {\n    return &Map[K, V]{data: make(map[K]V)}\n}\n\nfunc (m *Map[K, V]) Get(key K, defaultVal V) V {\n    if v, ok := m.data[key]; ok {\n        return v\n    }\n    return defaultVal\n}\n\nfunc (m *Map[K, V]) Set(key K, val V) {\n    m.data[key] = val\n}\n\nfunc (m *Map[K, V]) GetOrInit(key K, init func() V) V {\n    if v, ok := m.data[key]; ok {\n        return v\n    }\n    v := init()\n    m.data[key] = v\n    return v\n}\n\n\u002F\u002F Usage:\nm := NewMap[string, int]()\nm.Set(\"count\", 42)\nfmt.Println(m.Get(\"count\", 0))      \u002F\u002F 42\nfmt.Println(m.Get(\"missing\", -1))   \u002F\u002F -1 (default)\nfmt.Println(m.GetOrInit(\"lazy\", func() int { return 100 }))  \u002F\u002F 100\n",[18,1578,1579,1584,1588,1614,1632,1636,1640,1676,1713,1717,1721,1769,1781,1788,1792,1799,1803,1807,1847,1857,1861,1865,1913,1923,1929,1933,1944,1952,1958,1962,1966,1971,1989,2008,2040,2071],{"__ignoreMap":36},[40,1580,1581],{"class":42,"line":43},[40,1582,1583],{"class":46},"\u002F\u002F A generic map with default values:\n",[40,1585,1586],{"class":42,"line":50},[40,1587,60],{"emptyLinePlaceholder":59},[40,1589,1590,1592,1594,1596,1599,1601,1603,1606,1608,1610,1612],{"class":42,"line":56},[40,1591,428],{"class":66},[40,1593,71],{"class":70},[40,1595,75],{"class":74},[40,1597,1598],{"class":78},"K",[40,1600,1028],{"class":70},[40,1602,82],{"class":74},[40,1604,1605],{"class":78},"V",[40,1607,88],{"class":70},[40,1609,1161],{"class":74},[40,1611,1164],{"class":66},[40,1613,125],{"class":74},[40,1615,1616,1619,1622,1624,1626,1629],{"class":42,"line":63},[40,1617,1618],{"class":74},"    data ",[40,1620,1621],{"class":66},"map",[40,1623,75],{"class":74},[40,1625,1598],{"class":70},[40,1627,1628],{"class":74},"]",[40,1630,1631],{"class":70},"V\n",[40,1633,1634],{"class":42,"line":128},[40,1635,203],{"class":74},[40,1637,1638],{"class":42,"line":153},[40,1639,60],{"emptyLinePlaceholder":59},[40,1641,1642,1644,1647,1649,1651,1653,1655,1657,1659,1661,1663,1666,1668,1670,1672,1674],{"class":42,"line":170},[40,1643,67],{"class":66},[40,1645,1646],{"class":70}," NewMap",[40,1648,75],{"class":74},[40,1650,1598],{"class":78},[40,1652,1028],{"class":70},[40,1654,82],{"class":74},[40,1656,1605],{"class":78},[40,1658,88],{"class":70},[40,1660,1198],{"class":74},[40,1662,275],{"class":66},[40,1664,1665],{"class":70},"Map",[40,1667,75],{"class":74},[40,1669,1598],{"class":70},[40,1671,82],{"class":74},[40,1673,1605],{"class":70},[40,1675,1210],{"class":74},[40,1677,1678,1680,1682,1684,1686,1688,1690,1692,1695,1698,1700,1702,1704,1706,1708,1710],{"class":42,"line":185},[40,1679,194],{"class":66},[40,1681,1217],{"class":66},[40,1683,1665],{"class":70},[40,1685,75],{"class":74},[40,1687,1598],{"class":70},[40,1689,82],{"class":74},[40,1691,1605],{"class":70},[40,1693,1694],{"class":74},"]{data: ",[40,1696,1697],{"class":70},"make",[40,1699,110],{"class":74},[40,1701,1621],{"class":66},[40,1703,75],{"class":74},[40,1705,1598],{"class":70},[40,1707,1628],{"class":74},[40,1709,1605],{"class":70},[40,1711,1712],{"class":74},")}\n",[40,1714,1715],{"class":42,"line":191},[40,1716,203],{"class":74},[40,1718,1719],{"class":42,"line":200},[40,1720,60],{"emptyLinePlaceholder":59},[40,1722,1723,1725,1727,1730,1732,1734,1736,1738,1740,1742,1744,1747,1749,1752,1755,1757,1760,1763,1765,1767],{"class":42,"line":206},[40,1724,67],{"class":66},[40,1726,1241],{"class":74},[40,1728,1729],{"class":78},"m ",[40,1731,275],{"class":66},[40,1733,1665],{"class":70},[40,1735,75],{"class":74},[40,1737,1598],{"class":70},[40,1739,82],{"class":74},[40,1741,1605],{"class":70},[40,1743,1255],{"class":74},[40,1745,1746],{"class":70},"Get",[40,1748,110],{"class":74},[40,1750,1751],{"class":78},"key",[40,1753,1754],{"class":70}," K",[40,1756,82],{"class":74},[40,1758,1759],{"class":78},"defaultVal",[40,1761,1762],{"class":70}," V",[40,1764,115],{"class":74},[40,1766,1605],{"class":70},[40,1768,125],{"class":74},[40,1770,1771,1773,1776,1778],{"class":42,"line":211},[40,1772,724],{"class":66},[40,1774,1775],{"class":74}," v, ok ",[40,1777,134],{"class":66},[40,1779,1780],{"class":74}," m.data[key]; ok {\n",[40,1782,1783,1785],{"class":42,"line":217},[40,1784,1353],{"class":66},[40,1786,1787],{"class":74}," v\n",[40,1789,1790],{"class":42,"line":287},[40,1791,188],{"class":74},[40,1793,1794,1796],{"class":42,"line":319},[40,1795,194],{"class":66},[40,1797,1798],{"class":74}," defaultVal\n",[40,1800,1801],{"class":42,"line":324},[40,1802,203],{"class":74},[40,1804,1805],{"class":42,"line":330},[40,1806,60],{"emptyLinePlaceholder":59},[40,1808,1809,1811,1813,1815,1817,1819,1821,1823,1825,1827,1829,1832,1834,1836,1838,1840,1843,1845],{"class":42,"line":594},[40,1810,67],{"class":66},[40,1812,1241],{"class":74},[40,1814,1729],{"class":78},[40,1816,275],{"class":66},[40,1818,1665],{"class":70},[40,1820,75],{"class":74},[40,1822,1598],{"class":70},[40,1824,82],{"class":74},[40,1826,1605],{"class":70},[40,1828,1255],{"class":74},[40,1830,1831],{"class":70},"Set",[40,1833,110],{"class":74},[40,1835,1751],{"class":78},[40,1837,1754],{"class":70},[40,1839,82],{"class":74},[40,1841,1842],{"class":78},"val",[40,1844,1762],{"class":70},[40,1846,1267],{"class":74},[40,1848,1849,1852,1854],{"class":42,"line":611},[40,1850,1851],{"class":74},"    m.data[key] ",[40,1853,176],{"class":66},[40,1855,1856],{"class":74}," val\n",[40,1858,1859],{"class":42,"line":620},[40,1860,203],{"class":74},[40,1862,1863],{"class":42,"line":636},[40,1864,60],{"emptyLinePlaceholder":59},[40,1866,1867,1869,1871,1873,1875,1877,1879,1881,1883,1885,1887,1890,1892,1894,1896,1898,1901,1903,1905,1907,1909,1911],{"class":42,"line":646},[40,1868,67],{"class":66},[40,1870,1241],{"class":74},[40,1872,1729],{"class":78},[40,1874,275],{"class":66},[40,1876,1665],{"class":70},[40,1878,75],{"class":74},[40,1880,1598],{"class":70},[40,1882,82],{"class":74},[40,1884,1605],{"class":70},[40,1886,1255],{"class":74},[40,1888,1889],{"class":70},"GetOrInit",[40,1891,110],{"class":74},[40,1893,1751],{"class":78},[40,1895,1754],{"class":70},[40,1897,82],{"class":74},[40,1899,1900],{"class":78},"init",[40,1902,107],{"class":66},[40,1904,812],{"class":74},[40,1906,1605],{"class":70},[40,1908,115],{"class":74},[40,1910,1605],{"class":70},[40,1912,125],{"class":74},[40,1914,1915,1917,1919,1921],{"class":42,"line":651},[40,1916,724],{"class":66},[40,1918,1775],{"class":74},[40,1920,134],{"class":66},[40,1922,1780],{"class":74},[40,1924,1925,1927],{"class":42,"line":656},[40,1926,1353],{"class":66},[40,1928,1787],{"class":74},[40,1930,1931],{"class":42,"line":662},[40,1932,188],{"class":74},[40,1934,1935,1937,1939,1942],{"class":42,"line":677},[40,1936,1368],{"class":74},[40,1938,134],{"class":66},[40,1940,1941],{"class":70}," init",[40,1943,945],{"class":74},[40,1945,1946,1948,1950],{"class":42,"line":682},[40,1947,1851],{"class":74},[40,1949,176],{"class":66},[40,1951,1787],{"class":74},[40,1953,1954,1956],{"class":42,"line":721},[40,1955,194],{"class":66},[40,1957,1787],{"class":74},[40,1959,1960],{"class":42,"line":741},[40,1961,203],{"class":74},[40,1963,1964],{"class":42,"line":749},[40,1965,60],{"emptyLinePlaceholder":59},[40,1967,1968],{"class":42,"line":754},[40,1969,1970],{"class":46},"\u002F\u002F Usage:\n",[40,1972,1973,1975,1977,1979,1981,1983,1985,1987],{"class":42,"line":760},[40,1974,1729],{"class":74},[40,1976,134],{"class":66},[40,1978,1646],{"class":70},[40,1980,75],{"class":74},[40,1982,299],{"class":66},[40,1984,82],{"class":74},[40,1986,229],{"class":66},[40,1988,1482],{"class":74},[40,1990,1991,1994,1996,1998,2001,2003,2006],{"class":42,"line":1095},[40,1992,1993],{"class":74},"m.",[40,1995,1831],{"class":70},[40,1997,110],{"class":74},[40,1999,2000],{"class":304},"\"count\"",[40,2002,82],{"class":74},[40,2004,2005],{"class":235},"42",[40,2007,1496],{"class":74},[40,2009,2010,2013,2016,2018,2021,2023,2025,2027,2029,2031,2034,2037],{"class":42,"line":1100},[40,2011,2012],{"class":74},"fmt.",[40,2014,2015],{"class":70},"Println",[40,2017,110],{"class":74},[40,2019,2020],{"class":70},"m",[40,2022,697],{"class":74},[40,2024,1746],{"class":70},[40,2026,110],{"class":74},[40,2028,2000],{"class":304},[40,2030,82],{"class":74},[40,2032,2033],{"class":235},"0",[40,2035,2036],{"class":74},"))      ",[40,2038,2039],{"class":46},"\u002F\u002F 42\n",[40,2041,2042,2044,2046,2048,2050,2052,2054,2056,2059,2061,2063,2065,2068],{"class":42,"line":1105},[40,2043,2012],{"class":74},[40,2045,2015],{"class":70},[40,2047,110],{"class":74},[40,2049,2020],{"class":70},[40,2051,697],{"class":74},[40,2053,1746],{"class":70},[40,2055,110],{"class":74},[40,2057,2058],{"class":304},"\"missing\"",[40,2060,82],{"class":74},[40,2062,1381],{"class":66},[40,2064,236],{"class":235},[40,2066,2067],{"class":74},"))   ",[40,2069,2070],{"class":46},"\u002F\u002F -1 (default)\n",[40,2072,2073,2075,2077,2079,2081,2083,2085,2087,2090,2092,2094,2096,2098,2100,2102,2105,2108],{"class":42,"line":1111},[40,2074,2012],{"class":74},[40,2076,2015],{"class":70},[40,2078,110],{"class":74},[40,2080,2020],{"class":70},[40,2082,697],{"class":74},[40,2084,1889],{"class":70},[40,2086,110],{"class":74},[40,2088,2089],{"class":304},"\"lazy\"",[40,2091,82],{"class":74},[40,2093,67],{"class":66},[40,2095,812],{"class":74},[40,2097,229],{"class":66},[40,2099,266],{"class":74},[40,2101,269],{"class":66},[40,2103,2104],{"class":235}," 100",[40,2106,2107],{"class":74}," }))  ",[40,2109,2110],{"class":46},"\u002F\u002F 100\n",[23,2112,2114,2115,2118,2119,2122],{"id":2113},"the-slices-and-maps-packages-go-121","The ",[18,2116,2117],{},"slices"," and ",[18,2120,2121],{},"maps"," Packages (Go 1.21+)",[28,2124,2125,2626,2630],{"language":30},[32,2126,2128],{"className":34,"code":2127,"language":30,"meta":36,"style":36},"import (\n    \"slices\"\n    \"maps\"\n)\n\nfunc stdlibGenerics() {\n    \u002F\u002F ─── slices package ───\n    s := []int{3, 1, 4, 1, 5, 9, 2, 6}\n    slices.Sort(s)                              \u002F\u002F [1 1 2 3 4 5 6 9]\n    slices.SortStableFunc(s, func(a, b int) int { return a - b })\n    slices.Reverse(s)\n    clone := slices.Clone(s)                   \u002F\u002F independent copy\n    slices.Contains(s, 5)                      \u002F\u002F true\n    idx, found := slices.BinarySearch(s, 4)    \u002F\u002F idx=3, found=true\n    s = slices.Delete(s, 0, 2)                 \u002F\u002F remove indices 0,1\n    s = slices.Insert(s, 0, 0)                 \u002F\u002F insert 0 at front\n    slices.Compact(s)                          \u002F\u002F remove consecutive duplicates\n    slices.DeleteFunc(s, func(v int) bool { return v \u003C 3 })\n\n    \u002F\u002F ─── maps package ───\n    m := map[string]int{\"a\": 1, \"b\": 2, \"c\": 3}\n    keys := maps.Keys(m)        \u002F\u002F []string (unordered, Go 1.23+: iter.Seq)\n    vals := maps.Values(m)      \u002F\u002F []int\n    maps.Copy(dst, src)         \u002F\u002F copy all entries from src to dst\n    maps.Equal(m1, m2)          \u002F\u002F compare two maps\n    maps.DeleteFunc(m, func(k string, v int) bool { return v \u003C 2 })\n    maps.Clone(m)               \u002F\u002F independent copy\n}\n\n\u002F\u002F Prefer slices\u002Fmaps over hand-rolled helpers — tested, idiomatic, fast.\n",[18,2129,2130,2137,2146,2154,2158,2162,2171,2176,2225,2239,2276,2286,2305,2322,2344,2369,2393,2406,2443,2447,2452,2498,2517,2535,2549,2562,2602,2613,2617,2621],{"__ignoreMap":36},[40,2131,2132,2134],{"class":42,"line":43},[40,2133,665],{"class":66},[40,2135,2136],{"class":74}," (\n",[40,2138,2139,2142,2144],{"class":42,"line":50},[40,2140,2141],{"class":304},"    \"",[40,2143,2117],{"class":70},[40,2145,674],{"class":304},[40,2147,2148,2150,2152],{"class":42,"line":56},[40,2149,2141],{"class":304},[40,2151,2121],{"class":70},[40,2153,674],{"class":304},[40,2155,2156],{"class":42,"line":63},[40,2157,1496],{"class":74},[40,2159,2160],{"class":42,"line":128},[40,2161,60],{"emptyLinePlaceholder":59},[40,2163,2164,2166,2169],{"class":42,"line":153},[40,2165,67],{"class":66},[40,2167,2168],{"class":70}," stdlibGenerics",[40,2170,591],{"class":74},[40,2172,2173],{"class":42,"line":170},[40,2174,2175],{"class":46},"    \u002F\u002F ─── slices package ───\n",[40,2177,2178,2181,2183,2185,2187,2189,2191,2193,2195,2197,2200,2202,2204,2206,2209,2211,2214,2216,2218,2220,2223],{"class":42,"line":185},[40,2179,2180],{"class":74},"    s ",[40,2182,134],{"class":66},[40,2184,97],{"class":74},[40,2186,229],{"class":66},[40,2188,232],{"class":74},[40,2190,246],{"class":235},[40,2192,82],{"class":74},[40,2194,236],{"class":235},[40,2196,82],{"class":74},[40,2198,2199],{"class":235},"4",[40,2201,82],{"class":74},[40,2203,236],{"class":235},[40,2205,82],{"class":74},[40,2207,2208],{"class":235},"5",[40,2210,82],{"class":74},[40,2212,2213],{"class":235},"9",[40,2215,82],{"class":74},[40,2217,241],{"class":235},[40,2219,82],{"class":74},[40,2221,2222],{"class":235},"6",[40,2224,203],{"class":74},[40,2226,2227,2230,2233,2236],{"class":42,"line":191},[40,2228,2229],{"class":74},"    slices.",[40,2231,2232],{"class":70},"Sort",[40,2234,2235],{"class":74},"(s)                              ",[40,2237,2238],{"class":46},"\u002F\u002F [1 1 2 3 4 5 6 9]\n",[40,2240,2241,2243,2246,2249,2251,2253,2255,2257,2259,2261,2263,2265,2267,2269,2271,2273],{"class":42,"line":200},[40,2242,2229],{"class":74},[40,2244,2245],{"class":70},"SortStableFunc",[40,2247,2248],{"class":74},"(s, ",[40,2250,67],{"class":66},[40,2252,110],{"class":74},[40,2254,705],{"class":78},[40,2256,82],{"class":74},[40,2258,710],{"class":78},[40,2260,259],{"class":66},[40,2262,115],{"class":74},[40,2264,229],{"class":66},[40,2266,266],{"class":74},[40,2268,269],{"class":66},[40,2270,727],{"class":74},[40,2272,1381],{"class":66},[40,2274,2275],{"class":74}," b })\n",[40,2277,2278,2280,2283],{"class":42,"line":206},[40,2279,2229],{"class":74},[40,2281,2282],{"class":70},"Reverse",[40,2284,2285],{"class":74},"(s)\n",[40,2287,2288,2291,2293,2296,2299,2302],{"class":42,"line":211},[40,2289,2290],{"class":74},"    clone ",[40,2292,134],{"class":66},[40,2294,2295],{"class":74}," slices.",[40,2297,2298],{"class":70},"Clone",[40,2300,2301],{"class":74},"(s)                   ",[40,2303,2304],{"class":46},"\u002F\u002F independent copy\n",[40,2306,2307,2309,2312,2314,2316,2319],{"class":42,"line":217},[40,2308,2229],{"class":74},[40,2310,2311],{"class":70},"Contains",[40,2313,2248],{"class":74},[40,2315,2208],{"class":235},[40,2317,2318],{"class":74},")                      ",[40,2320,2321],{"class":46},"\u002F\u002F true\n",[40,2323,2324,2327,2329,2331,2334,2336,2338,2341],{"class":42,"line":287},[40,2325,2326],{"class":74},"    idx, found ",[40,2328,134],{"class":66},[40,2330,2295],{"class":74},[40,2332,2333],{"class":70},"BinarySearch",[40,2335,2248],{"class":74},[40,2337,2199],{"class":235},[40,2339,2340],{"class":74},")    ",[40,2342,2343],{"class":46},"\u002F\u002F idx=3, found=true\n",[40,2345,2346,2348,2350,2352,2355,2357,2359,2361,2363,2366],{"class":42,"line":319},[40,2347,2180],{"class":74},[40,2349,176],{"class":66},[40,2351,2295],{"class":74},[40,2353,2354],{"class":70},"Delete",[40,2356,2248],{"class":74},[40,2358,2033],{"class":235},[40,2360,82],{"class":74},[40,2362,241],{"class":235},[40,2364,2365],{"class":74},")                 ",[40,2367,2368],{"class":46},"\u002F\u002F remove indices 0,1\n",[40,2370,2371,2373,2375,2377,2380,2382,2384,2386,2388,2390],{"class":42,"line":324},[40,2372,2180],{"class":74},[40,2374,176],{"class":66},[40,2376,2295],{"class":74},[40,2378,2379],{"class":70},"Insert",[40,2381,2248],{"class":74},[40,2383,2033],{"class":235},[40,2385,82],{"class":74},[40,2387,2033],{"class":235},[40,2389,2365],{"class":74},[40,2391,2392],{"class":46},"\u002F\u002F insert 0 at front\n",[40,2394,2395,2397,2400,2403],{"class":42,"line":330},[40,2396,2229],{"class":74},[40,2398,2399],{"class":70},"Compact",[40,2401,2402],{"class":74},"(s)                          ",[40,2404,2405],{"class":46},"\u002F\u002F remove consecutive duplicates\n",[40,2407,2408,2410,2413,2415,2417,2419,2421,2423,2425,2427,2429,2431,2434,2437,2440],{"class":42,"line":594},[40,2409,2229],{"class":74},[40,2411,2412],{"class":70},"DeleteFunc",[40,2414,2248],{"class":74},[40,2416,67],{"class":66},[40,2418,110],{"class":74},[40,2420,534],{"class":78},[40,2422,259],{"class":66},[40,2424,115],{"class":74},[40,2426,1047],{"class":66},[40,2428,266],{"class":74},[40,2430,269],{"class":66},[40,2432,2433],{"class":74}," v ",[40,2435,2436],{"class":66},"\u003C",[40,2438,2439],{"class":235}," 3",[40,2441,2442],{"class":74}," })\n",[40,2444,2445],{"class":42,"line":611},[40,2446,60],{"emptyLinePlaceholder":59},[40,2448,2449],{"class":42,"line":620},[40,2450,2451],{"class":46},"    \u002F\u002F ─── maps package ───\n",[40,2453,2454,2457,2459,2462,2464,2466,2468,2470,2472,2474,2477,2479,2481,2483,2485,2487,2489,2492,2494,2496],{"class":42,"line":636},[40,2455,2456],{"class":74},"    m ",[40,2458,134],{"class":66},[40,2460,2461],{"class":66}," map",[40,2463,75],{"class":74},[40,2465,299],{"class":66},[40,2467,1628],{"class":74},[40,2469,229],{"class":66},[40,2471,232],{"class":74},[40,2473,305],{"class":304},[40,2475,2476],{"class":74},": ",[40,2478,236],{"class":235},[40,2480,82],{"class":74},[40,2482,310],{"class":304},[40,2484,2476],{"class":74},[40,2486,241],{"class":235},[40,2488,82],{"class":74},[40,2490,2491],{"class":304},"\"c\"",[40,2493,2476],{"class":74},[40,2495,246],{"class":235},[40,2497,203],{"class":74},[40,2499,2500,2503,2505,2508,2511,2514],{"class":42,"line":646},[40,2501,2502],{"class":74},"    keys ",[40,2504,134],{"class":66},[40,2506,2507],{"class":74}," maps.",[40,2509,2510],{"class":70},"Keys",[40,2512,2513],{"class":74},"(m)        ",[40,2515,2516],{"class":46},"\u002F\u002F []string (unordered, Go 1.23+: iter.Seq)\n",[40,2518,2519,2522,2524,2526,2529,2532],{"class":42,"line":651},[40,2520,2521],{"class":74},"    vals ",[40,2523,134],{"class":66},[40,2525,2507],{"class":74},[40,2527,2528],{"class":70},"Values",[40,2530,2531],{"class":74},"(m)      ",[40,2533,2534],{"class":46},"\u002F\u002F []int\n",[40,2536,2537,2540,2543,2546],{"class":42,"line":656},[40,2538,2539],{"class":74},"    maps.",[40,2541,2542],{"class":70},"Copy",[40,2544,2545],{"class":74},"(dst, src)         ",[40,2547,2548],{"class":46},"\u002F\u002F copy all entries from src to dst\n",[40,2550,2551,2553,2556,2559],{"class":42,"line":662},[40,2552,2539],{"class":74},[40,2554,2555],{"class":70},"Equal",[40,2557,2558],{"class":74},"(m1, m2)          ",[40,2560,2561],{"class":46},"\u002F\u002F compare two maps\n",[40,2563,2564,2566,2568,2571,2573,2575,2578,2580,2582,2584,2586,2588,2590,2592,2594,2596,2598,2600],{"class":42,"line":677},[40,2565,2539],{"class":74},[40,2567,2412],{"class":70},[40,2569,2570],{"class":74},"(m, ",[40,2572,67],{"class":66},[40,2574,110],{"class":74},[40,2576,2577],{"class":78},"k",[40,2579,853],{"class":66},[40,2581,82],{"class":74},[40,2583,534],{"class":78},[40,2585,259],{"class":66},[40,2587,115],{"class":74},[40,2589,1047],{"class":66},[40,2591,266],{"class":74},[40,2593,269],{"class":66},[40,2595,2433],{"class":74},[40,2597,2436],{"class":66},[40,2599,278],{"class":235},[40,2601,2442],{"class":74},[40,2603,2604,2606,2608,2611],{"class":42,"line":682},[40,2605,2539],{"class":74},[40,2607,2298],{"class":70},[40,2609,2610],{"class":74},"(m)               ",[40,2612,2304],{"class":46},[40,2614,2615],{"class":42,"line":721},[40,2616,203],{"class":74},[40,2618,2619],{"class":42,"line":741},[40,2620,60],{"emptyLinePlaceholder":59},[40,2622,2623],{"class":42,"line":749},[40,2624,2625],{"class":46},"\u002F\u002F Prefer slices\u002Fmaps over hand-rolled helpers — tested, idiomatic, fast.\n",[23,2627,2629],{"id":2628},"type-inference-when-you-need-explicit-args","Type Inference — When You Need Explicit Args",[28,2631,2632,2832,2836],{"language":30},[32,2633,2635],{"className":34,"code":2634,"language":30,"meta":36,"style":36},"\u002F\u002F Go infers type args in most cases. You need explicit args when:\n\u002F\u002F   1. Inference is ambiguous\n\u002F\u002F   2. You want a different type than what would be inferred\n\u002F\u002F   3. The function has no parameters to infer from\n\n\u002F\u002F Case 1: empty slice — can't infer T from []T{}:\n\u002F\u002F Map([]int{}, func(x int) int { return x * 2 })  \u002F\u002F ok (function literal hints T)\n\u002F\u002F But sometimes the compiler can't infer:\n\u002F\u002F   func Foo[T any]() T { var zero T; return zero }\n\u002F\u002F   x := Foo()  \u002F\u002F ❌ can't infer T\n\u002F\u002F   x := Foo[int]()  \u002F\u002F ✅ explicit\n\n\u002F\u002F Case 2: different result type than input:\nfunc Transform[T any, U any](v T, fn func(T) U) U { return fn(v) }\n\u002F\u002F Transform(42, func(x int) string { return fmt.Sprintf(\"%d\", x) })\n\u002F\u002F — T=int, U=string — inferred from the function literal. Usually works.\n\n\u002F\u002F Case 3: no args to infer from:\nfunc Zero[T any]() T { var zero T; return zero }\n_ = Zero[int]()  \u002F\u002F must specify T — no value to infer from\n",[18,2636,2637,2642,2647,2652,2657,2661,2666,2674,2679,2684,2692,2700,2704,2709,2761,2766,2771,2775,2780,2814],{"__ignoreMap":36},[40,2638,2639],{"class":42,"line":43},[40,2640,2641],{"class":46},"\u002F\u002F Go infers type args in most cases. You need explicit args when:\n",[40,2643,2644],{"class":42,"line":50},[40,2645,2646],{"class":46},"\u002F\u002F   1. Inference is ambiguous\n",[40,2648,2649],{"class":42,"line":56},[40,2650,2651],{"class":46},"\u002F\u002F   2. You want a different type than what would be inferred\n",[40,2653,2654],{"class":42,"line":63},[40,2655,2656],{"class":46},"\u002F\u002F   3. The function has no parameters to infer from\n",[40,2658,2659],{"class":42,"line":128},[40,2660,60],{"emptyLinePlaceholder":59},[40,2662,2663],{"class":42,"line":153},[40,2664,2665],{"class":46},"\u002F\u002F Case 1: empty slice — can't infer T from []T{}:\n",[40,2667,2668,2671],{"class":42,"line":170},[40,2669,2670],{"class":46},"\u002F\u002F Map([]int{}, func(x int) int { return x * 2 })",[40,2672,2673],{"class":46},"  \u002F\u002F ok (function literal hints T)\n",[40,2675,2676],{"class":42,"line":185},[40,2677,2678],{"class":46},"\u002F\u002F But sometimes the compiler can't infer:\n",[40,2680,2681],{"class":42,"line":191},[40,2682,2683],{"class":46},"\u002F\u002F   func Foo[T any]() T { var zero T; return zero }\n",[40,2685,2686,2689],{"class":42,"line":200},[40,2687,2688],{"class":46},"\u002F\u002F   x := Foo()",[40,2690,2691],{"class":46},"  \u002F\u002F ❌ can't infer T\n",[40,2693,2694,2697],{"class":42,"line":206},[40,2695,2696],{"class":46},"\u002F\u002F   x := Foo[int]()",[40,2698,2699],{"class":46},"  \u002F\u002F ✅ explicit\n",[40,2701,2702],{"class":42,"line":211},[40,2703,60],{"emptyLinePlaceholder":59},[40,2705,2706],{"class":42,"line":217},[40,2707,2708],{"class":46},"\u002F\u002F Case 2: different result type than input:\n",[40,2710,2711,2713,2716,2718,2720,2722,2724,2726,2728,2730,2732,2734,2736,2738,2740,2742,2744,2746,2748,2750,2752,2754,2756,2758],{"class":42,"line":287},[40,2712,67],{"class":66},[40,2714,2715],{"class":70}," Transform",[40,2717,75],{"class":74},[40,2719,79],{"class":78},[40,2721,88],{"class":70},[40,2723,82],{"class":74},[40,2725,85],{"class":78},[40,2727,88],{"class":70},[40,2729,91],{"class":74},[40,2731,534],{"class":78},[40,2733,537],{"class":70},[40,2735,82],{"class":74},[40,2737,104],{"class":78},[40,2739,107],{"class":66},[40,2741,110],{"class":74},[40,2743,79],{"class":70},[40,2745,115],{"class":74},[40,2747,85],{"class":70},[40,2749,115],{"class":74},[40,2751,85],{"class":70},[40,2753,266],{"class":74},[40,2755,269],{"class":66},[40,2757,179],{"class":70},[40,2759,2760],{"class":74},"(v) }\n",[40,2762,2763],{"class":42,"line":319},[40,2764,2765],{"class":46},"\u002F\u002F Transform(42, func(x int) string { return fmt.Sprintf(\"%d\", x) })\n",[40,2767,2768],{"class":42,"line":324},[40,2769,2770],{"class":46},"\u002F\u002F — T=int, U=string — inferred from the function literal. Usually works.\n",[40,2772,2773],{"class":42,"line":330},[40,2774,60],{"emptyLinePlaceholder":59},[40,2776,2777],{"class":42,"line":594},[40,2778,2779],{"class":46},"\u002F\u002F Case 3: no args to infer from:\n",[40,2781,2782,2784,2787,2789,2791,2793,2795,2797,2799,2802,2804,2806,2809,2811],{"class":42,"line":611},[40,2783,67],{"class":66},[40,2785,2786],{"class":70}," Zero",[40,2788,75],{"class":74},[40,2790,79],{"class":78},[40,2792,88],{"class":70},[40,2794,1198],{"class":74},[40,2796,79],{"class":70},[40,2798,266],{"class":74},[40,2800,2801],{"class":66},"var",[40,2803,1327],{"class":74},[40,2805,79],{"class":70},[40,2807,2808],{"class":74},"; ",[40,2810,269],{"class":66},[40,2812,2813],{"class":74}," zero }\n",[40,2815,2816,2818,2820,2822,2824,2826,2829],{"class":42,"line":620},[40,2817,333],{"class":74},[40,2819,176],{"class":66},[40,2821,2786],{"class":70},[40,2823,75],{"class":74},[40,2825,229],{"class":66},[40,2827,2828],{"class":74},"]()  ",[40,2830,2831],{"class":46},"\u002F\u002F must specify T — no value to infer from\n",[23,2833,2835],{"id":2834},"when-to-use-generics-and-when-not","When to Use Generics — and When Not",[28,2837,2838,2945,2949,3044,3048,3143,3147],{"language":30},[32,2839,2841],{"className":34,"code":2840,"language":30,"meta":36,"style":36},"\u002F\u002F ┌──────────────────────────┬──────────────────────────────────────────┐\n\u002F\u002F │ Use generics for          │ Avoid generics for                       │\n\u002F\u002F │ ──────────────────────────│ ───────────────────────────────────────── │\n\u002F\u002F │ Container types (Stack[T])│ Single-use code (write it concretely)    │\n\u002F\u002F │ Utility funcs (Map, Filter)│ When an interface is clearer             │\n\u002F\u002F │ Algorithms over types     │ Over-abstraction (a generic framework)   │\n\u002F\u002F │ Replacing interface{} +   │ When the type constraint is so specific   │\n\u002F\u002F │   type assertions          │   that only one type ever satisfies it    │\n\u002F\u002F └──────────────────────────┴──────────────────────────────────────────┘\n\n\u002F\u002F ❌ ANTI-PATTERN: over-genericizing single-use code\n\u002F\u002F   func process[T any](items []T, fn func(T) T) []T { ... }\n\u002F\u002F   If you only call this with []User once, just write:\n\u002F\u002F   func processUsers(items []User, fn func(User) User) []User { ... }\n\n\u002F\u002F ✅ CORRECT: generics for reusable containers:\n\u002F\u002F   Stack[T], Set[T], Queue[T], Map[K, V] — used across many types\n\n\u002F\u002F ❌ ANTI-PATTERN: generic with a single-type constraint\n\u002F\u002F   func OnlyInt[T int](v T) T { return v }\n\u002F\u002F   If only int works, just use int — generics add no value.\n",[18,2842,2843,2848,2853,2858,2863,2868,2873,2878,2883,2888,2892,2897,2902,2907,2912,2916,2921,2926,2930,2935,2940],{"__ignoreMap":36},[40,2844,2845],{"class":42,"line":43},[40,2846,2847],{"class":46},"\u002F\u002F ┌──────────────────────────┬──────────────────────────────────────────┐\n",[40,2849,2850],{"class":42,"line":50},[40,2851,2852],{"class":46},"\u002F\u002F │ Use generics for          │ Avoid generics for                       │\n",[40,2854,2855],{"class":42,"line":56},[40,2856,2857],{"class":46},"\u002F\u002F │ ──────────────────────────│ ───────────────────────────────────────── │\n",[40,2859,2860],{"class":42,"line":63},[40,2861,2862],{"class":46},"\u002F\u002F │ Container types (Stack[T])│ Single-use code (write it concretely)    │\n",[40,2864,2865],{"class":42,"line":128},[40,2866,2867],{"class":46},"\u002F\u002F │ Utility funcs (Map, Filter)│ When an interface is clearer             │\n",[40,2869,2870],{"class":42,"line":153},[40,2871,2872],{"class":46},"\u002F\u002F │ Algorithms over types     │ Over-abstraction (a generic framework)   │\n",[40,2874,2875],{"class":42,"line":170},[40,2876,2877],{"class":46},"\u002F\u002F │ Replacing interface{} +   │ When the type constraint is so specific   │\n",[40,2879,2880],{"class":42,"line":185},[40,2881,2882],{"class":46},"\u002F\u002F │   type assertions          │   that only one type ever satisfies it    │\n",[40,2884,2885],{"class":42,"line":191},[40,2886,2887],{"class":46},"\u002F\u002F └──────────────────────────┴──────────────────────────────────────────┘\n",[40,2889,2890],{"class":42,"line":200},[40,2891,60],{"emptyLinePlaceholder":59},[40,2893,2894],{"class":42,"line":206},[40,2895,2896],{"class":46},"\u002F\u002F ❌ ANTI-PATTERN: over-genericizing single-use code\n",[40,2898,2899],{"class":42,"line":211},[40,2900,2901],{"class":46},"\u002F\u002F   func process[T any](items []T, fn func(T) T) []T { ... }\n",[40,2903,2904],{"class":42,"line":217},[40,2905,2906],{"class":46},"\u002F\u002F   If you only call this with []User once, just write:\n",[40,2908,2909],{"class":42,"line":287},[40,2910,2911],{"class":46},"\u002F\u002F   func processUsers(items []User, fn func(User) User) []User { ... }\n",[40,2913,2914],{"class":42,"line":319},[40,2915,60],{"emptyLinePlaceholder":59},[40,2917,2918],{"class":42,"line":324},[40,2919,2920],{"class":46},"\u002F\u002F ✅ CORRECT: generics for reusable containers:\n",[40,2922,2923],{"class":42,"line":330},[40,2924,2925],{"class":46},"\u002F\u002F   Stack[T], Set[T], Queue[T], Map[K, V] — used across many types\n",[40,2927,2928],{"class":42,"line":594},[40,2929,60],{"emptyLinePlaceholder":59},[40,2931,2932],{"class":42,"line":611},[40,2933,2934],{"class":46},"\u002F\u002F ❌ ANTI-PATTERN: generic with a single-type constraint\n",[40,2936,2937],{"class":42,"line":620},[40,2938,2939],{"class":46},"\u002F\u002F   func OnlyInt[T int](v T) T { return v }\n",[40,2941,2942],{"class":42,"line":636},[40,2943,2944],{"class":46},"\u002F\u002F   If only int works, just use int — generics add no value.\n",[23,2946,2948],{"id":2947},"tips-tricks","💡 Tips & Tricks",[2950,2951,2952,2981,3006,3017,3022,3038],"ul",{},[2953,2954,2955,2959,2960,2962,2963,2965,2966,82,2968,82,2970,82,2972,82,2974,82,2976,82,2978,2980],"li",{},[2956,2957,2958],"strong",{},"Idiom",": prefer ",[18,2961,2117],{},"\u002F",[18,2964,2121],{}," (Go 1.21+) over hand-rolled generic helpers — they cover ",[18,2967,2232],{},[18,2969,2311],{},[18,2971,2298],{},[18,2973,2333],{},[18,2975,2510],{},[18,2977,2528],{},[18,2979,2555],{},". Reach for your own generics only when the stdlib doesn't cover the case.",[2953,2982,2983,2985,2986,2988,2989,2991,2992,2994,2995,2998,2999,3002,3003,3005],{},[2956,2984,2958],{},": use ",[18,2987,402],{}," in constraints to include named types — ",[18,2990,496],{}," matches ",[18,2993,229],{}," AND ",[18,2996,2997],{},"type MyInt int",". Without ",[18,3000,3001],{},"~",", named types based on ",[18,3004,229],{}," don't match, which is rarely what you want for numeric constraints.",[2953,3007,3008,2985,3010,3013,3014,697],{},[2956,3009,2958],{},[18,3011,3012],{},"cmp.Ordered"," (Go 1.21+) for \"any orderable type\" — covers integers, floats, and strings. Pre-1.21, define the constraint yourself or use ",[18,3015,3016],{},"golang.org\u002Fx\u002Fexp\u002Fconstraints",[2953,3018,3019,3021],{},[2956,3020,2958],{},": don't over-genericize — if a function is used with one type, write it concretely. Generics shine for reusable containers and algorithms; over-abstracting single-use code adds complexity.",[2953,3023,3024,3026,3027,3029,3030,3033,3034,3037],{},[2956,3025,2958],{},": use generics to replace ",[18,3028,20],{}," + type assertions where the type is known at the call site — a ",[18,3031,3032],{},"Stack[T]"," is type-safe (no ",[18,3035,3036],{},"any",", no assertion), and the compiler catches type mismatches at compile time.",[2953,3039,3040,3043],{},[2956,3041,3042],{},"Performance",": generic functions are monomorphized in most cases — the compiler generates a version per type argument, so there's no runtime overhead (no virtual dispatch like interfaces). But this increases binary size.",[23,3045,3047],{"id":3046},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[2950,3049,3050,3056,3071,3090,3102,3111,3124,3130],{},[2953,3051,3052,3055],{},[2956,3053,3054],{},"Generics don't work with methods",": Go doesn't support generic methods (methods with their own type parameters distinct from the receiver's). Methods can use the receiver's type parameters, but can't add new ones. This is a known limitation.",[2953,3057,3058,3064,3065,3067,3068,3070],{},[2956,3059,3060,3063],{},[18,3061,3062],{},"comparable"," doesn't include slices\u002Fmaps\u002Ffunctions",": a struct containing a slice isn't ",[18,3066,3062],{},", even if all other fields are. Can't use it as a map key or in ",[18,3069,1071],{}," within a generic function.",[2953,3072,3073,2476,3078,2991,3080,3082,3083,3086,3087,3089],{},[2956,3074,3075,3077],{},[18,3076,402],{}," requires the underlying type",[18,3079,496],{},[18,3081,2997],{}," but NOT ",[18,3084,3085],{},"type MyStruct struct{ x int }",". The ",[18,3088,3001],{}," matches underlying type, not struct fields.",[2953,3091,3092,2476,3095,3098,3099,697],{},[2956,3093,3094],{},"Type inference can fail on nil",[18,3096,3097],{},"Map(nil, fn)"," — can't infer T from a nil slice. Specify explicitly: ",[18,3100,3101],{},"Map[int, int](nil, fn)",[2953,3103,3104,2476,3107,3110],{},[2956,3105,3106],{},"Generic types can't have generic methods",[18,3108,3109],{},"type Stack[T any] struct{}; func (s *Stack[T]) Map[U any](fn func(T) U) []U"," — compile error. This is the #1 generics limitation.",[2953,3112,3113,2476,3116,3119,3120,3123],{},[2956,3114,3115],{},"Constraint interfaces with methods can't be used as regular interfaces",[18,3117,3118],{},"type Stringer interface { String() string }"," works as both a constraint and a regular interface. But ",[18,3121,3122],{},"type Num interface { ~int | ~float64; String() string }"," can only be a constraint (type sets can't be in regular interfaces).",[2953,3125,3126,3129],{},[2956,3127,3128],{},"Binary size",": generics are monomorphized — each type argument generates a separate copy. For a generic function used with 10 types, the binary includes 10 copies. Usually negligible, but can matter for embedded\u002Fbinary-size-constrained builds.",[2953,3131,3132,2476,3135,3138,3139,3142],{},[2956,3133,3134],{},"Zero value of a type parameter",[18,3136,3137],{},"var zero T"," gives the zero value of T — works for any T. Can't do ",[18,3140,3141],{},"T{}"," (struct literal) unless T is constrained to structs.",[23,3144,3146],{"id":3145},"quick-quiz","🧠 Quick Quiz",[28,3148,3149,3265],{"language":30},[32,3150,3152],{"className":34,"code":3151,"language":30,"meta":36,"style":36},"type MyInt int\n\nfunc Add[T ~int](a, b T) T { return a + b }\n\nfunc main() {\n    var x MyInt = 10\n    var y MyInt = 20\n    fmt.Println(Add(x, y))\n}\n",[18,3153,3154,3162,3166,3206,3210,3219,3232,3246,3261],{"__ignoreMap":36},[40,3155,3156,3158,3160],{"class":42,"line":43},[40,3157,428],{"class":66},[40,3159,509],{"class":70},[40,3161,512],{"class":66},[40,3163,3164],{"class":42,"line":50},[40,3165,60],{"emptyLinePlaceholder":59},[40,3167,3168,3170,3173,3175,3177,3180,3182,3184,3186,3188,3190,3192,3194,3196,3198,3200,3203],{"class":42,"line":56},[40,3169,67],{"class":66},[40,3171,3172],{"class":70}," Add",[40,3174,75],{"class":74},[40,3176,79],{"class":78},[40,3178,3179],{"class":66}," ~int",[40,3181,91],{"class":74},[40,3183,705],{"class":78},[40,3185,82],{"class":74},[40,3187,710],{"class":78},[40,3189,537],{"class":70},[40,3191,115],{"class":74},[40,3193,79],{"class":70},[40,3195,266],{"class":74},[40,3197,269],{"class":66},[40,3199,727],{"class":74},[40,3201,3202],{"class":66},"+",[40,3204,3205],{"class":74}," b }\n",[40,3207,3208],{"class":42,"line":63},[40,3209,60],{"emptyLinePlaceholder":59},[40,3211,3212,3214,3217],{"class":42,"line":128},[40,3213,67],{"class":66},[40,3215,3216],{"class":70}," main",[40,3218,591],{"class":74},[40,3220,3221,3223,3225,3227,3229],{"class":42,"line":153},[40,3222,597],{"class":66},[40,3224,272],{"class":74},[40,3226,602],{"class":70},[40,3228,605],{"class":66},[40,3230,3231],{"class":235}," 10\n",[40,3233,3234,3236,3239,3241,3243],{"class":42,"line":170},[40,3235,597],{"class":66},[40,3237,3238],{"class":74}," y ",[40,3240,602],{"class":70},[40,3242,605],{"class":66},[40,3244,3245],{"class":235}," 20\n",[40,3247,3248,3251,3253,3255,3258],{"class":42,"line":185},[40,3249,3250],{"class":74},"    fmt.",[40,3252,2015],{"class":70},[40,3254,110],{"class":74},[40,3256,3257],{"class":70},"Add",[40,3259,3260],{"class":74},"(x, y))\n",[40,3262,3263],{"class":42,"line":191},[40,3264,203],{"class":74},[14,3266,3267],{},"Does this compile, and what's printed?",[3269,3270,3271,3275,3278,3286,3302,3321],"details",{},[3272,3273,3274],"summary",{},"Answer",[14,3276,3277],{},"Compiles and prints:",[32,3279,3284],{"className":3280,"code":3282,"language":3283},[3281],"language-text","30\n","text",[18,3285,3282],{"__ignoreMap":36},[14,3287,3288,3289,2991,3291,3293,3294,3296,3297,3086,3299,3301],{},"The constraint ",[18,3290,496],{},[18,3292,602],{}," because ",[18,3295,602],{},"'s underlying type is ",[18,3298,229],{},[18,3300,3001],{}," tilde prefix means \"this type or any named type with this underlying type.\"",[14,3303,3304,3305,3307,3308,3310,3311,3314,3315,3317,3318,3320],{},"If the constraint were ",[18,3306,229],{}," (without ",[18,3309,3001],{},"), ",[18,3312,3313],{},"Add(x, y)"," would fail with: \"MyInt does not satisfy int\" — because ",[18,3316,229],{}," (without tilde) only matches the predeclared ",[18,3319,229],{},", not named types based on it.",[14,3322,3323,3324,3326,3327,82,3330,3333],{},"This is why ",[18,3325,3001],{}," is critical in constraints for numeric types — users often have ",[18,3328,3329],{},"type UserID int64",[18,3331,3332],{},"type Celsius float64",", etc., and they expect generic numeric functions to work with them.",[23,3335,3337],{"id":3336},"whats-next","📚 What's Next",[14,3339,3340,3341,3345,3346,2962,3349,3352],{},"→ ",[705,3342,3344],{"href":3343},"\u002Fgo\u002F15-error-handling","15 — Error Handling"," — error wrapping, ",[18,3347,3348],{},"errors.Is",[18,3350,3351],{},"As",", sentinel errors, typed errors, and the panic-vs-error decision.",[3354,3355,3356],"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 .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}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);}",{"title":36,"searchDepth":50,"depth":50,"links":3358},[3359,3360,3362],{"id":25,"depth":50,"text":26},{"id":398,"depth":50,"text":3361},"Type Constraints — Type Sets and ~T",{"id":3336,"depth":50,"text":3337},"Type parameters, type-set constraints, `~T` underlying-type matching, `cmp.Ordered`, the `slices`\u002F`maps` packages, and generic type design patterns.","md",{},"\u002Fgo\u002F14-generics",{"title":5,"description":3363},"go\u002F14-generics","3igW82cvz6XdtvvBYChQOygzcBLkgvo4zLxOBEpy3to",1789924648538]