[{"data":1,"prerenderedAt":6873},["ShallowReactive",2],{"content:\u002F02-functions-errors\u002F01-functions":3},{"title":4,"description":5,"path":6,"body":7},"Функции в Go","","\u002F02-functions-errors\u002F01-functions",{"type":8,"value":9,"toc":6803},"minimark",[10,46,49,54,59,126,130,134,183,187,227,231,290,294,408,411,414,416,457,459,463,467,664,668,721,725,776,779,783,804,811,813,855,857,861,865,1001,1011,1015,1136,1145,1149,1245,1248,1252,1345,1355,1357,1393,1395,1399,1403,1488,1501,1505,1623,1636,1640,1828,1832,1907,1916,1918,1951,1953,1957,1961,2109,2126,2130,2138,2151,2223,2227,2347,2368,2372,2499,2516,2518,2541,2543,2547,2551,2811,2814,2818,2998,3010,3014,3141,3147,3149,3177,3179,3183,3187,3356,3360,3412,3416,3548,3551,3555,3610,3617,3621,3624,3626,3655,3657,3661,3665,3725,3739,3743,3782,3793,3797,3853,3863,3866,3869,3904,3907,3909,3964,3970,3972,4003,4005,4009,4013,4198,4205,4212,4216,4223,4227,4426,4433,4437,4440,4446,4453,4455,4475,4477,4481,4484,4730,4733,4736,4956,4959,4963,5046,5049,5053,5219,5222,5224,5247,5249,5253,5256,5407,5410,5414,5607,5613,5617,5899,5911,5923,5925,5929,6073,6266,6522,6799],[11,12,13,22,25,32,39],"ul",{},[14,15,16,17,21],"li",{},"функция = ",[18,19,20],"strong",{},"адрес первой инструкции"," её скомпилированного кода",[14,23,24],{},"параметры — переменные в объявлении; аргументы — значения при вызове",[14,26,27,28,31],{},"аргументы вычисляются ",[18,29,30],{},"слева направо"," (в C++ порядок не определён)",[14,33,34,35,38],{},"сигнатура = типы входных параметров + типы возвращаемых значений (имя, тело, имена параметров — ",[18,36,37],{},"не"," часть сигнатуры)",[14,40,41,42,45],{},"при передаче и возврате ",[18,43,44],{},"всё копируется"," (указатель, slice, map, interface — копия заголовка)",[47,48],"hr",{},[50,51,53],"h2",{"id":52},"модель-вызова-функции","Модель вызова функции",[55,56,58],"h3",{"id":57},"функция-адрес","Функция = адрес",[60,61,65],"pre",{"className":62,"code":63,"language":64,"meta":5,"style":5},"language-go shiki shiki-themes github-dark","func add(a, b int) int { return a + b }\n\u002F\u002F add → 0x4A3F10 (адрес первой инструкции)\n","go",[66,67,68,119],"code",{"__ignoreMap":5},[69,70,73,77,81,85,89,92,95,98,101,104,107,110,113,116],"span",{"class":71,"line":72},"line",1,[69,74,76],{"class":75},"snl16","func",[69,78,80],{"class":79},"svObZ"," add",[69,82,84],{"class":83},"s95oV","(",[69,86,88],{"class":87},"s9osk","a",[69,90,91],{"class":83},", ",[69,93,94],{"class":87},"b",[69,96,97],{"class":75}," int",[69,99,100],{"class":83},") ",[69,102,103],{"class":75},"int",[69,105,106],{"class":83}," { ",[69,108,109],{"class":75},"return",[69,111,112],{"class":83}," a ",[69,114,115],{"class":75},"+",[69,117,118],{"class":83}," b }\n",[69,120,122],{"class":71,"line":121},2,[69,123,125],{"class":124},"sAwPA","\u002F\u002F add → 0x4A3F10 (адрес первой инструкции)\n",[127,128,129],"p",{},"Вызов функции = переход по этому адресу (инструкция CALL).",[55,131,133],{"id":132},"параметры-vs-аргументы","Параметры vs аргументы",[60,135,137],{"className":62,"code":136,"language":64,"meta":5,"style":5},"func greet(name string) { ... }  \u002F\u002F name — параметр (объявление)\ngreet(\"Alice\")                    \u002F\u002F \"Alice\" — аргумент (вызов)\n",[66,138,139,166],{"__ignoreMap":5},[69,140,141,143,146,148,151,154,157,160,163],{"class":71,"line":72},[69,142,76],{"class":75},[69,144,145],{"class":79}," greet",[69,147,84],{"class":83},[69,149,150],{"class":87},"name",[69,152,153],{"class":75}," string",[69,155,156],{"class":83},") { ",[69,158,159],{"class":75},"...",[69,161,162],{"class":83}," }  ",[69,164,165],{"class":124},"\u002F\u002F name — параметр (объявление)\n",[69,167,168,171,173,177,180],{"class":71,"line":121},[69,169,170],{"class":79},"greet",[69,172,84],{"class":83},[69,174,176],{"class":175},"sU2Wk","\"Alice\"",[69,178,179],{"class":83},")                    ",[69,181,182],{"class":124},"\u002F\u002F \"Alice\" — аргумент (вызов)\n",[55,184,186],{"id":185},"порядок-вычисления-аргументов","Порядок вычисления аргументов",[60,188,190],{"className":62,"code":189,"language":64,"meta":5,"style":5},"process(computeX(), computeY(), computeZ())\n\u002F\u002F        1️⃣            2️⃣            3️⃣\n\u002F\u002F слева направо — можно закладываться на порядок\n",[66,191,192,216,221],{"__ignoreMap":5},[69,193,194,197,199,202,205,208,210,213],{"class":71,"line":72},[69,195,196],{"class":79},"process",[69,198,84],{"class":83},[69,200,201],{"class":79},"computeX",[69,203,204],{"class":83},"(), ",[69,206,207],{"class":79},"computeY",[69,209,204],{"class":83},[69,211,212],{"class":79},"computeZ",[69,214,215],{"class":83},"())\n",[69,217,218],{"class":71,"line":121},[69,219,220],{"class":124},"\u002F\u002F        1️⃣            2️⃣            3️⃣\n",[69,222,224],{"class":71,"line":223},3,[69,225,226],{"class":124},"\u002F\u002F слева направо — можно закладываться на порядок\n",[55,228,230],{"id":229},"сигнатура","Сигнатура",[60,232,234],{"className":62,"code":233,"language":64,"meta":5,"style":5},"func add(a, b int) int            \u002F\u002F сигнатура: (int, int) int\nfunc sum(x, y int) int            \u002F\u002F сигнатура: (int, int) int — та же!\n\u002F\u002F имена a\u002Fb, x\u002Fy и имя функции — не часть сигнатуры\n",[66,235,236,259,285],{"__ignoreMap":5},[69,237,238,240,242,244,246,248,250,252,254,256],{"class":71,"line":72},[69,239,76],{"class":75},[69,241,80],{"class":79},[69,243,84],{"class":83},[69,245,88],{"class":87},[69,247,91],{"class":83},[69,249,94],{"class":87},[69,251,97],{"class":75},[69,253,100],{"class":83},[69,255,103],{"class":75},[69,257,258],{"class":124},"            \u002F\u002F сигнатура: (int, int) int\n",[69,260,261,263,266,268,271,273,276,278,280,282],{"class":71,"line":121},[69,262,76],{"class":75},[69,264,265],{"class":79}," sum",[69,267,84],{"class":83},[69,269,270],{"class":87},"x",[69,272,91],{"class":83},[69,274,275],{"class":87},"y",[69,277,97],{"class":75},[69,279,100],{"class":83},[69,281,103],{"class":75},[69,283,284],{"class":124},"            \u002F\u002F сигнатура: (int, int) int — та же!\n",[69,286,287],{"class":71,"line":223},[69,288,289],{"class":124},"\u002F\u002F имена a\u002Fb, x\u002Fy и имя функции — не часть сигнатуры\n",[55,291,293],{"id":292},"всё-копируется","Всё копируется",[60,295,297],{"className":62,"code":296,"language":64,"meta":5,"style":5},"func modify(s []int) { s[0] = 99 }   \u002F\u002F копия заголовка slice → тот же backing array\nfunc replace(m map[string]int) { m[\"a\"] = 1 } \u002F\u002F копия указателя → тот же hmap\nfunc bump(x int) { x++ }             \u002F\u002F копия значения → оригинал не изменён\n",[66,298,299,338,383],{"__ignoreMap":5},[69,300,301,303,306,308,311,314,316,319,323,326,329,332,335],{"class":71,"line":72},[69,302,76],{"class":75},[69,304,305],{"class":79}," modify",[69,307,84],{"class":83},[69,309,310],{"class":87},"s",[69,312,313],{"class":83}," []",[69,315,103],{"class":75},[69,317,318],{"class":83},") { s[",[69,320,322],{"class":321},"sDLfK","0",[69,324,325],{"class":83},"] ",[69,327,328],{"class":75},"=",[69,330,331],{"class":321}," 99",[69,333,334],{"class":83}," }   ",[69,336,337],{"class":124},"\u002F\u002F копия заголовка slice → тот же backing array\n",[69,339,340,342,345,347,350,353,356,359,362,364,367,370,372,374,377,380],{"class":71,"line":121},[69,341,76],{"class":75},[69,343,344],{"class":79}," replace",[69,346,84],{"class":83},[69,348,349],{"class":87},"m",[69,351,352],{"class":75}," map",[69,354,355],{"class":83},"[",[69,357,358],{"class":75},"string",[69,360,361],{"class":83},"]",[69,363,103],{"class":75},[69,365,366],{"class":83},") { m[",[69,368,369],{"class":175},"\"a\"",[69,371,325],{"class":83},[69,373,328],{"class":75},[69,375,376],{"class":321}," 1",[69,378,379],{"class":83}," } ",[69,381,382],{"class":124},"\u002F\u002F копия указателя → тот же hmap\n",[69,384,385,387,390,392,394,396,399,402,405],{"class":71,"line":223},[69,386,76],{"class":75},[69,388,389],{"class":79}," bump",[69,391,84],{"class":83},[69,393,270],{"class":87},[69,395,97],{"class":75},[69,397,398],{"class":83},") { x",[69,400,401],{"class":75},"++",[69,403,404],{"class":83}," }             ",[69,406,407],{"class":124},"\u002F\u002F копия значения → оригинал не изменён\n",[127,409,410],{},"Возврат — тоже копия.",[127,412,413],{},"Нет RVO: объект создаётся внутри, потом копируется наружу.",[47,415],{},[11,417,418,424,437,443,450],{},[14,419,420,421],{},"функции ведут себя как переменные: можно ",[18,422,423],{},"присваивать, передавать, возвращать",[14,425,426,429,430,433,434],{},[18,427,428],{},"нельзя сравнивать"," (как slice) и ",[18,431,432],{},"нельзя взять адрес"," ",[66,435,436],{},"&fn",[14,438,439,440],{},"zero value любого функционального типа = ",[18,441,442],{},"nil",[14,444,445,446,449],{},"встроенные функции (append, len, cap, make, copy...) ",[18,447,448],{},"нельзя"," использовать как значения",[14,451,452,453,456],{},"через ",[66,454,455],{},"unsafe"," взять адрес функции можно, но стандартный синтаксис — нет",[47,458],{},[50,460,462],{"id":461},"функции-как-значения","Функции как значения",[55,464,466],{"id":465},"функция-как-значение","Функция как значение",[60,468,470],{"className":62,"code":469,"language":64,"meta":5,"style":5},"\u002F\u002F присвоить\nvar fn func(int) int\nfn = func(x int) int { return x * 2 }\n\n\u002F\u002F передать в функцию\nfunc apply(f func(int) int, x int) int { return f(x) }\n\n\u002F\u002F вернуть из функции\nfunc multiplier(n int) func(int) int {\n    return func(x int) int { return x * n }\n}\n",[66,471,472,477,496,532,539,545,588,593,599,629,658],{"__ignoreMap":5},[69,473,474],{"class":71,"line":72},[69,475,476],{"class":124},"\u002F\u002F присвоить\n",[69,478,479,482,485,487,489,491,493],{"class":71,"line":121},[69,480,481],{"class":75},"var",[69,483,484],{"class":83}," fn ",[69,486,76],{"class":75},[69,488,84],{"class":83},[69,490,103],{"class":75},[69,492,100],{"class":83},[69,494,495],{"class":75},"int\n",[69,497,498,501,503,506,508,510,512,514,516,518,520,523,526,529],{"class":71,"line":223},[69,499,500],{"class":83},"fn ",[69,502,328],{"class":75},[69,504,505],{"class":75}," func",[69,507,84],{"class":83},[69,509,270],{"class":87},[69,511,97],{"class":75},[69,513,100],{"class":83},[69,515,103],{"class":75},[69,517,106],{"class":83},[69,519,109],{"class":75},[69,521,522],{"class":83}," x ",[69,524,525],{"class":75},"*",[69,527,528],{"class":321}," 2",[69,530,531],{"class":83}," }\n",[69,533,535],{"class":71,"line":534},4,[69,536,538],{"emptyLinePlaceholder":537},true,"\n",[69,540,542],{"class":71,"line":541},5,[69,543,544],{"class":124},"\u002F\u002F передать в функцию\n",[69,546,548,550,553,555,558,560,562,564,566,568,570,572,574,576,578,580,582,585],{"class":71,"line":547},6,[69,549,76],{"class":75},[69,551,552],{"class":79}," apply",[69,554,84],{"class":83},[69,556,557],{"class":87},"f",[69,559,505],{"class":75},[69,561,84],{"class":83},[69,563,103],{"class":75},[69,565,100],{"class":83},[69,567,103],{"class":75},[69,569,91],{"class":83},[69,571,270],{"class":87},[69,573,97],{"class":75},[69,575,100],{"class":83},[69,577,103],{"class":75},[69,579,106],{"class":83},[69,581,109],{"class":75},[69,583,584],{"class":79}," f",[69,586,587],{"class":83},"(x) }\n",[69,589,591],{"class":71,"line":590},7,[69,592,538],{"emptyLinePlaceholder":537},[69,594,596],{"class":71,"line":595},8,[69,597,598],{"class":124},"\u002F\u002F вернуть из функции\n",[69,600,602,604,607,609,612,614,616,618,620,622,624,626],{"class":71,"line":601},9,[69,603,76],{"class":75},[69,605,606],{"class":79}," multiplier",[69,608,84],{"class":83},[69,610,611],{"class":87},"n",[69,613,97],{"class":75},[69,615,100],{"class":83},[69,617,76],{"class":75},[69,619,84],{"class":83},[69,621,103],{"class":75},[69,623,100],{"class":83},[69,625,103],{"class":75},[69,627,628],{"class":83}," {\n",[69,630,632,635,637,639,641,643,645,647,649,651,653,655],{"class":71,"line":631},10,[69,633,634],{"class":75},"    return",[69,636,505],{"class":75},[69,638,84],{"class":83},[69,640,270],{"class":87},[69,642,97],{"class":75},[69,644,100],{"class":83},[69,646,103],{"class":75},[69,648,106],{"class":83},[69,650,109],{"class":75},[69,652,522],{"class":83},[69,654,525],{"class":75},[69,656,657],{"class":83}," n }\n",[69,659,661],{"class":71,"line":660},11,[69,662,663],{"class":83},"}\n",[55,665,667],{"id":666},"нельзя-сравнивать-и-брать-адрес","Нельзя сравнивать и брать адрес",[60,669,671],{"className":62,"code":670,"language":64,"meta":5,"style":5},"f1 := func() {}\nf2 := func() {}\n\u002F\u002F f1 == f2         \u002F\u002F ошибка компиляции\n\u002F\u002F f1 == nil        \u002F\u002F ✅ можно только с nil\n\u002F\u002F _ = &f1          \u002F\u002F нельзя взять адрес функции\n",[66,672,673,686,697,705,713],{"__ignoreMap":5},[69,674,675,678,681,683],{"class":71,"line":72},[69,676,677],{"class":83},"f1 ",[69,679,680],{"class":75},":=",[69,682,505],{"class":75},[69,684,685],{"class":83},"() {}\n",[69,687,688,691,693,695],{"class":71,"line":121},[69,689,690],{"class":83},"f2 ",[69,692,680],{"class":75},[69,694,505],{"class":75},[69,696,685],{"class":83},[69,698,699,702],{"class":71,"line":223},[69,700,701],{"class":124},"\u002F\u002F f1 == f2",[69,703,704],{"class":124},"         \u002F\u002F ошибка компиляции\n",[69,706,707,710],{"class":71,"line":534},[69,708,709],{"class":124},"\u002F\u002F f1 == nil",[69,711,712],{"class":124},"        \u002F\u002F ✅ можно только с nil\n",[69,714,715,718],{"class":71,"line":541},[69,716,717],{"class":124},"\u002F\u002F _ = &f1",[69,719,720],{"class":124},"          \u002F\u002F нельзя взять адрес функции\n",[55,722,724],{"id":723},"zero-value-nil","Zero value = nil",[60,726,728],{"className":62,"code":727,"language":64,"meta":5,"style":5},"var fn func(int) int\nfmt.Println(fn == nil) \u002F\u002F true\n\u002F\u002F fn(5)               \u002F\u002F panic: nil function call (намеренный пример — не запускать!)\n",[66,729,730,746,768],{"__ignoreMap":5},[69,731,732,734,736,738,740,742,744],{"class":71,"line":72},[69,733,481],{"class":75},[69,735,484],{"class":83},[69,737,76],{"class":75},[69,739,84],{"class":83},[69,741,103],{"class":75},[69,743,100],{"class":83},[69,745,495],{"class":75},[69,747,748,751,754,757,760,763,765],{"class":71,"line":121},[69,749,750],{"class":83},"fmt.",[69,752,753],{"class":79},"Println",[69,755,756],{"class":83},"(fn ",[69,758,759],{"class":75},"==",[69,761,762],{"class":321}," nil",[69,764,100],{"class":83},[69,766,767],{"class":124},"\u002F\u002F true\n",[69,769,770,773],{"class":71,"line":223},[69,771,772],{"class":124},"\u002F\u002F fn(5)",[69,774,775],{"class":124},"               \u002F\u002F panic: nil function call (намеренный пример — не запускать!)\n",[127,777,778],{},"Семантически функция — указатель на первую инструкцию. Nil = никуда не указывает.",[55,780,782],{"id":781},"встроенные-функции-не-значения","Встроенные функции — не значения",[60,784,786],{"className":62,"code":785,"language":64,"meta":5,"style":5},"\u002F\u002F f := append     \u002F\u002F ошибка: cannot use append as value\n\u002F\u002F f := len        \u002F\u002F ошибка: cannot use len as value\n",[66,787,788,796],{"__ignoreMap":5},[69,789,790,793],{"class":71,"line":72},[69,791,792],{"class":124},"\u002F\u002F f := append",[69,794,795],{"class":124},"     \u002F\u002F ошибка: cannot use append as value\n",[69,797,798,801],{"class":71,"line":121},[69,799,800],{"class":124},"\u002F\u002F f := len",[69,802,803],{"class":124},"        \u002F\u002F ошибка: cannot use len as value\n",[127,805,806,807,810],{},"Встроенные функции и ",[66,808,809],{},"init"," нельзя использовать как значения — особенность языка.",[47,812],{},[11,814,815,818,824,837,848],{},[14,816,817],{},"анонимная функция — определяется без имени, в месте использования",[14,819,820,821],{},"можно присвоить переменной или вызвать сразу ",[66,822,823],{},"func(x int){ ... }(42)",[14,825,826,829,830,833,834],{},[18,827,828],{},"variadic"," (",[66,831,832],{},"...T",") — синтаксический сахар над ",[66,835,836],{},"[]T",[14,838,839,840,843,844,847],{},"variadic: только ",[18,841,842],{},"один",", только ",[18,845,846],{},"последний"," в списке параметров",[14,849,850,851,854],{},"nil в variadic = nil slice; ",[66,852,853],{},"nil..."," = распаковка nil slice",[47,856],{},[50,858,860],{"id":859},"анонимные-и-variadic-функции","Анонимные и variadic-функции",[55,862,864],{"id":863},"анонимные-функции","Анонимные функции",[60,866,868],{"className":62,"code":867,"language":64,"meta":5,"style":5},"\u002F\u002F Способ 1: присвоить переменной\ndouble := func(x int) int { return x * 2 }\nfmt.Println(double(5))  \u002F\u002F 10\n\n\u002F\u002F Способ 2: вызвать сразу (IIFE)\nresult := func(a, b int) int {\n    return a + b\n}(3, 4)\nfmt.Println(result) \u002F\u002F 7 (функция вызвана сразу после определения)\n",[66,869,870,875,906,928,932,937,962,973,989],{"__ignoreMap":5},[69,871,872],{"class":71,"line":72},[69,873,874],{"class":124},"\u002F\u002F Способ 1: присвоить переменной\n",[69,876,877,880,882,884,886,888,890,892,894,896,898,900,902,904],{"class":71,"line":121},[69,878,879],{"class":83},"double ",[69,881,680],{"class":75},[69,883,505],{"class":75},[69,885,84],{"class":83},[69,887,270],{"class":87},[69,889,97],{"class":75},[69,891,100],{"class":83},[69,893,103],{"class":75},[69,895,106],{"class":83},[69,897,109],{"class":75},[69,899,522],{"class":83},[69,901,525],{"class":75},[69,903,528],{"class":321},[69,905,531],{"class":83},[69,907,908,910,912,914,917,919,922,925],{"class":71,"line":223},[69,909,750],{"class":83},[69,911,753],{"class":79},[69,913,84],{"class":83},[69,915,916],{"class":79},"double",[69,918,84],{"class":83},[69,920,921],{"class":321},"5",[69,923,924],{"class":83},"))  ",[69,926,927],{"class":124},"\u002F\u002F 10\n",[69,929,930],{"class":71,"line":534},[69,931,538],{"emptyLinePlaceholder":537},[69,933,934],{"class":71,"line":541},[69,935,936],{"class":124},"\u002F\u002F Способ 2: вызвать сразу (IIFE)\n",[69,938,939,942,944,946,948,950,952,954,956,958,960],{"class":71,"line":547},[69,940,941],{"class":83},"result ",[69,943,680],{"class":75},[69,945,505],{"class":75},[69,947,84],{"class":83},[69,949,88],{"class":87},[69,951,91],{"class":83},[69,953,94],{"class":87},[69,955,97],{"class":75},[69,957,100],{"class":83},[69,959,103],{"class":75},[69,961,628],{"class":83},[69,963,964,966,968,970],{"class":71,"line":590},[69,965,634],{"class":75},[69,967,112],{"class":83},[69,969,115],{"class":75},[69,971,972],{"class":83}," b\n",[69,974,975,978,981,983,986],{"class":71,"line":595},[69,976,977],{"class":83},"}(",[69,979,980],{"class":321},"3",[69,982,91],{"class":83},[69,984,985],{"class":321},"4",[69,987,988],{"class":83},")\n",[69,990,991,993,995,998],{"class":71,"line":601},[69,992,750],{"class":83},[69,994,753],{"class":79},[69,996,997],{"class":83},"(result) ",[69,999,1000],{"class":124},"\u002F\u002F 7 (функция вызвана сразу после определения)\n",[127,1002,1003,1004,1006,1007,1010],{},"Способ 1: ",[66,1005,916],{}," — функция. Способ 2: ",[66,1008,1009],{},"result"," — уже int (результат вызова).",[55,1012,1014],{"id":1013},"variadic-параметры","Variadic параметры",[60,1016,1018],{"className":62,"code":1017,"language":64,"meta":5,"style":5},"func sum(nums ...int) int {   \u002F\u002F nums — это []int\n    total := 0\n    for _, n := range nums {\n        total += n\n    }\n    return total\n}\n\nsum(1, 2, 3)       \u002F\u002F nums = []int{1, 2, 3}\nsum()               \u002F\u002F nums = []int{} (пустой slice)\n",[66,1019,1020,1044,1054,1070,1081,1086,1093,1097,1101,1126],{"__ignoreMap":5},[69,1021,1022,1024,1026,1028,1031,1034,1036,1038,1041],{"class":71,"line":72},[69,1023,76],{"class":75},[69,1025,265],{"class":79},[69,1027,84],{"class":83},[69,1029,1030],{"class":87},"nums",[69,1032,1033],{"class":75}," ...int",[69,1035,100],{"class":83},[69,1037,103],{"class":75},[69,1039,1040],{"class":83}," {   ",[69,1042,1043],{"class":124},"\u002F\u002F nums — это []int\n",[69,1045,1046,1049,1051],{"class":71,"line":121},[69,1047,1048],{"class":83},"    total ",[69,1050,680],{"class":75},[69,1052,1053],{"class":321}," 0\n",[69,1055,1056,1059,1062,1064,1067],{"class":71,"line":223},[69,1057,1058],{"class":75},"    for",[69,1060,1061],{"class":83}," _, n ",[69,1063,680],{"class":75},[69,1065,1066],{"class":75}," range",[69,1068,1069],{"class":83}," nums {\n",[69,1071,1072,1075,1078],{"class":71,"line":534},[69,1073,1074],{"class":83},"        total ",[69,1076,1077],{"class":75},"+=",[69,1079,1080],{"class":83}," n\n",[69,1082,1083],{"class":71,"line":541},[69,1084,1085],{"class":83},"    }\n",[69,1087,1088,1090],{"class":71,"line":547},[69,1089,634],{"class":75},[69,1091,1092],{"class":83}," total\n",[69,1094,1095],{"class":71,"line":590},[69,1096,663],{"class":83},[69,1098,1099],{"class":71,"line":595},[69,1100,538],{"emptyLinePlaceholder":537},[69,1102,1103,1106,1108,1111,1113,1116,1118,1120,1123],{"class":71,"line":601},[69,1104,1105],{"class":79},"sum",[69,1107,84],{"class":83},[69,1109,1110],{"class":321},"1",[69,1112,91],{"class":83},[69,1114,1115],{"class":321},"2",[69,1117,91],{"class":83},[69,1119,980],{"class":321},[69,1121,1122],{"class":83},")       ",[69,1124,1125],{"class":124},"\u002F\u002F nums = []int{1, 2, 3}\n",[69,1127,1128,1130,1133],{"class":71,"line":631},[69,1129,1105],{"class":79},[69,1131,1132],{"class":83},"()               ",[69,1134,1135],{"class":124},"\u002F\u002F nums = []int{} (пустой slice)\n",[127,1137,1138,1139,1141,1142,1144],{},"Variadic (",[66,1140,832],{},") — синтаксический сахар: внутри функции параметр является обычным ",[66,1143,836],{},".",[55,1146,1148],{"id":1147},"ограничения-variadic","Ограничения variadic",[60,1150,1152],{"className":62,"code":1151,"language":64,"meta":5,"style":5},"\u002F\u002F ❌ variadic не последний\nfunc bad(nums ...int, name string) {}\n\n\u002F\u002F ❌ два variadic\nfunc bad2(a ...int, b ...string) {}\n\n\u002F\u002F ✅ только один и последний\nfunc ok(prefix string, nums ...int) {}\n",[66,1153,1154,1159,1181,1185,1190,1214,1218,1223],{"__ignoreMap":5},[69,1155,1156],{"class":71,"line":72},[69,1157,1158],{"class":124},"\u002F\u002F ❌ variadic не последний\n",[69,1160,1161,1163,1166,1168,1170,1172,1174,1176,1178],{"class":71,"line":121},[69,1162,76],{"class":75},[69,1164,1165],{"class":79}," bad",[69,1167,84],{"class":83},[69,1169,1030],{"class":87},[69,1171,1033],{"class":75},[69,1173,91],{"class":83},[69,1175,150],{"class":87},[69,1177,153],{"class":75},[69,1179,1180],{"class":83},") {}\n",[69,1182,1183],{"class":71,"line":223},[69,1184,538],{"emptyLinePlaceholder":537},[69,1186,1187],{"class":71,"line":534},[69,1188,1189],{"class":124},"\u002F\u002F ❌ два variadic\n",[69,1191,1192,1194,1197,1199,1201,1203,1205,1207,1210,1212],{"class":71,"line":541},[69,1193,76],{"class":75},[69,1195,1196],{"class":79}," bad2",[69,1198,84],{"class":83},[69,1200,88],{"class":87},[69,1202,1033],{"class":75},[69,1204,91],{"class":83},[69,1206,94],{"class":87},[69,1208,1209],{"class":75}," ...",[69,1211,358],{"class":75},[69,1213,1180],{"class":83},[69,1215,1216],{"class":71,"line":547},[69,1217,538],{"emptyLinePlaceholder":537},[69,1219,1220],{"class":71,"line":590},[69,1221,1222],{"class":124},"\u002F\u002F ✅ только один и последний\n",[69,1224,1225,1227,1230,1232,1235,1237,1239,1241,1243],{"class":71,"line":595},[69,1226,76],{"class":75},[69,1228,1229],{"class":79}," ok",[69,1231,84],{"class":83},[69,1233,1234],{"class":87},"prefix",[69,1236,153],{"class":75},[69,1238,91],{"class":83},[69,1240,1030],{"class":87},[69,1242,1033],{"class":75},[69,1244,1180],{"class":83},[127,1246,1247],{},"Variadic может быть только один и только последним параметром.",[55,1249,1251],{"id":1250},"variadic-и-nil","Variadic и nil",[60,1253,1255],{"className":62,"code":1254,"language":64,"meta":5,"style":5},"func process(ptrs ...*int) {\n    fmt.Println(ptrs)  \u002F\u002F что выведет?\n}\n\nprocess(nil)      \u002F\u002F [\u003Cnil>]     — slice из одного nil-указателя\nprocess(nil...)   \u002F\u002F []          — распаковка nil slice = пустой slice\n\n\u002F\u002F Потому что variadic = slice:\n\u002F\u002F nil        → [](*int){nil}      один элемент\n\u002F\u002F nil...     → ([](*int))(nil)... → ничего\n",[66,1256,1257,1275,1288,1292,1296,1310,1326,1330,1335,1340],{"__ignoreMap":5},[69,1258,1259,1261,1264,1266,1269,1272],{"class":71,"line":72},[69,1260,76],{"class":75},[69,1262,1263],{"class":79}," process",[69,1265,84],{"class":83},[69,1267,1268],{"class":87},"ptrs",[69,1270,1271],{"class":75}," ...*int",[69,1273,1274],{"class":83},") {\n",[69,1276,1277,1280,1282,1285],{"class":71,"line":121},[69,1278,1279],{"class":83},"    fmt.",[69,1281,753],{"class":79},[69,1283,1284],{"class":83},"(ptrs)  ",[69,1286,1287],{"class":124},"\u002F\u002F что выведет?\n",[69,1289,1290],{"class":71,"line":223},[69,1291,663],{"class":83},[69,1293,1294],{"class":71,"line":534},[69,1295,538],{"emptyLinePlaceholder":537},[69,1297,1298,1300,1302,1304,1307],{"class":71,"line":541},[69,1299,196],{"class":79},[69,1301,84],{"class":83},[69,1303,442],{"class":321},[69,1305,1306],{"class":83},")      ",[69,1308,1309],{"class":124},"\u002F\u002F [\u003Cnil>]     — slice из одного nil-указателя\n",[69,1311,1312,1314,1316,1318,1320,1323],{"class":71,"line":547},[69,1313,196],{"class":79},[69,1315,84],{"class":83},[69,1317,442],{"class":321},[69,1319,159],{"class":75},[69,1321,1322],{"class":83},")   ",[69,1324,1325],{"class":124},"\u002F\u002F []          — распаковка nil slice = пустой slice\n",[69,1327,1328],{"class":71,"line":590},[69,1329,538],{"emptyLinePlaceholder":537},[69,1331,1332],{"class":71,"line":595},[69,1333,1334],{"class":124},"\u002F\u002F Потому что variadic = slice:\n",[69,1336,1337],{"class":71,"line":601},[69,1338,1339],{"class":124},"\u002F\u002F nil        → [](*int){nil}      один элемент\n",[69,1341,1342],{"class":71,"line":631},[69,1343,1344],{"class":124},"\u002F\u002F nil...     → ([](*int))(nil)... → ничего\n",[127,1346,1347,1350,1351,1354],{},[66,1348,1349],{},"process(nil)"," передаёт slice из одного nil-указателя. ",[66,1352,1353],{},"process(nil...)"," распаковывает nil slice — результат пустой slice.",[47,1356],{},[11,1358,1359,1366,1373,1386],{},[14,1360,1361,1362,1365],{},"именованные возвращаемые значения — по сути ",[18,1363,1364],{},"объявление переменных"," (zero value) в начале функции",[14,1367,1368,1369,1372],{},"используй когда повышают ",[18,1370,1371],{},"читаемость"," (два float64 → lat\u002Flon) или нужно модифицировать в defer",[14,1374,1375,1378,1379,1382,1383,1385],{},[18,1376,1377],{},"не мешай"," явный ",[66,1380,1381],{},"return lat, lon, err"," и голый ",[66,1384,109],{}," в одной функции",[14,1387,1388,1389,1392],{},"если хотя бы один параметр\u002Fрезультат проименован — остальные нужно именовать (или ",[66,1390,1391],{},"_",")",[47,1394],{},[50,1396,1398],{"id":1397},"именованные-возвращаемые-значения","Именованные возвращаемые значения",[55,1400,1402],{"id":1401},"когда-использовать","Когда использовать",[60,1404,1406],{"className":62,"code":1405,"language":64,"meta":5,"style":5},"\u002F\u002F ❌ Непонятно: где широта, где долгота?\nfunc GetLocation(addr string) (float64, float64, error)\n\n\u002F\u002F ✅ Понятно сразу\nfunc GetLocation(addr string) (latitude, longitude float64, err error)\n",[66,1407,1408,1413,1444,1448,1453],{"__ignoreMap":5},[69,1409,1410],{"class":71,"line":72},[69,1411,1412],{"class":124},"\u002F\u002F ❌ Непонятно: где широта, где долгота?\n",[69,1414,1415,1417,1420,1422,1425,1427,1430,1433,1435,1437,1439,1442],{"class":71,"line":121},[69,1416,76],{"class":75},[69,1418,1419],{"class":79}," GetLocation",[69,1421,84],{"class":83},[69,1423,1424],{"class":87},"addr",[69,1426,153],{"class":75},[69,1428,1429],{"class":83},") (",[69,1431,1432],{"class":75},"float64",[69,1434,91],{"class":83},[69,1436,1432],{"class":75},[69,1438,91],{"class":83},[69,1440,1441],{"class":75},"error",[69,1443,988],{"class":83},[69,1445,1446],{"class":71,"line":223},[69,1447,538],{"emptyLinePlaceholder":537},[69,1449,1450],{"class":71,"line":534},[69,1451,1452],{"class":124},"\u002F\u002F ✅ Понятно сразу\n",[69,1454,1455,1457,1459,1461,1463,1465,1467,1470,1472,1475,1478,1480,1483,1486],{"class":71,"line":541},[69,1456,76],{"class":75},[69,1458,1419],{"class":79},[69,1460,84],{"class":83},[69,1462,1424],{"class":87},[69,1464,153],{"class":75},[69,1466,1429],{"class":83},[69,1468,1469],{"class":87},"latitude",[69,1471,91],{"class":83},[69,1473,1474],{"class":87},"longitude",[69,1476,1477],{"class":75}," float64",[69,1479,91],{"class":83},[69,1481,1482],{"class":87},"err",[69,1484,1485],{"class":75}," error",[69,1487,988],{"class":83},[127,1489,1490,1491,1494,1495,1497,1498,1500],{},"Рекомендация Go community: используй именованные возвращаемые, когда это ",[18,1492,1493],{},"повышает читаемость",". Для одного ",[66,1496,103],{}," или ",[66,1499,1441],{}," — обычно не нужно.",[55,1502,1504],{"id":1503},"это-объявление-переменных","Это объявление переменных",[60,1506,1508],{"className":62,"code":1507,"language":64,"meta":5,"style":5},"func divide(a, b float64) (result float64, err error) {\n    \u002F\u002F result = 0.0 (zero value float64)\n    \u002F\u002F err = nil    (zero value error)\n    if b == 0 {\n        err = errors.New(\"division by zero\")\n        return  \u002F\u002F голый return → вернёт result=0, err=ошибка\n    }\n    result = a \u002F b\n    return  \u002F\u002F голый return → вернёт result, err=nil\n}\n",[66,1509,1510,1541,1546,1551,1566,1586,1594,1598,1612,1619],{"__ignoreMap":5},[69,1511,1512,1514,1517,1519,1521,1523,1525,1527,1529,1531,1533,1535,1537,1539],{"class":71,"line":72},[69,1513,76],{"class":75},[69,1515,1516],{"class":79}," divide",[69,1518,84],{"class":83},[69,1520,88],{"class":87},[69,1522,91],{"class":83},[69,1524,94],{"class":87},[69,1526,1477],{"class":75},[69,1528,1429],{"class":83},[69,1530,1009],{"class":87},[69,1532,1477],{"class":75},[69,1534,91],{"class":83},[69,1536,1482],{"class":87},[69,1538,1485],{"class":75},[69,1540,1274],{"class":83},[69,1542,1543],{"class":71,"line":121},[69,1544,1545],{"class":124},"    \u002F\u002F result = 0.0 (zero value float64)\n",[69,1547,1548],{"class":71,"line":223},[69,1549,1550],{"class":124},"    \u002F\u002F err = nil    (zero value error)\n",[69,1552,1553,1556,1559,1561,1564],{"class":71,"line":534},[69,1554,1555],{"class":75},"    if",[69,1557,1558],{"class":83}," b ",[69,1560,759],{"class":75},[69,1562,1563],{"class":321}," 0",[69,1565,628],{"class":83},[69,1567,1568,1571,1573,1576,1579,1581,1584],{"class":71,"line":541},[69,1569,1570],{"class":83},"        err ",[69,1572,328],{"class":75},[69,1574,1575],{"class":83}," errors.",[69,1577,1578],{"class":79},"New",[69,1580,84],{"class":83},[69,1582,1583],{"class":175},"\"division by zero\"",[69,1585,988],{"class":83},[69,1587,1588,1591],{"class":71,"line":547},[69,1589,1590],{"class":75},"        return",[69,1592,1593],{"class":124},"  \u002F\u002F голый return → вернёт result=0, err=ошибка\n",[69,1595,1596],{"class":71,"line":590},[69,1597,1085],{"class":83},[69,1599,1600,1603,1605,1607,1610],{"class":71,"line":595},[69,1601,1602],{"class":83},"    result ",[69,1604,328],{"class":75},[69,1606,112],{"class":83},[69,1608,1609],{"class":75},"\u002F",[69,1611,972],{"class":83},[69,1613,1614,1616],{"class":71,"line":601},[69,1615,634],{"class":75},[69,1617,1618],{"class":124},"  \u002F\u002F голый return → вернёт result, err=nil\n",[69,1620,1621],{"class":71,"line":631},[69,1622,663],{"class":83},[127,1624,1625,1626,91,1629,1632,1633,1635],{},"Именованные переменные инициализируются zero value автоматически: ",[66,1627,1628],{},"result = 0.0",[66,1630,1631],{},"err = nil",". Голый ",[66,1634,109],{}," возвращает текущие значения этих переменных.",[55,1637,1639],{"id":1638},"не-мешай-явный-и-голый-return","Не мешай явный и голый return",[60,1641,1643],{"className":62,"code":1642,"language":64,"meta":5,"style":5},"\u002F\u002F ❌ Плохо: путаница\nfunc process(addr string) (lat, lon float64, err error) {\n    if addr == \"\" {\n        return  \u002F\u002F голый — неявно возвращает lat, lon, err\n    }\n    \u002F\u002F ...\n    return lat, lon, err  \u002F\u002F явный — а тут другой стиль\n}\n\n\u002F\u002F ✅ Хорошо: один стиль везде\nfunc process(addr string) (lat, lon float64, err error) {\n    if addr == \"\" {\n        return 0, 0, errors.New(\"empty\")  \u002F\u002F явный\n    }\n    return lat, lon, nil  \u002F\u002F явный\n}\n",[66,1644,1645,1650,1682,1696,1703,1707,1712,1722,1726,1730,1735,1765,1778,1805,1810,1823],{"__ignoreMap":5},[69,1646,1647],{"class":71,"line":72},[69,1648,1649],{"class":124},"\u002F\u002F ❌ Плохо: путаница\n",[69,1651,1652,1654,1656,1658,1660,1662,1664,1667,1669,1672,1674,1676,1678,1680],{"class":71,"line":121},[69,1653,76],{"class":75},[69,1655,1263],{"class":79},[69,1657,84],{"class":83},[69,1659,1424],{"class":87},[69,1661,153],{"class":75},[69,1663,1429],{"class":83},[69,1665,1666],{"class":87},"lat",[69,1668,91],{"class":83},[69,1670,1671],{"class":87},"lon",[69,1673,1477],{"class":75},[69,1675,91],{"class":83},[69,1677,1482],{"class":87},[69,1679,1485],{"class":75},[69,1681,1274],{"class":83},[69,1683,1684,1686,1689,1691,1694],{"class":71,"line":223},[69,1685,1555],{"class":75},[69,1687,1688],{"class":83}," addr ",[69,1690,759],{"class":75},[69,1692,1693],{"class":175}," \"\"",[69,1695,628],{"class":83},[69,1697,1698,1700],{"class":71,"line":534},[69,1699,1590],{"class":75},[69,1701,1702],{"class":124},"  \u002F\u002F голый — неявно возвращает lat, lon, err\n",[69,1704,1705],{"class":71,"line":541},[69,1706,1085],{"class":83},[69,1708,1709],{"class":71,"line":547},[69,1710,1711],{"class":124},"    \u002F\u002F ...\n",[69,1713,1714,1716,1719],{"class":71,"line":590},[69,1715,634],{"class":75},[69,1717,1718],{"class":83}," lat, lon, err  ",[69,1720,1721],{"class":124},"\u002F\u002F явный — а тут другой стиль\n",[69,1723,1724],{"class":71,"line":595},[69,1725,663],{"class":83},[69,1727,1728],{"class":71,"line":601},[69,1729,538],{"emptyLinePlaceholder":537},[69,1731,1732],{"class":71,"line":631},[69,1733,1734],{"class":124},"\u002F\u002F ✅ Хорошо: один стиль везде\n",[69,1736,1737,1739,1741,1743,1745,1747,1749,1751,1753,1755,1757,1759,1761,1763],{"class":71,"line":660},[69,1738,76],{"class":75},[69,1740,1263],{"class":79},[69,1742,84],{"class":83},[69,1744,1424],{"class":87},[69,1746,153],{"class":75},[69,1748,1429],{"class":83},[69,1750,1666],{"class":87},[69,1752,91],{"class":83},[69,1754,1671],{"class":87},[69,1756,1477],{"class":75},[69,1758,91],{"class":83},[69,1760,1482],{"class":87},[69,1762,1485],{"class":75},[69,1764,1274],{"class":83},[69,1766,1768,1770,1772,1774,1776],{"class":71,"line":1767},12,[69,1769,1555],{"class":75},[69,1771,1688],{"class":83},[69,1773,759],{"class":75},[69,1775,1693],{"class":175},[69,1777,628],{"class":83},[69,1779,1781,1783,1785,1787,1789,1792,1794,1796,1799,1802],{"class":71,"line":1780},13,[69,1782,1590],{"class":75},[69,1784,1563],{"class":321},[69,1786,91],{"class":83},[69,1788,322],{"class":321},[69,1790,1791],{"class":83},", errors.",[69,1793,1578],{"class":79},[69,1795,84],{"class":83},[69,1797,1798],{"class":175},"\"empty\"",[69,1800,1801],{"class":83},")  ",[69,1803,1804],{"class":124},"\u002F\u002F явный\n",[69,1806,1808],{"class":71,"line":1807},14,[69,1809,1085],{"class":83},[69,1811,1813,1815,1818,1820],{"class":71,"line":1812},15,[69,1814,634],{"class":75},[69,1816,1817],{"class":83}," lat, lon, ",[69,1819,442],{"class":321},[69,1821,1822],{"class":124},"  \u002F\u002F явный\n",[69,1824,1826],{"class":71,"line":1825},16,[69,1827,663],{"class":83},[55,1829,1831],{"id":1830},"пропуск-имён-параметров","Пропуск имён параметров",[60,1833,1835],{"className":62,"code":1834,"language":64,"meta":5,"style":5},"\u002F\u002F Все пропущены — ок\nfunc Write([]byte) (int, error)\n\n\u002F\u002F Если один именован — остальные нужно именовать или _\nfunc Write(_ []byte) (n int, err error)\n\u002F\u002F ✅ несколько _ допустимо\n",[66,1836,1837,1842,1865,1869,1874,1902],{"__ignoreMap":5},[69,1838,1839],{"class":71,"line":72},[69,1840,1841],{"class":124},"\u002F\u002F Все пропущены — ок\n",[69,1843,1844,1846,1849,1852,1855,1857,1859,1861,1863],{"class":71,"line":121},[69,1845,76],{"class":75},[69,1847,1848],{"class":79}," Write",[69,1850,1851],{"class":83},"([]",[69,1853,1854],{"class":75},"byte",[69,1856,1429],{"class":83},[69,1858,103],{"class":75},[69,1860,91],{"class":83},[69,1862,1441],{"class":75},[69,1864,988],{"class":83},[69,1866,1867],{"class":71,"line":223},[69,1868,538],{"emptyLinePlaceholder":537},[69,1870,1871],{"class":71,"line":534},[69,1872,1873],{"class":124},"\u002F\u002F Если один именован — остальные нужно именовать или _\n",[69,1875,1876,1878,1880,1882,1884,1886,1888,1890,1892,1894,1896,1898,1900],{"class":71,"line":541},[69,1877,76],{"class":75},[69,1879,1848],{"class":79},[69,1881,84],{"class":83},[69,1883,1391],{"class":87},[69,1885,313],{"class":83},[69,1887,1854],{"class":75},[69,1889,1429],{"class":83},[69,1891,611],{"class":87},[69,1893,97],{"class":75},[69,1895,91],{"class":83},[69,1897,1482],{"class":87},[69,1899,1485],{"class":75},[69,1901,988],{"class":83},[69,1903,1904],{"class":71,"line":547},[69,1905,1906],{"class":124},"\u002F\u002F ✅ несколько _ допустимо\n",[127,1908,1909,1910,1913,1914,1144],{},"Правило: ",[18,1911,1912],{},"всё или ничего",". Если хоть одно имя задано — остальные обязаны иметь имя или ",[66,1915,1391],{},[47,1917],{},[11,1919,1920,1927,1938,1941],{},[14,1921,1922,1923,1926],{},"замыкание — функция, которая ",[18,1924,1925],{},"ссылается на переменные"," из области видимости родительской функции",[14,1928,1929,1930,1933,1934,1937],{},"замкнутая переменная ",[18,1931,1932],{},"живёт дольше"," родительской функции → аллокация в ",[18,1935,1936],{},"heap"," (escape analysis)",[14,1939,1940],{},"генератор\u002Fсчётчик — классический пример: функция «помнит» состояние между вызовами",[14,1942,1943,1944,1947,1948],{},"self-referencing anonymous: сначала ",[66,1945,1946],{},"var f func(...)",", потом ",[66,1949,1950],{},"f = func(...) { ... f(...) ... }",[47,1952],{},[50,1954,1956],{"id":1955},"замыкания","Замыкания",[55,1958,1960],{"id":1959},"генератор-счётчик","Генератор-счётчик",[60,1962,1964],{"className":62,"code":1963,"language":64,"meta":5,"style":5},"func generator(start int) func() int {\n    number := start               \u002F\u002F переменная родительской функции\n    return func() int {           \u002F\u002F замыкание — захватывает number\n        r := number\n        number++                  \u002F\u002F модифицирует НЕ локальную переменную\n        return r\n    }\n}\n\ngen := generator(100)\ngen()  \u002F\u002F 100\ngen()  \u002F\u002F 101\ngen()  \u002F\u002F 102\n\u002F\u002F number живёт в heap — не уничтожен с завершением generator()\n",[66,1965,1966,1991,2004,2020,2030,2040,2047,2051,2055,2059,2075,2086,2095,2104],{"__ignoreMap":5},[69,1967,1968,1970,1973,1975,1978,1980,1982,1984,1987,1989],{"class":71,"line":72},[69,1969,76],{"class":75},[69,1971,1972],{"class":79}," generator",[69,1974,84],{"class":83},[69,1976,1977],{"class":87},"start",[69,1979,97],{"class":75},[69,1981,100],{"class":83},[69,1983,76],{"class":75},[69,1985,1986],{"class":83},"() ",[69,1988,103],{"class":75},[69,1990,628],{"class":83},[69,1992,1993,1996,1998,2001],{"class":71,"line":121},[69,1994,1995],{"class":83},"    number ",[69,1997,680],{"class":75},[69,1999,2000],{"class":83}," start               ",[69,2002,2003],{"class":124},"\u002F\u002F переменная родительской функции\n",[69,2005,2006,2008,2010,2012,2014,2017],{"class":71,"line":223},[69,2007,634],{"class":75},[69,2009,505],{"class":75},[69,2011,1986],{"class":83},[69,2013,103],{"class":75},[69,2015,2016],{"class":83}," {           ",[69,2018,2019],{"class":124},"\u002F\u002F замыкание — захватывает number\n",[69,2021,2022,2025,2027],{"class":71,"line":534},[69,2023,2024],{"class":83},"        r ",[69,2026,680],{"class":75},[69,2028,2029],{"class":83}," number\n",[69,2031,2032,2035,2037],{"class":71,"line":541},[69,2033,2034],{"class":83},"        number",[69,2036,401],{"class":75},[69,2038,2039],{"class":124},"                  \u002F\u002F модифицирует НЕ локальную переменную\n",[69,2041,2042,2044],{"class":71,"line":547},[69,2043,1590],{"class":75},[69,2045,2046],{"class":83}," r\n",[69,2048,2049],{"class":71,"line":590},[69,2050,1085],{"class":83},[69,2052,2053],{"class":71,"line":595},[69,2054,663],{"class":83},[69,2056,2057],{"class":71,"line":601},[69,2058,538],{"emptyLinePlaceholder":537},[69,2060,2061,2064,2066,2068,2070,2073],{"class":71,"line":631},[69,2062,2063],{"class":83},"gen ",[69,2065,680],{"class":75},[69,2067,1972],{"class":79},[69,2069,84],{"class":83},[69,2071,2072],{"class":321},"100",[69,2074,988],{"class":83},[69,2076,2077,2080,2083],{"class":71,"line":660},[69,2078,2079],{"class":79},"gen",[69,2081,2082],{"class":83},"()  ",[69,2084,2085],{"class":124},"\u002F\u002F 100\n",[69,2087,2088,2090,2092],{"class":71,"line":1767},[69,2089,2079],{"class":79},[69,2091,2082],{"class":83},[69,2093,2094],{"class":124},"\u002F\u002F 101\n",[69,2096,2097,2099,2101],{"class":71,"line":1780},[69,2098,2079],{"class":79},[69,2100,2082],{"class":83},[69,2102,2103],{"class":124},"\u002F\u002F 102\n",[69,2105,2106],{"class":71,"line":1807},[69,2107,2108],{"class":124},"\u002F\u002F number живёт в heap — не уничтожен с завершением generator()\n",[127,2110,2111,2114,2115,2118,2119,2122,2123,2125],{},[18,2112,2113],{},"Почему number не умирает?"," Родительская функция ",[66,2116,2117],{},"generator"," завершилась, но возвращённая функция ссылается на ",[66,2120,2121],{},"number",". Escape analysis → ",[66,2124,2121],{}," аллоцируется в heap.",[55,2127,2129],{"id":2128},"как-это-выглядит-в-памяти","Как это выглядит в памяти",[60,2131,2136],{"className":2132,"code":2134,"language":2135},[2133],"language-text","gen (переменная на стеке main)\n  │\n  ▼\nfunc() int ──ссылка──▶ number: 102  (heap)\n","text",[66,2137,2134],{"__ignoreMap":5},[127,2139,2140,2141,2144,2145,433,2148,2150],{},"Каждый вызов ",[66,2142,2143],{},"generator()"," создаёт ",[18,2146,2147],{},"свой",[66,2149,2121],{}," в heap:",[60,2152,2154],{"className":62,"code":2153,"language":64,"meta":5,"style":5},"gen1 := generator(0)\ngen2 := generator(100)\ngen1()  \u002F\u002F 0   (свой number)\ngen2()  \u002F\u002F 100 (свой number)\ngen1()  \u002F\u002F 1\ngen2()  \u002F\u002F 101\n",[66,2155,2156,2171,2186,2196,2206,2215],{"__ignoreMap":5},[69,2157,2158,2161,2163,2165,2167,2169],{"class":71,"line":72},[69,2159,2160],{"class":83},"gen1 ",[69,2162,680],{"class":75},[69,2164,1972],{"class":79},[69,2166,84],{"class":83},[69,2168,322],{"class":321},[69,2170,988],{"class":83},[69,2172,2173,2176,2178,2180,2182,2184],{"class":71,"line":121},[69,2174,2175],{"class":83},"gen2 ",[69,2177,680],{"class":75},[69,2179,1972],{"class":79},[69,2181,84],{"class":83},[69,2183,2072],{"class":321},[69,2185,988],{"class":83},[69,2187,2188,2191,2193],{"class":71,"line":223},[69,2189,2190],{"class":79},"gen1",[69,2192,2082],{"class":83},[69,2194,2195],{"class":124},"\u002F\u002F 0   (свой number)\n",[69,2197,2198,2201,2203],{"class":71,"line":534},[69,2199,2200],{"class":79},"gen2",[69,2202,2082],{"class":83},[69,2204,2205],{"class":124},"\u002F\u002F 100 (свой number)\n",[69,2207,2208,2210,2212],{"class":71,"line":541},[69,2209,2190],{"class":79},[69,2211,2082],{"class":83},[69,2213,2214],{"class":124},"\u002F\u002F 1\n",[69,2216,2217,2219,2221],{"class":71,"line":547},[69,2218,2200],{"class":79},[69,2220,2082],{"class":83},[69,2222,2094],{"class":124},[55,2224,2226],{"id":2225},"self-referencing-анонимная-функция","Self-referencing анонимная функция",[60,2228,2230],{"className":62,"code":2229,"language":64,"meta":5,"style":5},"\u002F\u002F ❌ Нельзя — fib ещё не существует\n\u002F\u002F fib := func(n int) int { return fib(n-1) + fib(n-2) }\n\n\u002F\u002F ✅ Сначала объявить переменную, потом присвоить\nvar fib func(n int) int\nfib = func(n int) int {\n    if n \u003C= 1 { return 1 }\n    return fib(n-1) + fib(n-2)  \u002F\u002F fib уже объявлен\n}\n",[66,2231,2232,2237,2242,2246,2251,2270,2291,2311,2343],{"__ignoreMap":5},[69,2233,2234],{"class":71,"line":72},[69,2235,2236],{"class":124},"\u002F\u002F ❌ Нельзя — fib ещё не существует\n",[69,2238,2239],{"class":71,"line":121},[69,2240,2241],{"class":124},"\u002F\u002F fib := func(n int) int { return fib(n-1) + fib(n-2) }\n",[69,2243,2244],{"class":71,"line":223},[69,2245,538],{"emptyLinePlaceholder":537},[69,2247,2248],{"class":71,"line":534},[69,2249,2250],{"class":124},"\u002F\u002F ✅ Сначала объявить переменную, потом присвоить\n",[69,2252,2253,2255,2258,2260,2262,2264,2266,2268],{"class":71,"line":541},[69,2254,481],{"class":75},[69,2256,2257],{"class":83}," fib ",[69,2259,76],{"class":75},[69,2261,84],{"class":83},[69,2263,611],{"class":87},[69,2265,97],{"class":75},[69,2267,100],{"class":83},[69,2269,495],{"class":75},[69,2271,2272,2275,2277,2279,2281,2283,2285,2287,2289],{"class":71,"line":547},[69,2273,2274],{"class":83},"fib ",[69,2276,328],{"class":75},[69,2278,505],{"class":75},[69,2280,84],{"class":83},[69,2282,611],{"class":87},[69,2284,97],{"class":75},[69,2286,100],{"class":83},[69,2288,103],{"class":75},[69,2290,628],{"class":83},[69,2292,2293,2295,2298,2301,2303,2305,2307,2309],{"class":71,"line":590},[69,2294,1555],{"class":75},[69,2296,2297],{"class":83}," n ",[69,2299,2300],{"class":75},"\u003C=",[69,2302,376],{"class":321},[69,2304,106],{"class":83},[69,2306,109],{"class":75},[69,2308,376],{"class":321},[69,2310,531],{"class":83},[69,2312,2313,2315,2318,2321,2324,2326,2328,2330,2332,2334,2336,2338,2340],{"class":71,"line":595},[69,2314,634],{"class":75},[69,2316,2317],{"class":79}," fib",[69,2319,2320],{"class":83},"(n",[69,2322,2323],{"class":75},"-",[69,2325,1110],{"class":321},[69,2327,100],{"class":83},[69,2329,115],{"class":75},[69,2331,2317],{"class":79},[69,2333,2320],{"class":83},[69,2335,2323],{"class":75},[69,2337,1115],{"class":321},[69,2339,1801],{"class":83},[69,2341,2342],{"class":124},"\u002F\u002F fib уже объявлен\n",[69,2344,2345],{"class":71,"line":601},[69,2346,663],{"class":83},[127,2348,2349,2356,2357,2359,2360,2363,2364,2367],{},[18,2350,2351,2352,2355],{},"Почему нельзя ",[66,2353,2354],{},"fib := func(...) { fib(...) }","?"," В момент правой части ",[66,2358,680],{}," переменная ",[66,2361,2362],{},"fib"," ещё не объявлена — компилятор вернёт ошибку. Нужно сначала ",[66,2365,2366],{},"var fib func(...)",", чтобы имя было в scope.",[55,2369,2371],{"id":2370},"ловушка-замыкание-в-цикле","Ловушка: замыкание в цикле",[60,2373,2376],{"className":62,"code":2374,"language":64,"meta":2375,"style":5},"\u002F\u002F ⚠️ Ловушка остаётся, если переменная объявлена снаружи цикла\nvar i int\nfor i = 0; i \u003C 5; i++ {\n    go func() { fmt.Println(i) }()  \u002F\u002F скорее всего напечатает 5 5 5 5 5\n}\n\n\u002F\u002F ✅ Fix: передать как аргумент (копия)\nfor i := 0; i \u003C 5; i++ {\n    go func(n int) { fmt.Println(n) }(i)  \u002F\u002F копия i\n}\n","static",[66,2377,2378,2383,2392,2419,2437,2441,2445,2450,2472,2495],{"__ignoreMap":5},[69,2379,2380],{"class":71,"line":72},[69,2381,2382],{"class":124},"\u002F\u002F ⚠️ Ловушка остаётся, если переменная объявлена снаружи цикла\n",[69,2384,2385,2387,2390],{"class":71,"line":121},[69,2386,481],{"class":75},[69,2388,2389],{"class":83}," i ",[69,2391,495],{"class":75},[69,2393,2394,2397,2399,2401,2403,2406,2409,2412,2415,2417],{"class":71,"line":223},[69,2395,2396],{"class":75},"for",[69,2398,2389],{"class":83},[69,2400,328],{"class":75},[69,2402,1563],{"class":321},[69,2404,2405],{"class":83},"; i ",[69,2407,2408],{"class":75},"\u003C",[69,2410,2411],{"class":321}," 5",[69,2413,2414],{"class":83},"; i",[69,2416,401],{"class":75},[69,2418,628],{"class":83},[69,2420,2421,2424,2426,2429,2431,2434],{"class":71,"line":534},[69,2422,2423],{"class":75},"    go",[69,2425,505],{"class":75},[69,2427,2428],{"class":83},"() { fmt.",[69,2430,753],{"class":79},[69,2432,2433],{"class":83},"(i) }()  ",[69,2435,2436],{"class":124},"\u002F\u002F скорее всего напечатает 5 5 5 5 5\n",[69,2438,2439],{"class":71,"line":541},[69,2440,663],{"class":83},[69,2442,2443],{"class":71,"line":547},[69,2444,538],{"emptyLinePlaceholder":537},[69,2446,2447],{"class":71,"line":590},[69,2448,2449],{"class":124},"\u002F\u002F ✅ Fix: передать как аргумент (копия)\n",[69,2451,2452,2454,2456,2458,2460,2462,2464,2466,2468,2470],{"class":71,"line":595},[69,2453,2396],{"class":75},[69,2455,2389],{"class":83},[69,2457,680],{"class":75},[69,2459,1563],{"class":321},[69,2461,2405],{"class":83},[69,2463,2408],{"class":75},[69,2465,2411],{"class":321},[69,2467,2414],{"class":83},[69,2469,401],{"class":75},[69,2471,628],{"class":83},[69,2473,2474,2476,2478,2480,2482,2484,2487,2489,2492],{"class":71,"line":601},[69,2475,2423],{"class":75},[69,2477,505],{"class":75},[69,2479,84],{"class":83},[69,2481,611],{"class":87},[69,2483,97],{"class":75},[69,2485,2486],{"class":83},") { fmt.",[69,2488,753],{"class":79},[69,2490,2491],{"class":83},"(n) }(i)  ",[69,2493,2494],{"class":124},"\u002F\u002F копия i\n",[69,2496,2497],{"class":71,"line":631},[69,2498,663],{"class":83},[127,2500,2501,2504,2505,2508,2509,2512,2513,2515],{},[18,2502,2503],{},"Суть ловушки:"," анонимные функции замыкают переменную, а не снимок значения. Если переменная цикла объявлена снаружи, все горутины смотрят на одну и ту же ",[66,2506,2507],{},"i","; к моменту выполнения она уже равна 5. В Go 1.22+ переменные, объявленные прямо в ",[66,2510,2511],{},"for i := ...",", создаются заново на каждой итерации, поэтому старый пример с ",[66,2514,2511],{}," больше не демонстрирует эту ошибку.",[47,2517],{},[11,2519,2520,2526,2535,2538],{},[14,2521,2522,2525],{},[18,2523,2524],{},"функция высшего порядка"," (ФВП) — принимает функцию как аргумент и\u002Fили возвращает функцию",[14,2527,2528,2531,2532],{},[18,2529,2530],{},"предикат"," — функция, возвращающая ",[66,2533,2534],{},"bool",[14,2536,2537],{},"предикаты удобны для обобщения: одна сортировка + предикат → asc\u002Fdesc",[14,2539,2540],{},"ФВП — основа для forEach, map, filter, reduce в Go",[47,2542],{},[50,2544,2546],{"id":2545},"функции-высшего-порядка","Функции высшего порядка",[55,2548,2550],{"id":2549},"предикат-обобщение-поведения","Предикат — обобщение поведения",[60,2552,2554],{"className":62,"code":2553,"language":64,"meta":5,"style":5},"\u002F\u002F Сортировка вставками — один код, разное поведение через предикат\nfunc insertionSort(arr []int, less func(a, b int) bool) {\n    for i := 1; i \u003C len(arr); i++ {\n        key := arr[i]\n        j := i - 1\n        for j >= 0 && less(key, arr[j]) {\n            arr[j+1] = arr[j]\n            j--\n        }\n        arr[j+1] = key\n    }\n}\n\n\u002F\u002F По возрастанию\ninsertionSort(data, func(a, b int) bool { return a \u003C b })\n\n\u002F\u002F По убыванию — тот же код!\ninsertionSort(data, func(a, b int) bool { return a > b })\n",[66,2555,2556,2561,2600,2624,2634,2648,2670,2686,2694,2699,2715,2719,2723,2727,2732,2767,2771,2777],{"__ignoreMap":5},[69,2557,2558],{"class":71,"line":72},[69,2559,2560],{"class":124},"\u002F\u002F Сортировка вставками — один код, разное поведение через предикат\n",[69,2562,2563,2565,2568,2570,2573,2575,2577,2579,2582,2584,2586,2588,2590,2592,2594,2596,2598],{"class":71,"line":121},[69,2564,76],{"class":75},[69,2566,2567],{"class":79}," insertionSort",[69,2569,84],{"class":83},[69,2571,2572],{"class":87},"arr",[69,2574,313],{"class":83},[69,2576,103],{"class":75},[69,2578,91],{"class":83},[69,2580,2581],{"class":87},"less",[69,2583,505],{"class":75},[69,2585,84],{"class":83},[69,2587,88],{"class":87},[69,2589,91],{"class":83},[69,2591,94],{"class":87},[69,2593,97],{"class":75},[69,2595,100],{"class":83},[69,2597,2534],{"class":75},[69,2599,1274],{"class":83},[69,2601,2602,2604,2606,2608,2610,2612,2614,2617,2620,2622],{"class":71,"line":223},[69,2603,1058],{"class":75},[69,2605,2389],{"class":83},[69,2607,680],{"class":75},[69,2609,376],{"class":321},[69,2611,2405],{"class":83},[69,2613,2408],{"class":75},[69,2615,2616],{"class":79}," len",[69,2618,2619],{"class":83},"(arr); i",[69,2621,401],{"class":75},[69,2623,628],{"class":83},[69,2625,2626,2629,2631],{"class":71,"line":534},[69,2627,2628],{"class":83},"        key ",[69,2630,680],{"class":75},[69,2632,2633],{"class":83}," arr[i]\n",[69,2635,2636,2639,2641,2643,2645],{"class":71,"line":541},[69,2637,2638],{"class":83},"        j ",[69,2640,680],{"class":75},[69,2642,2389],{"class":83},[69,2644,2323],{"class":75},[69,2646,2647],{"class":321}," 1\n",[69,2649,2650,2653,2656,2659,2661,2664,2667],{"class":71,"line":547},[69,2651,2652],{"class":75},"        for",[69,2654,2655],{"class":83}," j ",[69,2657,2658],{"class":75},">=",[69,2660,1563],{"class":321},[69,2662,2663],{"class":75}," &&",[69,2665,2666],{"class":79}," less",[69,2668,2669],{"class":83},"(key, arr[j]) {\n",[69,2671,2672,2675,2677,2679,2681,2683],{"class":71,"line":590},[69,2673,2674],{"class":83},"            arr[j",[69,2676,115],{"class":75},[69,2678,1110],{"class":321},[69,2680,325],{"class":83},[69,2682,328],{"class":75},[69,2684,2685],{"class":83}," arr[j]\n",[69,2687,2688,2691],{"class":71,"line":595},[69,2689,2690],{"class":83},"            j",[69,2692,2693],{"class":75},"--\n",[69,2695,2696],{"class":71,"line":601},[69,2697,2698],{"class":83},"        }\n",[69,2700,2701,2704,2706,2708,2710,2712],{"class":71,"line":631},[69,2702,2703],{"class":83},"        arr[j",[69,2705,115],{"class":75},[69,2707,1110],{"class":321},[69,2709,325],{"class":83},[69,2711,328],{"class":75},[69,2713,2714],{"class":83}," key\n",[69,2716,2717],{"class":71,"line":660},[69,2718,1085],{"class":83},[69,2720,2721],{"class":71,"line":1767},[69,2722,663],{"class":83},[69,2724,2725],{"class":71,"line":1780},[69,2726,538],{"emptyLinePlaceholder":537},[69,2728,2729],{"class":71,"line":1807},[69,2730,2731],{"class":124},"\u002F\u002F По возрастанию\n",[69,2733,2734,2737,2740,2742,2744,2746,2748,2750,2752,2754,2756,2758,2760,2762,2764],{"class":71,"line":1812},[69,2735,2736],{"class":79},"insertionSort",[69,2738,2739],{"class":83},"(data, ",[69,2741,76],{"class":75},[69,2743,84],{"class":83},[69,2745,88],{"class":87},[69,2747,91],{"class":83},[69,2749,94],{"class":87},[69,2751,97],{"class":75},[69,2753,100],{"class":83},[69,2755,2534],{"class":75},[69,2757,106],{"class":83},[69,2759,109],{"class":75},[69,2761,112],{"class":83},[69,2763,2408],{"class":75},[69,2765,2766],{"class":83}," b })\n",[69,2768,2769],{"class":71,"line":1825},[69,2770,538],{"emptyLinePlaceholder":537},[69,2772,2774],{"class":71,"line":2773},17,[69,2775,2776],{"class":124},"\u002F\u002F По убыванию — тот же код!\n",[69,2778,2780,2782,2784,2786,2788,2790,2792,2794,2796,2798,2800,2802,2804,2806,2809],{"class":71,"line":2779},18,[69,2781,2736],{"class":79},[69,2783,2739],{"class":83},[69,2785,76],{"class":75},[69,2787,84],{"class":83},[69,2789,88],{"class":87},[69,2791,91],{"class":83},[69,2793,94],{"class":87},[69,2795,97],{"class":75},[69,2797,100],{"class":83},[69,2799,2534],{"class":75},[69,2801,106],{"class":83},[69,2803,109],{"class":75},[69,2805,112],{"class":83},[69,2807,2808],{"class":75},">",[69,2810,2766],{"class":83},[127,2812,2813],{},"Без предиката пришлось бы писать две функции сортировки.",[55,2815,2817],{"id":2816},"функция-высшего-порядка-foreach","Функция высшего порядка — forEach",[60,2819,2821],{"className":62,"code":2820,"language":64,"meta":5,"style":5},"func forEach(arr []int, fn func(int) int) []int {\n    result := make([]int, len(arr))  \u002F\u002F копия — чистая функция\n    for i, v := range arr {\n        result[i] = fn(v)\n    }\n    return result\n}\n\nsquares := forEach([]int{1, 2, 3, 4}, func(x int) int {\n    return x * x\n})\n\u002F\u002F [1, 4, 9, 16]\n",[66,2822,2823,2860,2884,2898,2911,2915,2922,2926,2930,2977,2988,2993],{"__ignoreMap":5},[69,2824,2825,2827,2830,2832,2834,2836,2838,2840,2843,2845,2847,2849,2851,2853,2856,2858],{"class":71,"line":72},[69,2826,76],{"class":75},[69,2828,2829],{"class":79}," forEach",[69,2831,84],{"class":83},[69,2833,2572],{"class":87},[69,2835,313],{"class":83},[69,2837,103],{"class":75},[69,2839,91],{"class":83},[69,2841,2842],{"class":87},"fn",[69,2844,505],{"class":75},[69,2846,84],{"class":83},[69,2848,103],{"class":75},[69,2850,100],{"class":83},[69,2852,103],{"class":75},[69,2854,2855],{"class":83},") []",[69,2857,103],{"class":75},[69,2859,628],{"class":83},[69,2861,2862,2864,2866,2869,2871,2873,2875,2878,2881],{"class":71,"line":121},[69,2863,1602],{"class":83},[69,2865,680],{"class":75},[69,2867,2868],{"class":79}," make",[69,2870,1851],{"class":83},[69,2872,103],{"class":75},[69,2874,91],{"class":83},[69,2876,2877],{"class":79},"len",[69,2879,2880],{"class":83},"(arr))  ",[69,2882,2883],{"class":124},"\u002F\u002F копия — чистая функция\n",[69,2885,2886,2888,2891,2893,2895],{"class":71,"line":223},[69,2887,1058],{"class":75},[69,2889,2890],{"class":83}," i, v ",[69,2892,680],{"class":75},[69,2894,1066],{"class":75},[69,2896,2897],{"class":83}," arr {\n",[69,2899,2900,2903,2905,2908],{"class":71,"line":534},[69,2901,2902],{"class":83},"        result[i] ",[69,2904,328],{"class":75},[69,2906,2907],{"class":79}," fn",[69,2909,2910],{"class":83},"(v)\n",[69,2912,2913],{"class":71,"line":541},[69,2914,1085],{"class":83},[69,2916,2917,2919],{"class":71,"line":547},[69,2918,634],{"class":75},[69,2920,2921],{"class":83}," result\n",[69,2923,2924],{"class":71,"line":590},[69,2925,663],{"class":83},[69,2927,2928],{"class":71,"line":595},[69,2929,538],{"emptyLinePlaceholder":537},[69,2931,2932,2935,2937,2939,2941,2943,2946,2948,2950,2952,2954,2956,2958,2960,2963,2965,2967,2969,2971,2973,2975],{"class":71,"line":601},[69,2933,2934],{"class":83},"squares ",[69,2936,680],{"class":75},[69,2938,2829],{"class":79},[69,2940,1851],{"class":83},[69,2942,103],{"class":75},[69,2944,2945],{"class":83},"{",[69,2947,1110],{"class":321},[69,2949,91],{"class":83},[69,2951,1115],{"class":321},[69,2953,91],{"class":83},[69,2955,980],{"class":321},[69,2957,91],{"class":83},[69,2959,985],{"class":321},[69,2961,2962],{"class":83},"}, ",[69,2964,76],{"class":75},[69,2966,84],{"class":83},[69,2968,270],{"class":87},[69,2970,97],{"class":75},[69,2972,100],{"class":83},[69,2974,103],{"class":75},[69,2976,628],{"class":83},[69,2978,2979,2981,2983,2985],{"class":71,"line":631},[69,2980,634],{"class":75},[69,2982,522],{"class":83},[69,2984,525],{"class":75},[69,2986,2987],{"class":83}," x\n",[69,2989,2990],{"class":71,"line":660},[69,2991,2992],{"class":83},"})\n",[69,2994,2995],{"class":71,"line":1767},[69,2996,2997],{"class":124},"\u002F\u002F [1, 4, 9, 16]\n",[127,2999,3000,3003,3004,3006,3007,3009],{},[66,3001,3002],{},"forEach"," — ФВП: принимает ",[66,3005,2842],{}," как аргумент. ",[66,3008,2842],{}," применяется к каждому элементу.",[55,3011,3013],{"id":3012},"фвп-принимает-возвращает","ФВП: принимает + возвращает",[60,3015,3017],{"className":62,"code":3016,"language":64,"meta":5,"style":5},"func multiplier(n int) func(int) int {\n    return func(x int) int { return x * n }\n}\n\ndouble := multiplier(2)  \u002F\u002F возвращает функцию\ntriple := multiplier(3)\n\ndouble(5)  \u002F\u002F 10\ntriple(5)  \u002F\u002F 15\n",[66,3018,3019,3045,3071,3075,3079,3096,3111,3115,3127],{"__ignoreMap":5},[69,3020,3021,3023,3025,3027,3029,3031,3033,3035,3037,3039,3041,3043],{"class":71,"line":72},[69,3022,76],{"class":75},[69,3024,606],{"class":79},[69,3026,84],{"class":83},[69,3028,611],{"class":87},[69,3030,97],{"class":75},[69,3032,100],{"class":83},[69,3034,76],{"class":75},[69,3036,84],{"class":83},[69,3038,103],{"class":75},[69,3040,100],{"class":83},[69,3042,103],{"class":75},[69,3044,628],{"class":83},[69,3046,3047,3049,3051,3053,3055,3057,3059,3061,3063,3065,3067,3069],{"class":71,"line":121},[69,3048,634],{"class":75},[69,3050,505],{"class":75},[69,3052,84],{"class":83},[69,3054,270],{"class":87},[69,3056,97],{"class":75},[69,3058,100],{"class":83},[69,3060,103],{"class":75},[69,3062,106],{"class":83},[69,3064,109],{"class":75},[69,3066,522],{"class":83},[69,3068,525],{"class":75},[69,3070,657],{"class":83},[69,3072,3073],{"class":71,"line":223},[69,3074,663],{"class":83},[69,3076,3077],{"class":71,"line":534},[69,3078,538],{"emptyLinePlaceholder":537},[69,3080,3081,3083,3085,3087,3089,3091,3093],{"class":71,"line":541},[69,3082,879],{"class":83},[69,3084,680],{"class":75},[69,3086,606],{"class":79},[69,3088,84],{"class":83},[69,3090,1115],{"class":321},[69,3092,1801],{"class":83},[69,3094,3095],{"class":124},"\u002F\u002F возвращает функцию\n",[69,3097,3098,3101,3103,3105,3107,3109],{"class":71,"line":547},[69,3099,3100],{"class":83},"triple ",[69,3102,680],{"class":75},[69,3104,606],{"class":79},[69,3106,84],{"class":83},[69,3108,980],{"class":321},[69,3110,988],{"class":83},[69,3112,3113],{"class":71,"line":590},[69,3114,538],{"emptyLinePlaceholder":537},[69,3116,3117,3119,3121,3123,3125],{"class":71,"line":595},[69,3118,916],{"class":79},[69,3120,84],{"class":83},[69,3122,921],{"class":321},[69,3124,1801],{"class":83},[69,3126,927],{"class":124},[69,3128,3129,3132,3134,3136,3138],{"class":71,"line":601},[69,3130,3131],{"class":79},"triple",[69,3133,84],{"class":83},[69,3135,921],{"class":321},[69,3137,1801],{"class":83},[69,3139,3140],{"class":124},"\u002F\u002F 15\n",[127,3142,3143,3146],{},[66,3144,3145],{},"multiplier"," — ФВП: возвращает функцию. Используется в каррировании и partial application.",[47,3148],{},[11,3150,3151,3161,3164,3167,3174],{},[14,3152,3153,3154,3157,3158],{},"чистая функция = ",[18,3155,3156],{},"детерминированная"," (один вход → всегда один выход) + ",[18,3159,3160],{},"без побочных эффектов",[14,3162,3163],{},"побочные эффекты: модификация внешних переменных, I\u002FO, рандом, глобальное состояние",[14,3165,3166],{},"преимущества: проще читать, тестировать, параллелить (нет shared state)",[14,3168,3169,3170,3173],{},"грязную функцию можно ",[18,3171,3172],{},"очистить",": вынести зависимость в параметр",[14,3175,3176],{},"не нужно впадать в крайности — бизнес-логику и вычисления делать чистыми, I\u002FO — грязное",[47,3178],{},[50,3180,3182],{"id":3181},"чистые-функции-и-побочные-эффекты","Чистые функции и побочные эффекты",[55,3184,3186],{"id":3185},"грязная-функция","Грязная функция",[60,3188,3190],{"className":62,"code":3189,"language":64,"meta":2375,"style":5},"var counter int  \u002F\u002F глобальная переменная\n\nfunc dirtySum(a, b *int) int {\n    counter++                    \u002F\u002F модифицирует глобальное состояние\n    *a = *a + *b                 \u002F\u002F модифицирует внешнюю память\n    fmt.Println(*a)              \u002F\u002F побочный эффект (I\u002FO)\n    r := rand.Intn(10)           \u002F\u002F недетерминированность\n    secret := os.Getenv(\"KEY\")   \u002F\u002F зависимость от окружения\n    _ = secret\n    return *a + r\n}\n",[66,3191,3192,3204,3208,3232,3242,3267,3283,3307,3330,3340,3352],{"__ignoreMap":5},[69,3193,3194,3196,3199,3201],{"class":71,"line":72},[69,3195,481],{"class":75},[69,3197,3198],{"class":83}," counter ",[69,3200,103],{"class":75},[69,3202,3203],{"class":124},"  \u002F\u002F глобальная переменная\n",[69,3205,3206],{"class":71,"line":121},[69,3207,538],{"emptyLinePlaceholder":537},[69,3209,3210,3212,3215,3217,3219,3221,3223,3226,3228,3230],{"class":71,"line":223},[69,3211,76],{"class":75},[69,3213,3214],{"class":79}," dirtySum",[69,3216,84],{"class":83},[69,3218,88],{"class":87},[69,3220,91],{"class":83},[69,3222,94],{"class":87},[69,3224,3225],{"class":75}," *int",[69,3227,100],{"class":83},[69,3229,103],{"class":75},[69,3231,628],{"class":83},[69,3233,3234,3237,3239],{"class":71,"line":534},[69,3235,3236],{"class":83},"    counter",[69,3238,401],{"class":75},[69,3240,3241],{"class":124},"                    \u002F\u002F модифицирует глобальное состояние\n",[69,3243,3244,3247,3250,3252,3255,3257,3259,3261,3264],{"class":71,"line":541},[69,3245,3246],{"class":75},"    *",[69,3248,3249],{"class":83},"a ",[69,3251,328],{"class":75},[69,3253,3254],{"class":75}," *",[69,3256,3249],{"class":83},[69,3258,115],{"class":75},[69,3260,3254],{"class":75},[69,3262,3263],{"class":83},"b                 ",[69,3265,3266],{"class":124},"\u002F\u002F модифицирует внешнюю память\n",[69,3268,3269,3271,3273,3275,3277,3280],{"class":71,"line":547},[69,3270,1279],{"class":83},[69,3272,753],{"class":79},[69,3274,84],{"class":83},[69,3276,525],{"class":75},[69,3278,3279],{"class":83},"a)              ",[69,3281,3282],{"class":124},"\u002F\u002F побочный эффект (I\u002FO)\n",[69,3284,3285,3288,3290,3293,3296,3298,3301,3304],{"class":71,"line":590},[69,3286,3287],{"class":83},"    r ",[69,3289,680],{"class":75},[69,3291,3292],{"class":83}," rand.",[69,3294,3295],{"class":79},"Intn",[69,3297,84],{"class":83},[69,3299,3300],{"class":321},"10",[69,3302,3303],{"class":83},")           ",[69,3305,3306],{"class":124},"\u002F\u002F недетерминированность\n",[69,3308,3309,3312,3314,3317,3320,3322,3325,3327],{"class":71,"line":595},[69,3310,3311],{"class":83},"    secret ",[69,3313,680],{"class":75},[69,3315,3316],{"class":83}," os.",[69,3318,3319],{"class":79},"Getenv",[69,3321,84],{"class":83},[69,3323,3324],{"class":175},"\"KEY\"",[69,3326,1322],{"class":83},[69,3328,3329],{"class":124},"\u002F\u002F зависимость от окружения\n",[69,3331,3332,3335,3337],{"class":71,"line":601},[69,3333,3334],{"class":83},"    _ ",[69,3336,328],{"class":75},[69,3338,3339],{"class":83}," secret\n",[69,3341,3342,3344,3346,3348,3350],{"class":71,"line":631},[69,3343,634],{"class":75},[69,3345,3254],{"class":75},[69,3347,3249],{"class":83},[69,3349,115],{"class":75},[69,3351,2046],{"class":83},[69,3353,3354],{"class":71,"line":660},[69,3355,663],{"class":83},[55,3357,3359],{"id":3358},"чистая-функция","Чистая функция",[60,3361,3363],{"className":62,"code":3362,"language":64,"meta":5,"style":5},"func pureSum(a, b int) int {\n    return a + b\n}\n\u002F\u002F ✅ Детерминированная: pureSum(3, 5) всегда = 8\n\u002F\u002F ✅ Нет побочных эффектов: ничего не меняет, не печатает, не читает\n",[66,3364,3365,3388,3398,3402,3407],{"__ignoreMap":5},[69,3366,3367,3369,3372,3374,3376,3378,3380,3382,3384,3386],{"class":71,"line":72},[69,3368,76],{"class":75},[69,3370,3371],{"class":79}," pureSum",[69,3373,84],{"class":83},[69,3375,88],{"class":87},[69,3377,91],{"class":83},[69,3379,94],{"class":87},[69,3381,97],{"class":75},[69,3383,100],{"class":83},[69,3385,103],{"class":75},[69,3387,628],{"class":83},[69,3389,3390,3392,3394,3396],{"class":71,"line":121},[69,3391,634],{"class":75},[69,3393,112],{"class":83},[69,3395,115],{"class":75},[69,3397,972],{"class":83},[69,3399,3400],{"class":71,"line":223},[69,3401,663],{"class":83},[69,3403,3404],{"class":71,"line":534},[69,3405,3406],{"class":124},"\u002F\u002F ✅ Детерминированная: pureSum(3, 5) всегда = 8\n",[69,3408,3409],{"class":71,"line":541},[69,3410,3411],{"class":124},"\u002F\u002F ✅ Нет побочных эффектов: ничего не меняет, не печатает, не читает\n",[55,3413,3415],{"id":3414},"как-очистить-грязную","Как очистить грязную",[60,3417,3419],{"className":62,"code":3418,"language":64,"meta":5,"style":5},"\u002F\u002F Грязная: зависит от rand\nfunc dirty(min, max int) float64 {\n    factor := rand.Float64()\n    return float64(max-min) * factor\n}\n\n\u002F\u002F Чистая: рандом вынесен в параметр\nfunc clean(min, max int, factor float64) float64 {\n    return float64(max-min) * factor\n}\n",[66,3420,3421,3426,3451,3466,3485,3489,3493,3498,3528,3544],{"__ignoreMap":5},[69,3422,3423],{"class":71,"line":72},[69,3424,3425],{"class":124},"\u002F\u002F Грязная: зависит от rand\n",[69,3427,3428,3430,3433,3435,3438,3440,3443,3445,3447,3449],{"class":71,"line":121},[69,3429,76],{"class":75},[69,3431,3432],{"class":79}," dirty",[69,3434,84],{"class":83},[69,3436,3437],{"class":87},"min",[69,3439,91],{"class":83},[69,3441,3442],{"class":87},"max",[69,3444,97],{"class":75},[69,3446,100],{"class":83},[69,3448,1432],{"class":75},[69,3450,628],{"class":83},[69,3452,3453,3456,3458,3460,3463],{"class":71,"line":223},[69,3454,3455],{"class":83},"    factor ",[69,3457,680],{"class":75},[69,3459,3292],{"class":83},[69,3461,3462],{"class":79},"Float64",[69,3464,3465],{"class":83},"()\n",[69,3467,3468,3470,3472,3475,3477,3480,3482],{"class":71,"line":534},[69,3469,634],{"class":75},[69,3471,1477],{"class":75},[69,3473,3474],{"class":83},"(max",[69,3476,2323],{"class":75},[69,3478,3479],{"class":83},"min) ",[69,3481,525],{"class":75},[69,3483,3484],{"class":83}," factor\n",[69,3486,3487],{"class":71,"line":541},[69,3488,663],{"class":83},[69,3490,3491],{"class":71,"line":547},[69,3492,538],{"emptyLinePlaceholder":537},[69,3494,3495],{"class":71,"line":590},[69,3496,3497],{"class":124},"\u002F\u002F Чистая: рандом вынесен в параметр\n",[69,3499,3500,3502,3505,3507,3509,3511,3513,3515,3517,3520,3522,3524,3526],{"class":71,"line":595},[69,3501,76],{"class":75},[69,3503,3504],{"class":79}," clean",[69,3506,84],{"class":83},[69,3508,3437],{"class":87},[69,3510,91],{"class":83},[69,3512,3442],{"class":87},[69,3514,97],{"class":75},[69,3516,91],{"class":83},[69,3518,3519],{"class":87},"factor",[69,3521,1477],{"class":75},[69,3523,100],{"class":83},[69,3525,1432],{"class":75},[69,3527,628],{"class":83},[69,3529,3530,3532,3534,3536,3538,3540,3542],{"class":71,"line":601},[69,3531,634],{"class":75},[69,3533,1477],{"class":75},[69,3535,3474],{"class":83},[69,3537,2323],{"class":75},[69,3539,3479],{"class":83},[69,3541,525],{"class":75},[69,3543,3484],{"class":83},[69,3545,3546],{"class":71,"line":631},[69,3547,663],{"class":83},[127,3549,3550],{},"Приём: зависимость, которая делает функцию грязной, выносится в параметр — вызывающий код берёт ответственность за «грязь».",[55,3552,3554],{"id":3553},"не-впадать-в-крайности","Не впадать в крайности",[60,3556,3558],{"className":62,"code":3557,"language":64,"meta":5,"style":5},"\u002F\u002F Формально «грязная» из-за math.Pi — глобальная константа\nfunc circleArea(r float64) float64 {\n    return math.Pi * r * r\n}\n\u002F\u002F Принимать Pi параметром ради «чистоты» — бессмысленно\n",[66,3559,3560,3565,3585,3601,3605],{"__ignoreMap":5},[69,3561,3562],{"class":71,"line":72},[69,3563,3564],{"class":124},"\u002F\u002F Формально «грязная» из-за math.Pi — глобальная константа\n",[69,3566,3567,3569,3572,3574,3577,3579,3581,3583],{"class":71,"line":121},[69,3568,76],{"class":75},[69,3570,3571],{"class":79}," circleArea",[69,3573,84],{"class":83},[69,3575,3576],{"class":87},"r",[69,3578,1477],{"class":75},[69,3580,100],{"class":83},[69,3582,1432],{"class":75},[69,3584,628],{"class":83},[69,3586,3587,3589,3592,3594,3597,3599],{"class":71,"line":223},[69,3588,634],{"class":75},[69,3590,3591],{"class":83}," math.Pi ",[69,3593,525],{"class":75},[69,3595,3596],{"class":83}," r ",[69,3598,525],{"class":75},[69,3600,2046],{"class":83},[69,3602,3603],{"class":71,"line":534},[69,3604,663],{"class":83},[69,3606,3607],{"class":71,"line":541},[69,3608,3609],{"class":124},"\u002F\u002F Принимать Pi параметром ради «чистоты» — бессмысленно\n",[127,3611,3612,3613,3616],{},"Глобальные ",[18,3614,3615],{},"константы"," не делают функцию грязной на практике.",[55,3618,3620],{"id":3619},"преимущества-чистых-функций","Преимущества чистых функций",[127,3622,3623],{},"Проще разбирать (нет зависимостей от внешнего состояния), проще тестировать (не нужно мокать глобальные переменные), проще параллелить (нет shared state → нет гонок).",[47,3625],{},[11,3627,3628,3634,3640,3646,3652],{},[14,3629,3630,3633],{},[18,3631,3632],{},"нет перегрузки"," — нельзя две функции с одним именем и разными параметрами",[14,3635,3636,3639],{},[18,3637,3638],{},"нет параметров по умолчанию"," — все аргументы обязательны",[14,3641,3642,3645],{},[18,3643,3644],{},"нет RVO \u002F NRVO"," — возврат всегда копирует (может появиться в будущих версиях)",[14,3647,3648,3651],{},[18,3649,3650],{},"прототипы"," (функция без тела) — для линковки с ассемблерным кодом",[14,3653,3654],{},"можно вызывать функции, определённые ниже (прототипы не нужны для Go-кода)",[47,3656],{},[50,3658,3660],{"id":3659},"ограничения-функций-в-go","Ограничения функций в Go",[55,3662,3664],{"id":3663},"нет-перегрузки","Нет перегрузки",[60,3666,3668],{"className":62,"code":3667,"language":64,"meta":5,"style":5},"func add(a, b int) int { ... }\nfunc add(a, b float64) float64 { ... }  \u002F\u002F ❌ ошибка: add redeclared\n",[66,3669,3670,3696],{"__ignoreMap":5},[69,3671,3672,3674,3676,3678,3680,3682,3684,3686,3688,3690,3692,3694],{"class":71,"line":72},[69,3673,76],{"class":75},[69,3675,80],{"class":79},[69,3677,84],{"class":83},[69,3679,88],{"class":87},[69,3681,91],{"class":83},[69,3683,94],{"class":87},[69,3685,97],{"class":75},[69,3687,100],{"class":83},[69,3689,103],{"class":75},[69,3691,106],{"class":83},[69,3693,159],{"class":75},[69,3695,531],{"class":83},[69,3697,3698,3700,3702,3704,3706,3708,3710,3712,3714,3716,3718,3720,3722],{"class":71,"line":121},[69,3699,76],{"class":75},[69,3701,80],{"class":79},[69,3703,84],{"class":83},[69,3705,88],{"class":87},[69,3707,91],{"class":83},[69,3709,94],{"class":87},[69,3711,1477],{"class":75},[69,3713,100],{"class":83},[69,3715,1432],{"class":75},[69,3717,106],{"class":83},[69,3719,159],{"class":75},[69,3721,162],{"class":83},[69,3723,3724],{"class":124},"\u002F\u002F ❌ ошибка: add redeclared\n",[127,3726,3727,3730,3731,3734,3735,3738],{},[18,3728,3729],{},"Исключения:"," можно объявить несколько ",[66,3732,3733],{},"init()"," и несколько ",[66,3736,3737],{},"_()"," (функция с подчёркиванием — нельзя вызвать).",[55,3740,3742],{"id":3741},"нет-параметров-по-умолчанию","Нет параметров по умолчанию",[60,3744,3746],{"className":62,"code":3745,"language":64,"meta":5,"style":5},"\u002F\u002F Так нельзя:\n\u002F\u002F func connect(host string, port int = 8080) { ... }\n\n\u002F\u002F Обходные пути:\n\u002F\u002F 1. Variadic\n\u002F\u002F 2. Структура с опциями\n\u002F\u002F 3. Functional options (паттерн)\n",[66,3747,3748,3753,3758,3762,3767,3772,3777],{"__ignoreMap":5},[69,3749,3750],{"class":71,"line":72},[69,3751,3752],{"class":124},"\u002F\u002F Так нельзя:\n",[69,3754,3755],{"class":71,"line":121},[69,3756,3757],{"class":124},"\u002F\u002F func connect(host string, port int = 8080) { ... }\n",[69,3759,3760],{"class":71,"line":223},[69,3761,538],{"emptyLinePlaceholder":537},[69,3763,3764],{"class":71,"line":534},[69,3765,3766],{"class":124},"\u002F\u002F Обходные пути:\n",[69,3768,3769],{"class":71,"line":541},[69,3770,3771],{"class":124},"\u002F\u002F 1. Variadic\n",[69,3773,3774],{"class":71,"line":547},[69,3775,3776],{"class":124},"\u002F\u002F 2. Структура с опциями\n",[69,3778,3779],{"class":71,"line":590},[69,3780,3781],{"class":124},"\u002F\u002F 3. Functional options (паттерн)\n",[127,3783,3784,3785,91,3787,91,3790,1144],{},"Три основных паттерна-обхода отсутствия default params: ",[18,3786,828],{},[18,3788,3789],{},"struct with options",[18,3791,3792],{},"functional options",[55,3794,3796],{"id":3795},"нет-rvo-nrvo","Нет RVO \u002F NRVO",[60,3798,3800],{"className":62,"code":3799,"language":64,"meta":5,"style":5},"func newPoint() Point {\n    return Point{X: 1, Y: 2}  \u002F\u002F объект создаётся внутри, потом КОПИРУЕТСЯ наружу\n}\n\u002F\u002F В C++ компилятор мог бы создать объект сразу на вызывающей стороне\n\u002F\u002F В Go такой оптимизации нет\n",[66,3801,3802,3816,3839,3843,3848],{"__ignoreMap":5},[69,3803,3804,3806,3809,3811,3814],{"class":71,"line":72},[69,3805,76],{"class":75},[69,3807,3808],{"class":79}," newPoint",[69,3810,1986],{"class":83},[69,3812,3813],{"class":79},"Point",[69,3815,628],{"class":83},[69,3817,3818,3820,3823,3826,3828,3831,3833,3836],{"class":71,"line":121},[69,3819,634],{"class":75},[69,3821,3822],{"class":79}," Point",[69,3824,3825],{"class":83},"{X: ",[69,3827,1110],{"class":321},[69,3829,3830],{"class":83},", Y: ",[69,3832,1115],{"class":321},[69,3834,3835],{"class":83},"}  ",[69,3837,3838],{"class":124},"\u002F\u002F объект создаётся внутри, потом КОПИРУЕТСЯ наружу\n",[69,3840,3841],{"class":71,"line":223},[69,3842,663],{"class":83},[69,3844,3845],{"class":71,"line":534},[69,3846,3847],{"class":124},"\u002F\u002F В C++ компилятор мог бы создать объект сразу на вызывающей стороне\n",[69,3849,3850],{"class":71,"line":541},[69,3851,3852],{"class":124},"\u002F\u002F В Go такой оптимизации нет\n",[127,3854,3855,3858,3859,3862],{},[18,3856,3857],{},"RVO"," — Return Value Optimization (анонимный объект). ",[18,3860,3861],{},"NRVO"," — Named RVO (именованная переменная).",[127,3864,3865],{},"Ни RVO, ни NRVO в Go нет — возврат значения из функции всегда копирует. Может появиться в будущих версиях.",[55,3867,3868],{"id":3650},"Прототипы",[60,3870,3872],{"className":62,"code":3871,"language":64,"meta":5,"style":5},"func asmFunction(x int) int  \u002F\u002F нет тела — прототип\n\u002F\u002F реализация будет в .s файле (ассемблер Go)\n\u002F\u002F при линковке ассемблерный код подключится к прототипу\n",[66,3873,3874,3894,3899],{"__ignoreMap":5},[69,3875,3876,3878,3881,3883,3885,3887,3889,3891],{"class":71,"line":72},[69,3877,76],{"class":75},[69,3879,3880],{"class":79}," asmFunction",[69,3882,84],{"class":83},[69,3884,270],{"class":87},[69,3886,97],{"class":75},[69,3888,100],{"class":83},[69,3890,103],{"class":75},[69,3892,3893],{"class":124},"  \u002F\u002F нет тела — прототип\n",[69,3895,3896],{"class":71,"line":121},[69,3897,3898],{"class":124},"\u002F\u002F реализация будет в .s файле (ассемблер Go)\n",[69,3900,3901],{"class":71,"line":223},[69,3902,3903],{"class":124},"\u002F\u002F при линковке ассемблерный код подключится к прототипу\n",[127,3905,3906],{},"Единственный практический кейс прототипов — реализация на ассемблере (крайне редко).",[55,3908,3733],{"id":809},[60,3910,3912],{"className":62,"code":3911,"language":64,"meta":5,"style":5},"func init() { fmt.Println(\"first\") }\nfunc init() { fmt.Println(\"second\") }  \u002F\u002F ✅ можно несколько init\n\u002F\u002F в одном пакете: порядок объявления\n\u002F\u002F между пакетами: порядок импорта (подробнее — в документации)\n",[66,3913,3914,3933,3954,3959],{"__ignoreMap":5},[69,3915,3916,3918,3921,3923,3925,3927,3930],{"class":71,"line":72},[69,3917,76],{"class":75},[69,3919,3920],{"class":79}," init",[69,3922,2428],{"class":83},[69,3924,753],{"class":79},[69,3926,84],{"class":83},[69,3928,3929],{"class":175},"\"first\"",[69,3931,3932],{"class":83},") }\n",[69,3934,3935,3937,3939,3941,3943,3945,3948,3951],{"class":71,"line":121},[69,3936,76],{"class":75},[69,3938,3920],{"class":79},[69,3940,2428],{"class":83},[69,3942,753],{"class":79},[69,3944,84],{"class":83},[69,3946,3947],{"class":175},"\"second\"",[69,3949,3950],{"class":83},") }  ",[69,3952,3953],{"class":124},"\u002F\u002F ✅ можно несколько init\n",[69,3955,3956],{"class":71,"line":223},[69,3957,3958],{"class":124},"\u002F\u002F в одном пакете: порядок объявления\n",[69,3960,3961],{"class":71,"line":534},[69,3962,3963],{"class":124},"\u002F\u002F между пакетами: порядок импорта (подробнее — в документации)\n",[127,3965,3966,3967,3969],{},"Можно объявить несколько ",[66,3968,3733],{}," в одном файле\u002Fпакете. В одном пакете порядок — по порядку объявления. Между пакетами — по порядку импорта.",[47,3971],{},[11,3973,3974,3984,3990,3997],{},[14,3975,3976,3979,3980,3983],{},[18,3977,3978],{},"прямая"," рекурсия: f → f. ",[18,3981,3982],{},"Косвенная",": f → g → f",[14,3985,3986,3989],{},[18,3987,3988],{},"хвостовая рекурсия"," — последний вызов = сам себя, без дополнительных операндов → можно развернуть в цикл",[14,3991,3992,3993,3996],{},"в Go ",[18,3994,3995],{},"нет оптимизации хвостовой рекурсии"," (\"не нужно в языке с циклами\")",[14,3998,3999,4002],{},[18,4000,4001],{},"мемоизация"," — кэширование результатов: не вычислять повторно (основа динамического программирования)",[47,4004],{},[50,4006,4008],{"id":4007},"рекурсия-и-мемоизация","Рекурсия и мемоизация",[55,4010,4012],{"id":4011},"обычный-vs-хвостовой-факториал","Обычный vs хвостовой факториал",[60,4014,4016],{"className":62,"code":4015,"language":64,"meta":5,"style":5},"\u002F\u002F Обычная рекурсия — дополнительный операнд (n *)\nfunc factorial(n int) int {\n    if n == 0 { return 1 }\n    return n * factorial(n-1)  \u002F\u002F n * ... нужно запомнить на стеке\n}\n\n\u002F\u002F Хвостовая рекурсия — аккумулятор в параметре\nfunc fastFactorial(n int) int {\n    return tailFact(n, 1)\n}\nfunc tailFact(n, acc int) int {\n    if n == 0 { return acc }\n    return tailFact(n-1, n*acc)  \u002F\u002F последний вызов — сам себя, без операндов\n}\n",[66,4017,4018,4023,4042,4060,4081,4085,4089,4094,4113,4127,4131,4154,4171,4194],{"__ignoreMap":5},[69,4019,4020],{"class":71,"line":72},[69,4021,4022],{"class":124},"\u002F\u002F Обычная рекурсия — дополнительный операнд (n *)\n",[69,4024,4025,4027,4030,4032,4034,4036,4038,4040],{"class":71,"line":121},[69,4026,76],{"class":75},[69,4028,4029],{"class":79}," factorial",[69,4031,84],{"class":83},[69,4033,611],{"class":87},[69,4035,97],{"class":75},[69,4037,100],{"class":83},[69,4039,103],{"class":75},[69,4041,628],{"class":83},[69,4043,4044,4046,4048,4050,4052,4054,4056,4058],{"class":71,"line":223},[69,4045,1555],{"class":75},[69,4047,2297],{"class":83},[69,4049,759],{"class":75},[69,4051,1563],{"class":321},[69,4053,106],{"class":83},[69,4055,109],{"class":75},[69,4057,376],{"class":321},[69,4059,531],{"class":83},[69,4061,4062,4064,4066,4068,4070,4072,4074,4076,4078],{"class":71,"line":534},[69,4063,634],{"class":75},[69,4065,2297],{"class":83},[69,4067,525],{"class":75},[69,4069,4029],{"class":79},[69,4071,2320],{"class":83},[69,4073,2323],{"class":75},[69,4075,1110],{"class":321},[69,4077,1801],{"class":83},[69,4079,4080],{"class":124},"\u002F\u002F n * ... нужно запомнить на стеке\n",[69,4082,4083],{"class":71,"line":541},[69,4084,663],{"class":83},[69,4086,4087],{"class":71,"line":547},[69,4088,538],{"emptyLinePlaceholder":537},[69,4090,4091],{"class":71,"line":590},[69,4092,4093],{"class":124},"\u002F\u002F Хвостовая рекурсия — аккумулятор в параметре\n",[69,4095,4096,4098,4101,4103,4105,4107,4109,4111],{"class":71,"line":595},[69,4097,76],{"class":75},[69,4099,4100],{"class":79}," fastFactorial",[69,4102,84],{"class":83},[69,4104,611],{"class":87},[69,4106,97],{"class":75},[69,4108,100],{"class":83},[69,4110,103],{"class":75},[69,4112,628],{"class":83},[69,4114,4115,4117,4120,4123,4125],{"class":71,"line":601},[69,4116,634],{"class":75},[69,4118,4119],{"class":79}," tailFact",[69,4121,4122],{"class":83},"(n, ",[69,4124,1110],{"class":321},[69,4126,988],{"class":83},[69,4128,4129],{"class":71,"line":631},[69,4130,663],{"class":83},[69,4132,4133,4135,4137,4139,4141,4143,4146,4148,4150,4152],{"class":71,"line":660},[69,4134,76],{"class":75},[69,4136,4119],{"class":79},[69,4138,84],{"class":83},[69,4140,611],{"class":87},[69,4142,91],{"class":83},[69,4144,4145],{"class":87},"acc",[69,4147,97],{"class":75},[69,4149,100],{"class":83},[69,4151,103],{"class":75},[69,4153,628],{"class":83},[69,4155,4156,4158,4160,4162,4164,4166,4168],{"class":71,"line":1767},[69,4157,1555],{"class":75},[69,4159,2297],{"class":83},[69,4161,759],{"class":75},[69,4163,1563],{"class":321},[69,4165,106],{"class":83},[69,4167,109],{"class":75},[69,4169,4170],{"class":83}," acc }\n",[69,4172,4173,4175,4177,4179,4181,4183,4186,4188,4191],{"class":71,"line":1780},[69,4174,634],{"class":75},[69,4176,4119],{"class":79},[69,4178,2320],{"class":83},[69,4180,2323],{"class":75},[69,4182,1110],{"class":321},[69,4184,4185],{"class":83},", n",[69,4187,525],{"class":75},[69,4189,4190],{"class":83},"acc)  ",[69,4192,4193],{"class":124},"\u002F\u002F последний вызов — сам себя, без операндов\n",[69,4195,4196],{"class":71,"line":1807},[69,4197,663],{"class":83},[127,4199,4200,4201,4204],{},"В языках с TCO (C++, Scheme) ",[66,4202,4203],{},"tailFact"," разворачивается в цикл с одним фреймом.",[127,4206,4207,4208,4211],{},"В Go — ",[18,4209,4210],{},"нет",": оба варианта одинаково расходуют стек. Бенчмарк подтверждает: производительность идентичная.",[55,4213,4215],{"id":4214},"почему-нет-tco-в-go","Почему нет TCO в Go",[127,4217,4218,4219],{},"Цитата из обсуждений: ",[4220,4221,4222],"em",{},"\"Tail call optimization is not needed in a language with loops. When a programmer writes recursive code, they want to think about a call stack, or they write a loop.\"",[55,4224,4226],{"id":4225},"мемоизация-fibonacci","Мемоизация — Fibonacci",[60,4228,4230],{"className":62,"code":4229,"language":64,"meta":5,"style":5},"func memoFib(n int) int {\n    cache := make([]int, n+1)\n\n    var fib func(int) int       \u002F\u002F 1. объявить переменную\n    fib = func(k int) int {     \u002F\u002F 2. присвоить (self-reference)\n        if k \u003C= 1 { return 1 }\n        if cache[k] != 0 { return cache[k] }  \u002F\u002F уже вычислено\n        cache[k] = fib(k-1) + fib(k-2)        \u002F\u002F вычислить и запомнить\n        return cache[k]\n    }\n\n    return fib(n)\n}\n",[66,4231,4232,4251,4272,4276,4296,4322,4342,4364,4398,4405,4409,4413,4422],{"__ignoreMap":5},[69,4233,4234,4236,4239,4241,4243,4245,4247,4249],{"class":71,"line":72},[69,4235,76],{"class":75},[69,4237,4238],{"class":79}," memoFib",[69,4240,84],{"class":83},[69,4242,611],{"class":87},[69,4244,97],{"class":75},[69,4246,100],{"class":83},[69,4248,103],{"class":75},[69,4250,628],{"class":83},[69,4252,4253,4256,4258,4260,4262,4264,4266,4268,4270],{"class":71,"line":121},[69,4254,4255],{"class":83},"    cache ",[69,4257,680],{"class":75},[69,4259,2868],{"class":79},[69,4261,1851],{"class":83},[69,4263,103],{"class":75},[69,4265,4185],{"class":83},[69,4267,115],{"class":75},[69,4269,1110],{"class":321},[69,4271,988],{"class":83},[69,4273,4274],{"class":71,"line":223},[69,4275,538],{"emptyLinePlaceholder":537},[69,4277,4278,4281,4283,4285,4287,4289,4291,4293],{"class":71,"line":534},[69,4279,4280],{"class":75},"    var",[69,4282,2257],{"class":83},[69,4284,76],{"class":75},[69,4286,84],{"class":83},[69,4288,103],{"class":75},[69,4290,100],{"class":83},[69,4292,103],{"class":75},[69,4294,4295],{"class":124},"       \u002F\u002F 1. объявить переменную\n",[69,4297,4298,4301,4303,4305,4307,4310,4312,4314,4316,4319],{"class":71,"line":541},[69,4299,4300],{"class":83},"    fib ",[69,4302,328],{"class":75},[69,4304,505],{"class":75},[69,4306,84],{"class":83},[69,4308,4309],{"class":87},"k",[69,4311,97],{"class":75},[69,4313,100],{"class":83},[69,4315,103],{"class":75},[69,4317,4318],{"class":83}," {     ",[69,4320,4321],{"class":124},"\u002F\u002F 2. присвоить (self-reference)\n",[69,4323,4324,4327,4330,4332,4334,4336,4338,4340],{"class":71,"line":547},[69,4325,4326],{"class":75},"        if",[69,4328,4329],{"class":83}," k ",[69,4331,2300],{"class":75},[69,4333,376],{"class":321},[69,4335,106],{"class":83},[69,4337,109],{"class":75},[69,4339,376],{"class":321},[69,4341,531],{"class":83},[69,4343,4344,4346,4349,4352,4354,4356,4358,4361],{"class":71,"line":590},[69,4345,4326],{"class":75},[69,4347,4348],{"class":83}," cache[k] ",[69,4350,4351],{"class":75},"!=",[69,4353,1563],{"class":321},[69,4355,106],{"class":83},[69,4357,109],{"class":75},[69,4359,4360],{"class":83}," cache[k] }  ",[69,4362,4363],{"class":124},"\u002F\u002F уже вычислено\n",[69,4365,4366,4369,4371,4373,4376,4378,4380,4382,4384,4386,4388,4390,4392,4395],{"class":71,"line":595},[69,4367,4368],{"class":83},"        cache[k] ",[69,4370,328],{"class":75},[69,4372,2317],{"class":79},[69,4374,4375],{"class":83},"(k",[69,4377,2323],{"class":75},[69,4379,1110],{"class":321},[69,4381,100],{"class":83},[69,4383,115],{"class":75},[69,4385,2317],{"class":79},[69,4387,4375],{"class":83},[69,4389,2323],{"class":75},[69,4391,1115],{"class":321},[69,4393,4394],{"class":83},")        ",[69,4396,4397],{"class":124},"\u002F\u002F вычислить и запомнить\n",[69,4399,4400,4402],{"class":71,"line":601},[69,4401,1590],{"class":75},[69,4403,4404],{"class":83}," cache[k]\n",[69,4406,4407],{"class":71,"line":631},[69,4408,1085],{"class":83},[69,4410,4411],{"class":71,"line":660},[69,4412,538],{"emptyLinePlaceholder":537},[69,4414,4415,4417,4419],{"class":71,"line":1767},[69,4416,634],{"class":75},[69,4418,2317],{"class":79},[69,4420,4421],{"class":83},"(n)\n",[69,4423,4424],{"class":71,"line":1780},[69,4425,663],{"class":83},[127,4427,4428,4429,4432],{},"Паттерн self-reference: сначала ",[66,4430,4431],{},"var fib func(int) int",", затем присвоение — иначе рекурсия внутри анонимной функции невозможна.",[55,4434,4436],{"id":4435},"зачем-мемоизация","Зачем мемоизация",[127,4438,4439],{},"Дерево рекурсии Fibonacci без кэша:",[60,4441,4444],{"className":4442,"code":4443,"language":2135},[2133],"fib(5) → fib(4) + fib(3)\n          │         │\n     fib(3)+fib(2)  fib(2)+fib(1)   ← fib(3) вычислен дважды\n     │               │                ← fib(2) вычислен трижды\n    ...             ...\n",[66,4445,4443],{"__ignoreMap":5},[127,4447,4448,4449,4452],{},"С мемоизацией: каждое значение вычисляется ",[18,4450,4451],{},"один раз"," → O(n) вместо O(2^n).",[47,4454],{},[11,4456,4457,4463,4469,4472],{},[14,4458,4459,4462],{},[18,4460,4461],{},"декоратор"," — обёртка: добавляет поведение (логи, метрики) вокруг бизнес-функции",[14,4464,4465,4468],{},[18,4466,4467],{},"композиция"," — цепочка функций: результат одной → вход следующей (pipeline)",[14,4470,4471],{},"оба паттерна — ФВП: принимают\u002Fвозвращают функции",[14,4473,4474],{},"continuation (callback success\u002Ferror) — тоже вариант, но осторожно с callback hell",[47,4476],{},[50,4478,4480],{"id":4479},"декораторы-композиция-и-callbacks","Декораторы, композиция и callbacks",[55,4482,4483],{"id":4461},"Декоратор",[60,4485,4487],{"className":62,"code":4486,"language":64,"meta":5,"style":5},"type BinOp func(int, int) int\n\nfunc calculate(op BinOp, a, b int) int {\n    fmt.Printf(\"args: %d, %d\\n\", a, b)  \u002F\u002F добавленное поведение (лог)\n    result := op(a, b)                    \u002F\u002F вызов оригинальной функции\n    fmt.Printf(\"result: %d\\n\", result)    \u002F\u002F добавленное поведение (лог)\n    return result\n}\n\nadd := func(a, b int) int { return a + b }\nmul := func(a, b int) int { return a * b }\n\ncalculate(add, 3, 5)  \u002F\u002F args: 3, 5 → result: 8\ncalculate(mul, 3, 5)  \u002F\u002F args: 3, 5 → result: 15\n",[66,4488,4489,4511,4515,4545,4574,4589,4609,4615,4619,4623,4656,4689,4693,4712],{"__ignoreMap":5},[69,4490,4491,4494,4497,4499,4501,4503,4505,4507,4509],{"class":71,"line":72},[69,4492,4493],{"class":75},"type",[69,4495,4496],{"class":79}," BinOp",[69,4498,505],{"class":75},[69,4500,84],{"class":83},[69,4502,103],{"class":75},[69,4504,91],{"class":83},[69,4506,103],{"class":75},[69,4508,100],{"class":83},[69,4510,495],{"class":75},[69,4512,4513],{"class":71,"line":121},[69,4514,538],{"emptyLinePlaceholder":537},[69,4516,4517,4519,4522,4524,4527,4529,4531,4533,4535,4537,4539,4541,4543],{"class":71,"line":223},[69,4518,76],{"class":75},[69,4520,4521],{"class":79}," calculate",[69,4523,84],{"class":83},[69,4525,4526],{"class":87},"op",[69,4528,4496],{"class":79},[69,4530,91],{"class":83},[69,4532,88],{"class":87},[69,4534,91],{"class":83},[69,4536,94],{"class":87},[69,4538,97],{"class":75},[69,4540,100],{"class":83},[69,4542,103],{"class":75},[69,4544,628],{"class":83},[69,4546,4547,4549,4552,4554,4557,4560,4562,4565,4568,4571],{"class":71,"line":534},[69,4548,1279],{"class":83},[69,4550,4551],{"class":79},"Printf",[69,4553,84],{"class":83},[69,4555,4556],{"class":175},"\"args: ",[69,4558,4559],{"class":321},"%d",[69,4561,91],{"class":175},[69,4563,4564],{"class":321},"%d\\n",[69,4566,4567],{"class":175},"\"",[69,4569,4570],{"class":83},", a, b)  ",[69,4572,4573],{"class":124},"\u002F\u002F добавленное поведение (лог)\n",[69,4575,4576,4578,4580,4583,4586],{"class":71,"line":541},[69,4577,1602],{"class":83},[69,4579,680],{"class":75},[69,4581,4582],{"class":79}," op",[69,4584,4585],{"class":83},"(a, b)                    ",[69,4587,4588],{"class":124},"\u002F\u002F вызов оригинальной функции\n",[69,4590,4591,4593,4595,4597,4600,4602,4604,4607],{"class":71,"line":547},[69,4592,1279],{"class":83},[69,4594,4551],{"class":79},[69,4596,84],{"class":83},[69,4598,4599],{"class":175},"\"result: ",[69,4601,4564],{"class":321},[69,4603,4567],{"class":175},[69,4605,4606],{"class":83},", result)    ",[69,4608,4573],{"class":124},[69,4610,4611,4613],{"class":71,"line":590},[69,4612,634],{"class":75},[69,4614,2921],{"class":83},[69,4616,4617],{"class":71,"line":595},[69,4618,663],{"class":83},[69,4620,4621],{"class":71,"line":601},[69,4622,538],{"emptyLinePlaceholder":537},[69,4624,4625,4628,4630,4632,4634,4636,4638,4640,4642,4644,4646,4648,4650,4652,4654],{"class":71,"line":631},[69,4626,4627],{"class":83},"add ",[69,4629,680],{"class":75},[69,4631,505],{"class":75},[69,4633,84],{"class":83},[69,4635,88],{"class":87},[69,4637,91],{"class":83},[69,4639,94],{"class":87},[69,4641,97],{"class":75},[69,4643,100],{"class":83},[69,4645,103],{"class":75},[69,4647,106],{"class":83},[69,4649,109],{"class":75},[69,4651,112],{"class":83},[69,4653,115],{"class":75},[69,4655,118],{"class":83},[69,4657,4658,4661,4663,4665,4667,4669,4671,4673,4675,4677,4679,4681,4683,4685,4687],{"class":71,"line":660},[69,4659,4660],{"class":83},"mul ",[69,4662,680],{"class":75},[69,4664,505],{"class":75},[69,4666,84],{"class":83},[69,4668,88],{"class":87},[69,4670,91],{"class":83},[69,4672,94],{"class":87},[69,4674,97],{"class":75},[69,4676,100],{"class":83},[69,4678,103],{"class":75},[69,4680,106],{"class":83},[69,4682,109],{"class":75},[69,4684,112],{"class":83},[69,4686,525],{"class":75},[69,4688,118],{"class":83},[69,4690,4691],{"class":71,"line":1767},[69,4692,538],{"emptyLinePlaceholder":537},[69,4694,4695,4698,4701,4703,4705,4707,4709],{"class":71,"line":1780},[69,4696,4697],{"class":79},"calculate",[69,4699,4700],{"class":83},"(add, ",[69,4702,980],{"class":321},[69,4704,91],{"class":83},[69,4706,921],{"class":321},[69,4708,1801],{"class":83},[69,4710,4711],{"class":124},"\u002F\u002F args: 3, 5 → result: 8\n",[69,4713,4714,4716,4719,4721,4723,4725,4727],{"class":71,"line":1807},[69,4715,4697],{"class":79},[69,4717,4718],{"class":83},"(mul, ",[69,4720,980],{"class":321},[69,4722,91],{"class":83},[69,4724,921],{"class":321},[69,4726,1801],{"class":83},[69,4728,4729],{"class":124},"\u002F\u002F args: 3, 5 → result: 15\n",[127,4731,4732],{},"Декоратор принимает функцию и добавляет поведение (логи, метрики) вокруг неё, не засоряя бизнес-логику.",[55,4734,4735],{"id":4467},"Композиция",[60,4737,4739],{"className":62,"code":4738,"language":64,"meta":5,"style":5},"func compose(fns ...func(int) int) func(int) int {\n    return func(val int) int {\n        for _, fn := range fns {\n            val = fn(val)  \u002F\u002F результат → вход следующей\n        }\n        return val\n    }\n}\n\nsquare := func(x int) int { return x * x }\nnegate := func(x int) int { return -x }\n\ntransform := compose(square, negate, square)\n\u002F\u002F 4 → 16 → -16 → 256\ntransform(4)  \u002F\u002F 256\n",[66,4740,4741,4778,4797,4811,4826,4830,4837,4841,4845,4849,4879,4908,4912,4937,4942],{"__ignoreMap":5},[69,4742,4743,4745,4748,4750,4753,4756,4758,4760,4762,4764,4766,4768,4770,4772,4774,4776],{"class":71,"line":72},[69,4744,76],{"class":75},[69,4746,4747],{"class":79}," compose",[69,4749,84],{"class":83},[69,4751,4752],{"class":87},"fns",[69,4754,4755],{"class":75}," ...func",[69,4757,84],{"class":83},[69,4759,103],{"class":75},[69,4761,100],{"class":83},[69,4763,103],{"class":75},[69,4765,100],{"class":83},[69,4767,76],{"class":75},[69,4769,84],{"class":83},[69,4771,103],{"class":75},[69,4773,100],{"class":83},[69,4775,103],{"class":75},[69,4777,628],{"class":83},[69,4779,4780,4782,4784,4786,4789,4791,4793,4795],{"class":71,"line":121},[69,4781,634],{"class":75},[69,4783,505],{"class":75},[69,4785,84],{"class":83},[69,4787,4788],{"class":87},"val",[69,4790,97],{"class":75},[69,4792,100],{"class":83},[69,4794,103],{"class":75},[69,4796,628],{"class":83},[69,4798,4799,4801,4804,4806,4808],{"class":71,"line":223},[69,4800,2652],{"class":75},[69,4802,4803],{"class":83}," _, fn ",[69,4805,680],{"class":75},[69,4807,1066],{"class":75},[69,4809,4810],{"class":83}," fns {\n",[69,4812,4813,4816,4818,4820,4823],{"class":71,"line":534},[69,4814,4815],{"class":83},"            val ",[69,4817,328],{"class":75},[69,4819,2907],{"class":79},[69,4821,4822],{"class":83},"(val)  ",[69,4824,4825],{"class":124},"\u002F\u002F результат → вход следующей\n",[69,4827,4828],{"class":71,"line":541},[69,4829,2698],{"class":83},[69,4831,4832,4834],{"class":71,"line":547},[69,4833,1590],{"class":75},[69,4835,4836],{"class":83}," val\n",[69,4838,4839],{"class":71,"line":590},[69,4840,1085],{"class":83},[69,4842,4843],{"class":71,"line":595},[69,4844,663],{"class":83},[69,4846,4847],{"class":71,"line":601},[69,4848,538],{"emptyLinePlaceholder":537},[69,4850,4851,4854,4856,4858,4860,4862,4864,4866,4868,4870,4872,4874,4876],{"class":71,"line":631},[69,4852,4853],{"class":83},"square ",[69,4855,680],{"class":75},[69,4857,505],{"class":75},[69,4859,84],{"class":83},[69,4861,270],{"class":87},[69,4863,97],{"class":75},[69,4865,100],{"class":83},[69,4867,103],{"class":75},[69,4869,106],{"class":83},[69,4871,109],{"class":75},[69,4873,522],{"class":83},[69,4875,525],{"class":75},[69,4877,4878],{"class":83}," x }\n",[69,4880,4881,4884,4886,4888,4890,4892,4894,4896,4898,4900,4902,4905],{"class":71,"line":660},[69,4882,4883],{"class":83},"negate ",[69,4885,680],{"class":75},[69,4887,505],{"class":75},[69,4889,84],{"class":83},[69,4891,270],{"class":87},[69,4893,97],{"class":75},[69,4895,100],{"class":83},[69,4897,103],{"class":75},[69,4899,106],{"class":83},[69,4901,109],{"class":75},[69,4903,4904],{"class":75}," -",[69,4906,4907],{"class":83},"x }\n",[69,4909,4910],{"class":71,"line":1767},[69,4911,538],{"emptyLinePlaceholder":537},[69,4913,4914,4917,4919,4921,4923,4926,4928,4931,4933,4935],{"class":71,"line":1780},[69,4915,4916],{"class":83},"transform ",[69,4918,680],{"class":75},[69,4920,4747],{"class":79},[69,4922,84],{"class":83},[69,4924,4925],{"class":79},"square",[69,4927,91],{"class":83},[69,4929,4930],{"class":79},"negate",[69,4932,91],{"class":83},[69,4934,4925],{"class":79},[69,4936,988],{"class":83},[69,4938,4939],{"class":71,"line":1807},[69,4940,4941],{"class":124},"\u002F\u002F 4 → 16 → -16 → 256\n",[69,4943,4944,4947,4949,4951,4953],{"class":71,"line":1812},[69,4945,4946],{"class":79},"transform",[69,4948,84],{"class":83},[69,4950,985],{"class":321},[69,4952,1801],{"class":83},[69,4954,4955],{"class":124},"\u002F\u002F 256\n",[127,4957,4958],{},"Композиция — pipeline: каждая функция обрабатывает результат предыдущей. Порядок можно менять (reverse helper).",[55,4960,4962],{"id":4961},"декоратор-через-вложенность","Декоратор через вложенность",[60,4964,4966],{"className":62,"code":4965,"language":64,"meta":5,"style":5},"\u002F\u002F Альтернативный стиль: декорирование вложением\nresult := calculate(add, 3, 5)\n\u002F\u002F эквивалентно:\nresult := calculate(func(a, b int) int {\n    return a + b\n}, 3, 5)\n",[66,4967,4968,4973,4991,4996,5024,5034],{"__ignoreMap":5},[69,4969,4970],{"class":71,"line":72},[69,4971,4972],{"class":124},"\u002F\u002F Альтернативный стиль: декорирование вложением\n",[69,4974,4975,4977,4979,4981,4983,4985,4987,4989],{"class":71,"line":121},[69,4976,941],{"class":83},[69,4978,680],{"class":75},[69,4980,4521],{"class":79},[69,4982,4700],{"class":83},[69,4984,980],{"class":321},[69,4986,91],{"class":83},[69,4988,921],{"class":321},[69,4990,988],{"class":83},[69,4992,4993],{"class":71,"line":223},[69,4994,4995],{"class":124},"\u002F\u002F эквивалентно:\n",[69,4997,4998,5000,5002,5004,5006,5008,5010,5012,5014,5016,5018,5020,5022],{"class":71,"line":534},[69,4999,941],{"class":83},[69,5001,680],{"class":75},[69,5003,4521],{"class":79},[69,5005,84],{"class":83},[69,5007,76],{"class":75},[69,5009,84],{"class":83},[69,5011,88],{"class":87},[69,5013,91],{"class":83},[69,5015,94],{"class":87},[69,5017,97],{"class":75},[69,5019,100],{"class":83},[69,5021,103],{"class":75},[69,5023,628],{"class":83},[69,5025,5026,5028,5030,5032],{"class":71,"line":541},[69,5027,634],{"class":75},[69,5029,112],{"class":83},[69,5031,115],{"class":75},[69,5033,972],{"class":83},[69,5035,5036,5038,5040,5042,5044],{"class":71,"line":547},[69,5037,2962],{"class":83},[69,5039,980],{"class":321},[69,5041,91],{"class":83},[69,5043,921],{"class":321},[69,5045,988],{"class":83},[127,5047,5048],{},"Декоратор можно применять встроенной анонимной функцией без предварительного присваивания.",[55,5050,5052],{"id":5051},"continuation-callbacks","Continuation (callbacks)",[60,5054,5056],{"className":62,"code":5055,"language":64,"meta":5,"style":5},"func divide(a, b int, onSuccess func(int), onError func(string)) {\n    if b == 0 {\n        onError(\"division by zero\")\n        return\n    }\n    onSuccess(a \u002F b)\n}\n\ndivide(10, 2,\n    func(r int) { fmt.Println(\"ok:\", r) },\n    func(e string) { fmt.Println(\"err:\", e) },\n)\n",[66,5057,5058,5100,5112,5123,5128,5132,5145,5149,5153,5169,5192,5215],{"__ignoreMap":5},[69,5059,5060,5062,5064,5066,5068,5070,5072,5074,5076,5079,5081,5083,5085,5088,5091,5093,5095,5097],{"class":71,"line":72},[69,5061,76],{"class":75},[69,5063,1516],{"class":79},[69,5065,84],{"class":83},[69,5067,88],{"class":87},[69,5069,91],{"class":83},[69,5071,94],{"class":87},[69,5073,97],{"class":75},[69,5075,91],{"class":83},[69,5077,5078],{"class":87},"onSuccess",[69,5080,505],{"class":75},[69,5082,84],{"class":83},[69,5084,103],{"class":75},[69,5086,5087],{"class":83},"), ",[69,5089,5090],{"class":87},"onError",[69,5092,505],{"class":75},[69,5094,84],{"class":83},[69,5096,358],{"class":75},[69,5098,5099],{"class":83},")) {\n",[69,5101,5102,5104,5106,5108,5110],{"class":71,"line":121},[69,5103,1555],{"class":75},[69,5105,1558],{"class":83},[69,5107,759],{"class":75},[69,5109,1563],{"class":321},[69,5111,628],{"class":83},[69,5113,5114,5117,5119,5121],{"class":71,"line":223},[69,5115,5116],{"class":79},"        onError",[69,5118,84],{"class":83},[69,5120,1583],{"class":175},[69,5122,988],{"class":83},[69,5124,5125],{"class":71,"line":534},[69,5126,5127],{"class":75},"        return\n",[69,5129,5130],{"class":71,"line":541},[69,5131,1085],{"class":83},[69,5133,5134,5137,5140,5142],{"class":71,"line":547},[69,5135,5136],{"class":79},"    onSuccess",[69,5138,5139],{"class":83},"(a ",[69,5141,1609],{"class":75},[69,5143,5144],{"class":83}," b)\n",[69,5146,5147],{"class":71,"line":590},[69,5148,663],{"class":83},[69,5150,5151],{"class":71,"line":595},[69,5152,538],{"emptyLinePlaceholder":537},[69,5154,5155,5158,5160,5162,5164,5166],{"class":71,"line":601},[69,5156,5157],{"class":79},"divide",[69,5159,84],{"class":83},[69,5161,3300],{"class":321},[69,5163,91],{"class":83},[69,5165,1115],{"class":321},[69,5167,5168],{"class":83},",\n",[69,5170,5171,5174,5176,5178,5180,5182,5184,5186,5189],{"class":71,"line":631},[69,5172,5173],{"class":75},"    func",[69,5175,84],{"class":83},[69,5177,3576],{"class":87},[69,5179,97],{"class":75},[69,5181,2486],{"class":83},[69,5183,753],{"class":79},[69,5185,84],{"class":83},[69,5187,5188],{"class":175},"\"ok:\"",[69,5190,5191],{"class":83},", r) },\n",[69,5193,5194,5196,5198,5201,5203,5205,5207,5209,5212],{"class":71,"line":660},[69,5195,5173],{"class":75},[69,5197,84],{"class":83},[69,5199,5200],{"class":87},"e",[69,5202,153],{"class":75},[69,5204,2486],{"class":83},[69,5206,753],{"class":79},[69,5208,84],{"class":83},[69,5210,5211],{"class":175},"\"err:\"",[69,5213,5214],{"class":83},", e) },\n",[69,5216,5217],{"class":71,"line":1767},[69,5218,988],{"class":83},[127,5220,5221],{},"Continuation (callback) — передача функций success\u002Ferror вместо возврата значения. Полезен для асинхронных сценариев, но ведёт к callback hell при злоупотреблении.",[47,5223],{},[11,5225,5226,5232,5238,5244],{},[14,5227,5228,5231],{},[18,5229,5230],{},"каррирование"," — преобразование f(a, b, c) в f(a)(b)(c): цепочка функций по одному аргументу",[14,5233,5234,5237],{},[18,5235,5236],{},"partial application"," — закрепить часть аргументов, получить специализированную функцию",[14,5239,5240,5243],{},[18,5241,5242],{},"ленивые вычисления"," — инициализация только при первом обращении (через замыкание + флаг)",[14,5245,5246],{},"используй в узких местах: логгер с секцией, конфиг с prefix, тяжёлая инициализация по требованию",[47,5248],{},[50,5250,5252],{"id":5251},"каррирование-и-ленивые-вычисления","Каррирование и ленивые вычисления",[55,5254,5255],{"id":5230},"Каррирование",[60,5257,5259],{"className":62,"code":5258,"language":64,"meta":5,"style":5},"func multiply(x int) func(int) int {\n    return func(y int) int {\n        return x * y  \u002F\u002F x замкнут\n    }\n}\n\n\u002F\u002F Полный вызов\nmultiply(10)(15)  \u002F\u002F 150\n\n\u002F\u002F Partial application — закрепляем первый аргумент\ntimes10 := multiply(10)\ntimes10(5)   \u002F\u002F 50\ntimes10(15)  \u002F\u002F 150\n",[66,5260,5261,5288,5306,5320,5324,5328,5332,5337,5357,5361,5366,5381,5395],{"__ignoreMap":5},[69,5262,5263,5265,5268,5270,5272,5274,5276,5278,5280,5282,5284,5286],{"class":71,"line":72},[69,5264,76],{"class":75},[69,5266,5267],{"class":79}," multiply",[69,5269,84],{"class":83},[69,5271,270],{"class":87},[69,5273,97],{"class":75},[69,5275,100],{"class":83},[69,5277,76],{"class":75},[69,5279,84],{"class":83},[69,5281,103],{"class":75},[69,5283,100],{"class":83},[69,5285,103],{"class":75},[69,5287,628],{"class":83},[69,5289,5290,5292,5294,5296,5298,5300,5302,5304],{"class":71,"line":121},[69,5291,634],{"class":75},[69,5293,505],{"class":75},[69,5295,84],{"class":83},[69,5297,275],{"class":87},[69,5299,97],{"class":75},[69,5301,100],{"class":83},[69,5303,103],{"class":75},[69,5305,628],{"class":83},[69,5307,5308,5310,5312,5314,5317],{"class":71,"line":223},[69,5309,1590],{"class":75},[69,5311,522],{"class":83},[69,5313,525],{"class":75},[69,5315,5316],{"class":83}," y  ",[69,5318,5319],{"class":124},"\u002F\u002F x замкнут\n",[69,5321,5322],{"class":71,"line":534},[69,5323,1085],{"class":83},[69,5325,5326],{"class":71,"line":541},[69,5327,663],{"class":83},[69,5329,5330],{"class":71,"line":547},[69,5331,538],{"emptyLinePlaceholder":537},[69,5333,5334],{"class":71,"line":590},[69,5335,5336],{"class":124},"\u002F\u002F Полный вызов\n",[69,5338,5339,5342,5344,5346,5349,5352,5354],{"class":71,"line":595},[69,5340,5341],{"class":79},"multiply",[69,5343,84],{"class":83},[69,5345,3300],{"class":321},[69,5347,5348],{"class":83},")(",[69,5350,5351],{"class":321},"15",[69,5353,1801],{"class":83},[69,5355,5356],{"class":124},"\u002F\u002F 150\n",[69,5358,5359],{"class":71,"line":601},[69,5360,538],{"emptyLinePlaceholder":537},[69,5362,5363],{"class":71,"line":631},[69,5364,5365],{"class":124},"\u002F\u002F Partial application — закрепляем первый аргумент\n",[69,5367,5368,5371,5373,5375,5377,5379],{"class":71,"line":660},[69,5369,5370],{"class":83},"times10 ",[69,5372,680],{"class":75},[69,5374,5267],{"class":79},[69,5376,84],{"class":83},[69,5378,3300],{"class":321},[69,5380,988],{"class":83},[69,5382,5383,5386,5388,5390,5392],{"class":71,"line":1767},[69,5384,5385],{"class":79},"times10",[69,5387,84],{"class":83},[69,5389,921],{"class":321},[69,5391,1322],{"class":83},[69,5393,5394],{"class":124},"\u002F\u002F 50\n",[69,5396,5397,5399,5401,5403,5405],{"class":71,"line":1780},[69,5398,5385],{"class":79},[69,5400,84],{"class":83},[69,5402,5351],{"class":321},[69,5404,1801],{"class":83},[69,5406,5356],{"class":124},[127,5408,5409],{},"Каррирование в Go — это функция, возвращающая функцию. Аргументы фиксируются через замыкание.",[55,5411,5413],{"id":5412},"практический-пример-логгер","Практический пример: логгер",[60,5415,5417],{"className":62,"code":5416,"language":64,"meta":5,"style":5},"func logger(section string) func(string, string) {\n    return func(level, message string) {\n        fmt.Printf(\"[%s] %s: %s\\n\", section, level, message)\n    }\n}\n\nrepoLog := logger(\"repository\")   \u002F\u002F секция закреплена\nrepoLog(\"INFO\", \"query executed\")  \u002F\u002F [repository] INFO: query executed\nrepoLog(\"ERROR\", \"connection lost\") \u002F\u002F [repository] ERROR: connection lost\n\nbizLog := logger(\"business\")\nbizLog(\"INFO\", \"order created\")    \u002F\u002F [business] INFO: order created\n",[66,5418,5419,5447,5467,5497,5501,5505,5509,5528,5548,5567,5571,5587],{"__ignoreMap":5},[69,5420,5421,5423,5426,5428,5431,5433,5435,5437,5439,5441,5443,5445],{"class":71,"line":72},[69,5422,76],{"class":75},[69,5424,5425],{"class":79}," logger",[69,5427,84],{"class":83},[69,5429,5430],{"class":87},"section",[69,5432,153],{"class":75},[69,5434,100],{"class":83},[69,5436,76],{"class":75},[69,5438,84],{"class":83},[69,5440,358],{"class":75},[69,5442,91],{"class":83},[69,5444,358],{"class":75},[69,5446,1274],{"class":83},[69,5448,5449,5451,5453,5455,5458,5460,5463,5465],{"class":71,"line":121},[69,5450,634],{"class":75},[69,5452,505],{"class":75},[69,5454,84],{"class":83},[69,5456,5457],{"class":87},"level",[69,5459,91],{"class":83},[69,5461,5462],{"class":87},"message",[69,5464,153],{"class":75},[69,5466,1274],{"class":83},[69,5468,5469,5472,5474,5476,5479,5482,5484,5486,5489,5492,5494],{"class":71,"line":223},[69,5470,5471],{"class":83},"        fmt.",[69,5473,4551],{"class":79},[69,5475,84],{"class":83},[69,5477,5478],{"class":175},"\"[",[69,5480,5481],{"class":321},"%s",[69,5483,325],{"class":175},[69,5485,5481],{"class":321},[69,5487,5488],{"class":175},": ",[69,5490,5491],{"class":321},"%s\\n",[69,5493,4567],{"class":175},[69,5495,5496],{"class":83},", section, level, message)\n",[69,5498,5499],{"class":71,"line":534},[69,5500,1085],{"class":83},[69,5502,5503],{"class":71,"line":541},[69,5504,663],{"class":83},[69,5506,5507],{"class":71,"line":547},[69,5508,538],{"emptyLinePlaceholder":537},[69,5510,5511,5514,5516,5518,5520,5523,5525],{"class":71,"line":590},[69,5512,5513],{"class":83},"repoLog ",[69,5515,680],{"class":75},[69,5517,5425],{"class":79},[69,5519,84],{"class":83},[69,5521,5522],{"class":175},"\"repository\"",[69,5524,1322],{"class":83},[69,5526,5527],{"class":124},"\u002F\u002F секция закреплена\n",[69,5529,5530,5533,5535,5538,5540,5543,5545],{"class":71,"line":595},[69,5531,5532],{"class":79},"repoLog",[69,5534,84],{"class":83},[69,5536,5537],{"class":175},"\"INFO\"",[69,5539,91],{"class":83},[69,5541,5542],{"class":175},"\"query executed\"",[69,5544,1801],{"class":83},[69,5546,5547],{"class":124},"\u002F\u002F [repository] INFO: query executed\n",[69,5549,5550,5552,5554,5557,5559,5562,5564],{"class":71,"line":601},[69,5551,5532],{"class":79},[69,5553,84],{"class":83},[69,5555,5556],{"class":175},"\"ERROR\"",[69,5558,91],{"class":83},[69,5560,5561],{"class":175},"\"connection lost\"",[69,5563,100],{"class":83},[69,5565,5566],{"class":124},"\u002F\u002F [repository] ERROR: connection lost\n",[69,5568,5569],{"class":71,"line":631},[69,5570,538],{"emptyLinePlaceholder":537},[69,5572,5573,5576,5578,5580,5582,5585],{"class":71,"line":660},[69,5574,5575],{"class":83},"bizLog ",[69,5577,680],{"class":75},[69,5579,5425],{"class":79},[69,5581,84],{"class":83},[69,5583,5584],{"class":175},"\"business\"",[69,5586,988],{"class":83},[69,5588,5589,5592,5594,5596,5598,5601,5604],{"class":71,"line":1767},[69,5590,5591],{"class":79},"bizLog",[69,5593,84],{"class":83},[69,5595,5537],{"class":175},[69,5597,91],{"class":83},[69,5599,5600],{"class":175},"\"order created\"",[69,5602,5603],{"class":83},")    ",[69,5605,5606],{"class":124},"\u002F\u002F [business] INFO: order created\n",[127,5608,5609,5610,5612],{},"Partial application позволяет не передавать ",[66,5611,5430],{}," каждый раз — он зафиксирован в замыкании.",[55,5614,5616],{"id":5615},"ленивые-вычисления","Ленивые вычисления",[60,5618,5620],{"className":62,"code":5619,"language":64,"meta":5,"style":5},"type LazyMap func() map[string]string\n\nfunc MakeLazy(init func() map[string]string) LazyMap {\n    var data map[string]string\n    var initialized bool\n\n    return func() map[string]string {\n        if !initialized {\n            data = init()          \u002F\u002F тяжёлая инициализация — один раз\n            initialized = true\n            init = nil             \u002F\u002F отпускаем init для GC\n        }\n        return data\n    }\n}\n\nconfig := MakeLazy(func() map[string]string {\n    \u002F\u002F дорогая операция: чтение файла, поход в сеть...\n    return map[string]string{\"host\": \"localhost\", \"port\": \"8080\"}\n})\n\n\u002F\u002F Пока не вызвали config() — память не выделена\n\u002F\u002F Первый вызов: инициализация\n\u002F\u002F Второй+ вызов: возврат готовой map\n",[66,5621,5622,5645,5649,5681,5698,5708,5712,5732,5742,5757,5767,5779,5783,5790,5794,5798,5802,5829,5834,5871,5876,5881,5887,5893],{"__ignoreMap":5},[69,5623,5624,5626,5629,5631,5633,5636,5638,5640,5642],{"class":71,"line":72},[69,5625,4493],{"class":75},[69,5627,5628],{"class":79}," LazyMap",[69,5630,505],{"class":75},[69,5632,1986],{"class":83},[69,5634,5635],{"class":75},"map",[69,5637,355],{"class":83},[69,5639,358],{"class":75},[69,5641,361],{"class":83},[69,5643,5644],{"class":75},"string\n",[69,5646,5647],{"class":71,"line":121},[69,5648,538],{"emptyLinePlaceholder":537},[69,5650,5651,5653,5656,5658,5660,5662,5664,5666,5668,5670,5672,5674,5676,5679],{"class":71,"line":223},[69,5652,76],{"class":75},[69,5654,5655],{"class":79}," MakeLazy",[69,5657,84],{"class":83},[69,5659,809],{"class":87},[69,5661,505],{"class":75},[69,5663,1986],{"class":83},[69,5665,5635],{"class":75},[69,5667,355],{"class":83},[69,5669,358],{"class":75},[69,5671,361],{"class":83},[69,5673,358],{"class":75},[69,5675,100],{"class":83},[69,5677,5678],{"class":79},"LazyMap",[69,5680,628],{"class":83},[69,5682,5683,5685,5688,5690,5692,5694,5696],{"class":71,"line":534},[69,5684,4280],{"class":75},[69,5686,5687],{"class":83}," data ",[69,5689,5635],{"class":75},[69,5691,355],{"class":83},[69,5693,358],{"class":75},[69,5695,361],{"class":83},[69,5697,5644],{"class":75},[69,5699,5700,5702,5705],{"class":71,"line":541},[69,5701,4280],{"class":75},[69,5703,5704],{"class":83}," initialized ",[69,5706,5707],{"class":75},"bool\n",[69,5709,5710],{"class":71,"line":547},[69,5711,538],{"emptyLinePlaceholder":537},[69,5713,5714,5716,5718,5720,5722,5724,5726,5728,5730],{"class":71,"line":590},[69,5715,634],{"class":75},[69,5717,505],{"class":75},[69,5719,1986],{"class":83},[69,5721,5635],{"class":75},[69,5723,355],{"class":83},[69,5725,358],{"class":75},[69,5727,361],{"class":83},[69,5729,358],{"class":75},[69,5731,628],{"class":83},[69,5733,5734,5736,5739],{"class":71,"line":595},[69,5735,4326],{"class":75},[69,5737,5738],{"class":75}," !",[69,5740,5741],{"class":83},"initialized {\n",[69,5743,5744,5747,5749,5751,5754],{"class":71,"line":601},[69,5745,5746],{"class":83},"            data ",[69,5748,328],{"class":75},[69,5750,3920],{"class":79},[69,5752,5753],{"class":83},"()          ",[69,5755,5756],{"class":124},"\u002F\u002F тяжёлая инициализация — один раз\n",[69,5758,5759,5762,5764],{"class":71,"line":631},[69,5760,5761],{"class":83},"            initialized ",[69,5763,328],{"class":75},[69,5765,5766],{"class":321}," true\n",[69,5768,5769,5772,5774,5776],{"class":71,"line":660},[69,5770,5771],{"class":83},"            init ",[69,5773,328],{"class":75},[69,5775,762],{"class":321},[69,5777,5778],{"class":124},"             \u002F\u002F отпускаем init для GC\n",[69,5780,5781],{"class":71,"line":1767},[69,5782,2698],{"class":83},[69,5784,5785,5787],{"class":71,"line":1780},[69,5786,1590],{"class":75},[69,5788,5789],{"class":83}," data\n",[69,5791,5792],{"class":71,"line":1807},[69,5793,1085],{"class":83},[69,5795,5796],{"class":71,"line":1812},[69,5797,663],{"class":83},[69,5799,5800],{"class":71,"line":1825},[69,5801,538],{"emptyLinePlaceholder":537},[69,5803,5804,5807,5809,5811,5813,5815,5817,5819,5821,5823,5825,5827],{"class":71,"line":2773},[69,5805,5806],{"class":83},"config ",[69,5808,680],{"class":75},[69,5810,5655],{"class":79},[69,5812,84],{"class":83},[69,5814,76],{"class":75},[69,5816,1986],{"class":83},[69,5818,5635],{"class":75},[69,5820,355],{"class":83},[69,5822,358],{"class":75},[69,5824,361],{"class":83},[69,5826,358],{"class":75},[69,5828,628],{"class":83},[69,5830,5831],{"class":71,"line":2779},[69,5832,5833],{"class":124},"    \u002F\u002F дорогая операция: чтение файла, поход в сеть...\n",[69,5835,5837,5839,5841,5843,5845,5847,5849,5851,5854,5856,5859,5861,5864,5866,5869],{"class":71,"line":5836},19,[69,5838,634],{"class":75},[69,5840,352],{"class":75},[69,5842,355],{"class":83},[69,5844,358],{"class":75},[69,5846,361],{"class":83},[69,5848,358],{"class":75},[69,5850,2945],{"class":83},[69,5852,5853],{"class":175},"\"host\"",[69,5855,5488],{"class":83},[69,5857,5858],{"class":175},"\"localhost\"",[69,5860,91],{"class":83},[69,5862,5863],{"class":175},"\"port\"",[69,5865,5488],{"class":83},[69,5867,5868],{"class":175},"\"8080\"",[69,5870,663],{"class":83},[69,5872,5874],{"class":71,"line":5873},20,[69,5875,2992],{"class":83},[69,5877,5879],{"class":71,"line":5878},21,[69,5880,538],{"emptyLinePlaceholder":537},[69,5882,5884],{"class":71,"line":5883},22,[69,5885,5886],{"class":124},"\u002F\u002F Пока не вызвали config() — память не выделена\n",[69,5888,5890],{"class":71,"line":5889},23,[69,5891,5892],{"class":124},"\u002F\u002F Первый вызов: инициализация\n",[69,5894,5896],{"class":71,"line":5895},24,[69,5897,5898],{"class":124},"\u002F\u002F Второй+ вызов: возврат готовой map\n",[127,5900,5901,5902,91,5905,91,5908,5910],{},"Замыкание хранит ",[66,5903,5904],{},"data",[66,5906,5907],{},"initialized",[66,5909,809],{}," — всё в heap.",[127,5912,5913,5919,5920,5922],{},[18,5914,5915,5916,2355],{},"Зачем ",[66,5917,5918],{},"init = nil"," После инициализации функция ",[66,5921,809],{}," больше не нужна. Обнуление позволяет GC собрать её и всё что она удерживает (например, конфиги, соединения, буферы).",[47,5924],{},[50,5926,5928],{"id":5927},"практика","Практика",[5930,5931,5933,5943,6036,6053],"quiz",{"answer":980,"id":5932,"xp":3300},"funcs-functions-q1",[127,5934,5935,5936,5939,5940,2355],{},"Что выведут три вызова ",[66,5937,5938],{},"gen()"," после ",[66,5941,5942],{},"gen := generator(10)",[60,5944,5946],{"className":62,"code":5945,"language":64,"meta":5,"style":5},"func generator(start int) func() int {\n    n := start\n    return func() int {\n        r := n\n        n++\n        return r\n    }\n}\ngen := generator(10)\n",[66,5947,5948,5970,5980,5992,6000,6008,6014,6018,6022],{"__ignoreMap":5},[69,5949,5950,5952,5954,5956,5958,5960,5962,5964,5966,5968],{"class":71,"line":72},[69,5951,76],{"class":75},[69,5953,1972],{"class":79},[69,5955,84],{"class":83},[69,5957,1977],{"class":87},[69,5959,97],{"class":75},[69,5961,100],{"class":83},[69,5963,76],{"class":75},[69,5965,1986],{"class":83},[69,5967,103],{"class":75},[69,5969,628],{"class":83},[69,5971,5972,5975,5977],{"class":71,"line":121},[69,5973,5974],{"class":83},"    n ",[69,5976,680],{"class":75},[69,5978,5979],{"class":83}," start\n",[69,5981,5982,5984,5986,5988,5990],{"class":71,"line":223},[69,5983,634],{"class":75},[69,5985,505],{"class":75},[69,5987,1986],{"class":83},[69,5989,103],{"class":75},[69,5991,628],{"class":83},[69,5993,5994,5996,5998],{"class":71,"line":534},[69,5995,2024],{"class":83},[69,5997,680],{"class":75},[69,5999,1080],{"class":83},[69,6001,6002,6005],{"class":71,"line":541},[69,6003,6004],{"class":83},"        n",[69,6006,6007],{"class":75},"++\n",[69,6009,6010,6012],{"class":71,"line":547},[69,6011,1590],{"class":75},[69,6013,2046],{"class":83},[69,6015,6016],{"class":71,"line":590},[69,6017,1085],{"class":83},[69,6019,6020],{"class":71,"line":595},[69,6021,663],{"class":83},[69,6023,6024,6026,6028,6030,6032,6034],{"class":71,"line":601},[69,6025,2063],{"class":83},[69,6027,680],{"class":75},[69,6029,1972],{"class":79},[69,6031,84],{"class":83},[69,6033,3300],{"class":321},[69,6035,988],{"class":83},[6037,6038,6039],"template",{"v-slot:options":5},[11,6040,6041,6044,6047,6050],{},[14,6042,6043],{},"10, 10, 10",[14,6045,6046],{},"11, 12, 13",[14,6048,6049],{},"10, 11, 12",[14,6051,6052],{},"0, 1, 2",[6037,6054,6055],{"v-slot:explanation":5},[127,6056,6057,6058,433,6061,6063,6064,6066,6067,6069,6070,6072],{},"Замыкание ",[18,6059,6060],{},"захватывает переменную",[66,6062,611],{}," по ссылке, а не по значению. При каждом вызове ",[66,6065,5938],{}," значение ",[66,6068,611],{}," инкрементируется. Первый вызов — ",[66,6071,611],{}," равен 10, возвращает 10, потом инкрементирует до 11. Второй — возвращает 11, и т.д.",[6074,6075,6078,6081,6259],"predict",{"answer":6076,"id":6077,"xp":5351},"3 3 3","funcs-functions-p1",[127,6079,6080],{},"Что выведет этот код? Объясни почему.",[6037,6082,6083],{"v-slot:code":5},[60,6084,6086],{"className":62,"code":6085,"language":64,"meta":5,"style":5},"package main\n\nimport \"fmt\"\n\nfunc main() {\n    funcs := make([]func() int, 0, 3)\n    var i int\n    for i = 0; i \u003C 3; i++ {\n        funcs = append(funcs, func() int { return i })\n    }\n\n    fmt.Println(funcs[0](), funcs[1](), funcs[2]())\n}\n",[66,6087,6088,6096,6100,6114,6118,6128,6155,6163,6186,6212,6216,6220,6255],{"__ignoreMap":5},[69,6089,6090,6093],{"class":71,"line":72},[69,6091,6092],{"class":75},"package",[69,6094,6095],{"class":79}," main\n",[69,6097,6098],{"class":71,"line":121},[69,6099,538],{"emptyLinePlaceholder":537},[69,6101,6102,6105,6108,6111],{"class":71,"line":223},[69,6103,6104],{"class":75},"import",[69,6106,6107],{"class":175}," \"",[69,6109,6110],{"class":79},"fmt",[69,6112,6113],{"class":175},"\"\n",[69,6115,6116],{"class":71,"line":534},[69,6117,538],{"emptyLinePlaceholder":537},[69,6119,6120,6122,6125],{"class":71,"line":541},[69,6121,76],{"class":75},[69,6123,6124],{"class":79}," main",[69,6126,6127],{"class":83},"() {\n",[69,6129,6130,6133,6135,6137,6139,6141,6143,6145,6147,6149,6151,6153],{"class":71,"line":547},[69,6131,6132],{"class":83},"    funcs ",[69,6134,680],{"class":75},[69,6136,2868],{"class":79},[69,6138,1851],{"class":83},[69,6140,76],{"class":75},[69,6142,1986],{"class":83},[69,6144,103],{"class":75},[69,6146,91],{"class":83},[69,6148,322],{"class":321},[69,6150,91],{"class":83},[69,6152,980],{"class":321},[69,6154,988],{"class":83},[69,6156,6157,6159,6161],{"class":71,"line":590},[69,6158,4280],{"class":75},[69,6160,2389],{"class":83},[69,6162,495],{"class":75},[69,6164,6165,6167,6169,6171,6173,6175,6177,6180,6182,6184],{"class":71,"line":595},[69,6166,1058],{"class":75},[69,6168,2389],{"class":83},[69,6170,328],{"class":75},[69,6172,1563],{"class":321},[69,6174,2405],{"class":83},[69,6176,2408],{"class":75},[69,6178,6179],{"class":321}," 3",[69,6181,2414],{"class":83},[69,6183,401],{"class":75},[69,6185,628],{"class":83},[69,6187,6188,6191,6193,6196,6199,6201,6203,6205,6207,6209],{"class":71,"line":601},[69,6189,6190],{"class":83},"        funcs ",[69,6192,328],{"class":75},[69,6194,6195],{"class":79}," append",[69,6197,6198],{"class":83},"(funcs, ",[69,6200,76],{"class":75},[69,6202,1986],{"class":83},[69,6204,103],{"class":75},[69,6206,106],{"class":83},[69,6208,109],{"class":75},[69,6210,6211],{"class":83}," i })\n",[69,6213,6214],{"class":71,"line":631},[69,6215,1085],{"class":83},[69,6217,6218],{"class":71,"line":660},[69,6219,538],{"emptyLinePlaceholder":537},[69,6221,6222,6224,6226,6228,6231,6233,6235,6238,6240,6242,6244,6246,6248,6250,6252],{"class":71,"line":1767},[69,6223,1279],{"class":83},[69,6225,753],{"class":79},[69,6227,84],{"class":83},[69,6229,6230],{"class":79},"funcs",[69,6232,355],{"class":83},[69,6234,322],{"class":321},[69,6236,6237],{"class":83},"](), ",[69,6239,6230],{"class":79},[69,6241,355],{"class":83},[69,6243,1110],{"class":321},[69,6245,6237],{"class":83},[69,6247,6230],{"class":79},[69,6249,355],{"class":83},[69,6251,1115],{"class":321},[69,6253,6254],{"class":83},"]())\n",[69,6256,6257],{"class":71,"line":1780},[69,6258,663],{"class":83},[6037,6260,6261],{"v-slot:hint":5},[127,6262,6263,6265],{},[66,6264,2507],{}," объявлена снаружи цикла, поэтому все замыкания захватывают одну и ту же переменную. После цикла её значение равно 3.",[6267,6268,6272,6275,6493],"code-fix",{"expected":6269,"id":6270,"xp":6271},"100\\n101\\n102","funcs-functions-cf1","25",[127,6273,6274],{},"Исправь код: замыкание должно запоминать значение переменной в момент вызова, а не захватывать её по ссылке.",[6037,6276,6277],{"v-slot:code":5},[60,6278,6280],{"className":62,"code":6279,"language":64,"meta":5,"style":5},"package main\n\nimport \"fmt\"\n\nfunc makeAdders() []func() int {\n    adders := make([]func() int, 3)\n    var i int\n    for i = 0; i \u003C 3; i++ {\n        adders[i] = func() int { return 100 + i }\n    }\n    return adders\n}\n\nfunc main() {\n    adders := makeAdders()\n    fmt.Println(adders[0]())\n    fmt.Println(adders[1]())\n    fmt.Println(adders[2]())\n}\n",[66,6281,6282,6288,6292,6302,6306,6324,6347,6355,6377,6403,6407,6414,6418,6422,6430,6440,6457,6473,6489],{"__ignoreMap":5},[69,6283,6284,6286],{"class":71,"line":72},[69,6285,6092],{"class":75},[69,6287,6095],{"class":79},[69,6289,6290],{"class":71,"line":121},[69,6291,538],{"emptyLinePlaceholder":537},[69,6293,6294,6296,6298,6300],{"class":71,"line":223},[69,6295,6104],{"class":75},[69,6297,6107],{"class":175},[69,6299,6110],{"class":79},[69,6301,6113],{"class":175},[69,6303,6304],{"class":71,"line":534},[69,6305,538],{"emptyLinePlaceholder":537},[69,6307,6308,6310,6313,6316,6318,6320,6322],{"class":71,"line":541},[69,6309,76],{"class":75},[69,6311,6312],{"class":79}," makeAdders",[69,6314,6315],{"class":83},"() []",[69,6317,76],{"class":75},[69,6319,1986],{"class":83},[69,6321,103],{"class":75},[69,6323,628],{"class":83},[69,6325,6326,6329,6331,6333,6335,6337,6339,6341,6343,6345],{"class":71,"line":547},[69,6327,6328],{"class":83},"    adders ",[69,6330,680],{"class":75},[69,6332,2868],{"class":79},[69,6334,1851],{"class":83},[69,6336,76],{"class":75},[69,6338,1986],{"class":83},[69,6340,103],{"class":75},[69,6342,91],{"class":83},[69,6344,980],{"class":321},[69,6346,988],{"class":83},[69,6348,6349,6351,6353],{"class":71,"line":590},[69,6350,4280],{"class":75},[69,6352,2389],{"class":83},[69,6354,495],{"class":75},[69,6356,6357,6359,6361,6363,6365,6367,6369,6371,6373,6375],{"class":71,"line":595},[69,6358,1058],{"class":75},[69,6360,2389],{"class":83},[69,6362,328],{"class":75},[69,6364,1563],{"class":321},[69,6366,2405],{"class":83},[69,6368,2408],{"class":75},[69,6370,6179],{"class":321},[69,6372,2414],{"class":83},[69,6374,401],{"class":75},[69,6376,628],{"class":83},[69,6378,6379,6382,6384,6386,6388,6390,6392,6394,6397,6400],{"class":71,"line":601},[69,6380,6381],{"class":83},"        adders[i] ",[69,6383,328],{"class":75},[69,6385,505],{"class":75},[69,6387,1986],{"class":83},[69,6389,103],{"class":75},[69,6391,106],{"class":83},[69,6393,109],{"class":75},[69,6395,6396],{"class":321}," 100",[69,6398,6399],{"class":75}," +",[69,6401,6402],{"class":83}," i }\n",[69,6404,6405],{"class":71,"line":631},[69,6406,1085],{"class":83},[69,6408,6409,6411],{"class":71,"line":660},[69,6410,634],{"class":75},[69,6412,6413],{"class":83}," adders\n",[69,6415,6416],{"class":71,"line":1767},[69,6417,663],{"class":83},[69,6419,6420],{"class":71,"line":1780},[69,6421,538],{"emptyLinePlaceholder":537},[69,6423,6424,6426,6428],{"class":71,"line":1807},[69,6425,76],{"class":75},[69,6427,6124],{"class":79},[69,6429,6127],{"class":83},[69,6431,6432,6434,6436,6438],{"class":71,"line":1812},[69,6433,6328],{"class":83},[69,6435,680],{"class":75},[69,6437,6312],{"class":79},[69,6439,3465],{"class":83},[69,6441,6442,6444,6446,6448,6451,6453,6455],{"class":71,"line":1825},[69,6443,1279],{"class":83},[69,6445,753],{"class":79},[69,6447,84],{"class":83},[69,6449,6450],{"class":79},"adders",[69,6452,355],{"class":83},[69,6454,322],{"class":321},[69,6456,6254],{"class":83},[69,6458,6459,6461,6463,6465,6467,6469,6471],{"class":71,"line":2773},[69,6460,1279],{"class":83},[69,6462,753],{"class":79},[69,6464,84],{"class":83},[69,6466,6450],{"class":79},[69,6468,355],{"class":83},[69,6470,1110],{"class":321},[69,6472,6254],{"class":83},[69,6474,6475,6477,6479,6481,6483,6485,6487],{"class":71,"line":2779},[69,6476,1279],{"class":83},[69,6478,753],{"class":79},[69,6480,84],{"class":83},[69,6482,6450],{"class":79},[69,6484,355],{"class":83},[69,6486,1115],{"class":321},[69,6488,6254],{"class":83},[69,6490,6491],{"class":71,"line":5836},[69,6492,663],{"class":83},[6037,6494,6495],{"v-slot:hints":5},[11,6496,6497,6503,6512],{},[14,6498,6499,6500,6502],{},"Все три функции захватывают одну переменную ",[66,6501,2507],{}," — после цикла она равна 3, поэтому все возвращают 103",[14,6504,6505,6506,6508,6509],{},"Зафиксируй значение ",[66,6507,2507],{}," через параметр: ",[66,6510,6511],{},"func(n int) func() int { return func() int { return 100 + n } }(i)",[14,6513,6514,6515,6518,6519],{},"Или объяви локальную копию внутри цикла: ",[66,6516,6517],{},"j := i"," и замыкай ",[66,6520,6521],{},"j",[6523,6524,6528,6553,6778],"code-task",{"expected":6525,"id":6526,"xp":6527},"8\\n14","funcs-functions-ct1","20",[127,6529,6530,6531,6534,6535,6537,6538,6541,6542,6545,6546,1947,6548,5488,6550,1144],{},"Реализуй функцию ",[66,6532,6533],{},"compose",", которая принимает две функции ",[66,6536,557],{}," и ",[66,6539,6540],{},"g"," (обе типа ",[66,6543,6544],{},"func(int) int",") и возвращает новую функцию, которая применяет сначала ",[66,6547,6540],{},[66,6549,557],{},[66,6551,6552],{},"f(g(x))",[6037,6554,6555],{"v-slot:template":5},[60,6556,6558],{"className":62,"code":6557,"language":64,"meta":5,"style":5},"package main\n\nimport \"fmt\"\n\nfunc compose(f, g func(int) int) func(int) int {\n    \u002F\u002F твой код здесь\n    return nil \u002F\u002F TODO: реализуй f(g(x))\n}\n\nfunc main() {\n    double := func(x int) int { return x * 2 }\n    addOne := func(x int) int { return x + 1 }\n\n    doubleAfterAdd := compose(double, addOne) \u002F\u002F double(addOne(x))\n    fmt.Println(doubleAfterAdd(3))            \u002F\u002F double(addOne(3)) = double(4) = 8\n    fmt.Println(doubleAfterAdd(6))            \u002F\u002F double(addOne(6)) = double(7) = 14\n}\n",[66,6559,6560,6566,6570,6580,6584,6622,6627,6636,6640,6644,6652,6683,6714,6718,6733,6754,6774],{"__ignoreMap":5},[69,6561,6562,6564],{"class":71,"line":72},[69,6563,6092],{"class":75},[69,6565,6095],{"class":79},[69,6567,6568],{"class":71,"line":121},[69,6569,538],{"emptyLinePlaceholder":537},[69,6571,6572,6574,6576,6578],{"class":71,"line":223},[69,6573,6104],{"class":75},[69,6575,6107],{"class":175},[69,6577,6110],{"class":79},[69,6579,6113],{"class":175},[69,6581,6582],{"class":71,"line":534},[69,6583,538],{"emptyLinePlaceholder":537},[69,6585,6586,6588,6590,6592,6594,6596,6598,6600,6602,6604,6606,6608,6610,6612,6614,6616,6618,6620],{"class":71,"line":541},[69,6587,76],{"class":75},[69,6589,4747],{"class":79},[69,6591,84],{"class":83},[69,6593,557],{"class":87},[69,6595,91],{"class":83},[69,6597,6540],{"class":87},[69,6599,505],{"class":75},[69,6601,84],{"class":83},[69,6603,103],{"class":75},[69,6605,100],{"class":83},[69,6607,103],{"class":75},[69,6609,100],{"class":83},[69,6611,76],{"class":75},[69,6613,84],{"class":83},[69,6615,103],{"class":75},[69,6617,100],{"class":83},[69,6619,103],{"class":75},[69,6621,628],{"class":83},[69,6623,6624],{"class":71,"line":547},[69,6625,6626],{"class":124},"    \u002F\u002F твой код здесь\n",[69,6628,6629,6631,6633],{"class":71,"line":590},[69,6630,634],{"class":75},[69,6632,762],{"class":321},[69,6634,6635],{"class":124}," \u002F\u002F TODO: реализуй f(g(x))\n",[69,6637,6638],{"class":71,"line":595},[69,6639,663],{"class":83},[69,6641,6642],{"class":71,"line":601},[69,6643,538],{"emptyLinePlaceholder":537},[69,6645,6646,6648,6650],{"class":71,"line":631},[69,6647,76],{"class":75},[69,6649,6124],{"class":79},[69,6651,6127],{"class":83},[69,6653,6654,6657,6659,6661,6663,6665,6667,6669,6671,6673,6675,6677,6679,6681],{"class":71,"line":660},[69,6655,6656],{"class":83},"    double ",[69,6658,680],{"class":75},[69,6660,505],{"class":75},[69,6662,84],{"class":83},[69,6664,270],{"class":87},[69,6666,97],{"class":75},[69,6668,100],{"class":83},[69,6670,103],{"class":75},[69,6672,106],{"class":83},[69,6674,109],{"class":75},[69,6676,522],{"class":83},[69,6678,525],{"class":75},[69,6680,528],{"class":321},[69,6682,531],{"class":83},[69,6684,6685,6688,6690,6692,6694,6696,6698,6700,6702,6704,6706,6708,6710,6712],{"class":71,"line":1767},[69,6686,6687],{"class":83},"    addOne ",[69,6689,680],{"class":75},[69,6691,505],{"class":75},[69,6693,84],{"class":83},[69,6695,270],{"class":87},[69,6697,97],{"class":75},[69,6699,100],{"class":83},[69,6701,103],{"class":75},[69,6703,106],{"class":83},[69,6705,109],{"class":75},[69,6707,522],{"class":83},[69,6709,115],{"class":75},[69,6711,376],{"class":321},[69,6713,531],{"class":83},[69,6715,6716],{"class":71,"line":1780},[69,6717,538],{"emptyLinePlaceholder":537},[69,6719,6720,6723,6725,6727,6730],{"class":71,"line":1807},[69,6721,6722],{"class":83},"    doubleAfterAdd ",[69,6724,680],{"class":75},[69,6726,4747],{"class":79},[69,6728,6729],{"class":83},"(double, addOne) ",[69,6731,6732],{"class":124},"\u002F\u002F double(addOne(x))\n",[69,6734,6735,6737,6739,6741,6744,6746,6748,6751],{"class":71,"line":1812},[69,6736,1279],{"class":83},[69,6738,753],{"class":79},[69,6740,84],{"class":83},[69,6742,6743],{"class":79},"doubleAfterAdd",[69,6745,84],{"class":83},[69,6747,980],{"class":321},[69,6749,6750],{"class":83},"))            ",[69,6752,6753],{"class":124},"\u002F\u002F double(addOne(3)) = double(4) = 8\n",[69,6755,6756,6758,6760,6762,6764,6766,6769,6771],{"class":71,"line":1825},[69,6757,1279],{"class":83},[69,6759,753],{"class":79},[69,6761,84],{"class":83},[69,6763,6743],{"class":79},[69,6765,84],{"class":83},[69,6767,6768],{"class":321},"6",[69,6770,6750],{"class":83},[69,6772,6773],{"class":124},"\u002F\u002F double(addOne(6)) = double(7) = 14\n",[69,6775,6776],{"class":71,"line":2773},[69,6777,663],{"class":83},[6037,6779,6780],{"v-slot:hints":5},[11,6781,6782,6791],{},[14,6783,6784,6787,6788],{},[66,6785,6786],{},"compose(f, g)"," должна вернуть ",[66,6789,6790],{},"func(x int) int { return f(g(x)) }",[14,6792,6793,6794,6537,6796,6798],{},"Замыкание захватывает ",[66,6795,557],{},[66,6797,6540],{}," из параметров — это безопасно",[6800,6801,6802],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}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 pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}",{"title":5,"searchDepth":121,"depth":121,"links":6804},[6805,6812,6818,6824,6830,6836,6841,6848,6855,6861,6867,6872],{"id":52,"depth":121,"text":53,"children":6806},[6807,6808,6809,6810,6811],{"id":57,"depth":223,"text":58},{"id":132,"depth":223,"text":133},{"id":185,"depth":223,"text":186},{"id":229,"depth":223,"text":230},{"id":292,"depth":223,"text":293},{"id":461,"depth":121,"text":462,"children":6813},[6814,6815,6816,6817],{"id":465,"depth":223,"text":466},{"id":666,"depth":223,"text":667},{"id":723,"depth":223,"text":724},{"id":781,"depth":223,"text":782},{"id":859,"depth":121,"text":860,"children":6819},[6820,6821,6822,6823],{"id":863,"depth":223,"text":864},{"id":1013,"depth":223,"text":1014},{"id":1147,"depth":223,"text":1148},{"id":1250,"depth":223,"text":1251},{"id":1397,"depth":121,"text":1398,"children":6825},[6826,6827,6828,6829],{"id":1401,"depth":223,"text":1402},{"id":1503,"depth":223,"text":1504},{"id":1638,"depth":223,"text":1639},{"id":1830,"depth":223,"text":1831},{"id":1955,"depth":121,"text":1956,"children":6831},[6832,6833,6834,6835],{"id":1959,"depth":223,"text":1960},{"id":2128,"depth":223,"text":2129},{"id":2225,"depth":223,"text":2226},{"id":2370,"depth":223,"text":2371},{"id":2545,"depth":121,"text":2546,"children":6837},[6838,6839,6840],{"id":2549,"depth":223,"text":2550},{"id":2816,"depth":223,"text":2817},{"id":3012,"depth":223,"text":3013},{"id":3181,"depth":121,"text":3182,"children":6842},[6843,6844,6845,6846,6847],{"id":3185,"depth":223,"text":3186},{"id":3358,"depth":223,"text":3359},{"id":3414,"depth":223,"text":3415},{"id":3553,"depth":223,"text":3554},{"id":3619,"depth":223,"text":3620},{"id":3659,"depth":121,"text":3660,"children":6849},[6850,6851,6852,6853,6854],{"id":3663,"depth":223,"text":3664},{"id":3741,"depth":223,"text":3742},{"id":3795,"depth":223,"text":3796},{"id":3650,"depth":223,"text":3868},{"id":809,"depth":223,"text":3733},{"id":4007,"depth":121,"text":4008,"children":6856},[6857,6858,6859,6860],{"id":4011,"depth":223,"text":4012},{"id":4214,"depth":223,"text":4215},{"id":4225,"depth":223,"text":4226},{"id":4435,"depth":223,"text":4436},{"id":4479,"depth":121,"text":4480,"children":6862},[6863,6864,6865,6866],{"id":4461,"depth":223,"text":4483},{"id":4467,"depth":223,"text":4735},{"id":4961,"depth":223,"text":4962},{"id":5051,"depth":223,"text":5052},{"id":5251,"depth":121,"text":5252,"children":6868},[6869,6870,6871],{"id":5230,"depth":223,"text":5255},{"id":5412,"depth":223,"text":5413},{"id":5615,"depth":223,"text":5616},{"id":5927,"depth":121,"text":5928},1781458308979]