[{"data":1,"prerenderedAt":2879},["ShallowReactive",2],{"page-\u002Frust\u002F12-enums":3},{"id":4,"title":5,"body":6,"description":260,"extension":2873,"meta":2874,"navigation":43,"path":2875,"seo":2876,"stem":2877,"__hash__":2878},"content\u002Frust\u002F12-enums.md","12 — Enums",{"type":7,"value":8,"toc":2834},"minimark",[9,13,146,245,407,601,701,768,1047,1232,1336,1489,1566,1814,1922,2177,2297,2406,2497,2619,2716,2830],[10,11,5],"h1",{"id":12},"_12-enums",[14,15,16,30,81],"question-wrapper",{},[17,18,20,21,25,26,29],"h3",{"id":19},"q1-why-does-rust-use-optiont-instead-of-allowing-references-and-values-to-be-null","Q1. Why does Rust use ",[22,23,24],"code",{},"Option\u003CT>"," instead of allowing references and values to be ",[22,27,28],{},"null","?",[31,32,35,49,57,65],"ul",{"className":33},[34],"contains-task-list",[36,37,40,45,46,48],"li",{"className":38},[39],"task-list-item",[41,42],"input",{"disabled":43,"type":44},true,"checkbox"," ",[22,47,28],{}," is reserved as a keyword for future use",[36,50,52,45,54,56],{"className":51},[39],[41,53],{"disabled":43,"type":44},[22,55,24],{}," forces the compiler to make you explicitly handle the \"no value\" case at compile time, eliminating null-pointer-style runtime errors",[36,58,60,45,62,64],{"className":59},[39],[41,61],{"disabled":43,"type":44},[22,63,24],{}," is faster than a nullable pointer in every case",[36,66,68,70,71,73,74,77,78,80],{"className":67},[39],[41,69],{"disabled":43,"type":44}," Rust does support ",[22,72,28],{},", but only for raw pointers used in ",[22,75,76],{},"unsafe"," code, and ",[22,79,24],{}," is just a convenience wrapper on top",[82,83,84,88,98],"details",{},[85,86,87],"summary",{},"Show Answer",[89,90,91,95,96,56],"p",{},[92,93,94],"strong",{},"Answer:"," B — ",[22,97,24],{},[89,99,100,103,104,106,107,110,111,114,115,118,119,118,122,118,124,127,128,131,132,134,135,138,139,142,143,145],{},[92,101,102],{},"Explanation:"," By encoding absence as a distinct type (",[22,105,24],{}," = ",[22,108,109],{},"Some(T)"," or ",[22,112,113],{},"None",") rather than a special sentinel value any reference could silently hold, the compiler forces every caller to handle both cases (via ",[22,116,117],{},"match",", ",[22,120,121],{},"if let",[22,123,29],{},[22,125,126],{},".unwrap()",", etc.) before extracting the inner ",[22,129,130],{},"T",". This eliminates an entire class of null-dereference bugs at compile time. A is a distractor — ",[22,133,28],{}," isn't a reserved keyword tied to this. C overstates a general performance claim; the point is safety, not universal speed superiority (though ",[22,136,137],{},"Option\u003C&T>"," is often the same size as a raw pointer thanks to niche optimization, addressed later). D is false — safe Rust references (",[22,140,141],{},"&T",") genuinely cannot be null; there is no hidden null state for them outside of raw pointers in ",[22,144,76],{}," code, which are a fundamentally different type.",[14,147,148,156,204],{},[17,149,151,152,155],{"id":150},"q2-what-are-the-two-variants-of-resultt-e-and-what-does-each-represent","Q2. What are the two variants of ",[22,153,154],{},"Result\u003CT, E>",", and what does each represent?",[31,157,159,172,181,193],{"className":158},[34],[36,160,162,45,164,167,168,171],{"className":161},[39],[41,163],{"disabled":43,"type":44},[22,165,166],{},"Ok(T)"," for success, ",[22,169,170],{},"Err(E)"," for failure",[36,173,175,45,177,167,179,171],{"className":174},[39],[41,176],{"disabled":43,"type":44},[22,178,109],{},[22,180,113],{},[36,182,184,45,186,189,190],{"className":183},[39],[41,185],{"disabled":43,"type":44},[22,187,188],{},"Pass(T)"," and ",[22,191,192],{},"Fail(E)",[36,194,196,45,198,189,201],{"className":195},[39],[41,197],{"disabled":43,"type":44},[22,199,200],{},"Valid(T)",[22,202,203],{},"Invalid(String)",[82,205,206,208,217],{},[85,207,87],{},[89,209,210,212,213,167,215,171],{},[92,211,94],{}," A — ",[22,214,166],{},[22,216,170],{},[89,218,219,45,221,223,224,226,227,229,230,233,234,236,237,240,241,244],{},[92,220,102],{},[22,222,154],{}," is the standard library's two-variant enum for fallible operations: ",[22,225,166],{}," wraps the success value, ",[22,228,170],{}," wraps the error value, and the generic ",[22,231,232],{},"E"," lets each API choose its own error type. B is the tempting mix-up with ",[22,235,24],{},"'s variant names — a very common naming confusion for newcomers. C and D are plausible-sounding but fabricated variant names; the standard library specifically uses ",[22,238,239],{},"Ok","\u002F",[22,242,243],{},"Err",".",[14,246,248,252,356,386],{"language":247},"rust",[17,249,251],{"id":250},"q3-whats-the-memory-representation-implication-of-an-enum-with-data-carrying-variants-of-different-sizes-like-this-one","Q3. What's the memory representation implication of an enum with data-carrying variants of different sizes, like this one?",[253,254,255],"code-wrapper",{"language":247},[256,257,261],"pre",{"className":258,"code":259,"language":247,"meta":260,"style":260},"language-rust shiki shiki-themes github-light github-dark","enum Message {\n    Quit,\n    Move { x: i32, y: i32 },\n    Write(String),\n    ChangeColor(i32, i32, i32),\n}\n","",[22,262,263,280,289,314,329,350],{"__ignoreMap":260},[264,265,268,272,276],"span",{"class":266,"line":267},"line",1,[264,269,271],{"class":270},"svdQ7","enum",[264,273,275],{"class":274},"sIsaT"," Message",[264,277,279],{"class":278},"ssxIu"," {\n",[264,281,283,286],{"class":266,"line":282},2,[264,284,285],{"class":274},"    Quit",[264,287,288],{"class":278},",\n",[264,290,292,295,298,301,304,307,309,311],{"class":266,"line":291},3,[264,293,294],{"class":274},"    Move",[264,296,297],{"class":278}," { x",[264,299,300],{"class":270},":",[264,302,303],{"class":274}," i32",[264,305,306],{"class":278},", y",[264,308,300],{"class":270},[264,310,303],{"class":274},[264,312,313],{"class":278}," },\n",[264,315,317,320,323,326],{"class":266,"line":316},4,[264,318,319],{"class":274},"    Write",[264,321,322],{"class":278},"(",[264,324,325],{"class":274},"String",[264,327,328],{"class":278},"),\n",[264,330,332,335,337,340,342,344,346,348],{"class":266,"line":331},5,[264,333,334],{"class":274},"    ChangeColor",[264,336,322],{"class":278},[264,338,339],{"class":274},"i32",[264,341,118],{"class":278},[264,343,339],{"class":274},[264,345,118],{"class":278},[264,347,339],{"class":274},[264,349,328],{"class":278},[264,351,353],{"class":266,"line":352},6,[264,354,355],{"class":278},"}\n",[31,357,359,365,371,377],{"className":358},[34],[36,360,362,364],{"className":361},[39],[41,363],{"disabled":43,"type":44}," Each variant gets its own independent memory allocation",[36,366,368,370],{"className":367},[39],[41,369],{"disabled":43,"type":44}," The enum's total size is at least large enough to hold its largest variant, plus a discriminant tag to identify which variant is active",[36,372,374,376],{"className":373},[39],[41,375],{"disabled":43,"type":44}," The enum is always exactly the size of a pointer, regardless of variant contents",[36,378,380,45,382,385],{"className":379},[39],[41,381],{"disabled":43,"type":44},[22,383,384],{},"Quit"," (no data) makes the whole enum zero-sized",[82,387,388,390,395],{},[85,389,87],{},[89,391,392,394],{},[92,393,94],{}," B — The enum's total size is at least large enough to hold its largest variant, plus a discriminant tag to identify which variant is active",[89,396,397,399,400,110,403,406],{},[92,398,102],{}," Rust enums are tagged unions: the compiler reserves enough space for the largest variant (here, ",[22,401,402],{},"Write(String)",[22,404,405],{},"ChangeColor(i32,i32,i32)",", whichever is bigger) plus a discriminant to track which variant is currently stored, and every instance uses that same fixed size no matter which variant it holds. A describes a completely different allocation strategy Rust doesn't use for stack-resident enums. C is a fabricated simplification. D is wrong — one zero-sized variant among several data-carrying variants doesn't shrink the enum; the size is driven by the largest variant, not the smallest.",[14,408,409,423,490,525],{"language":247},[17,410,412,413,416,417,419,420,29],{"id":411},"q4-given-let-msg-messagewritestringfromhi-how-do-you-correctly-destructure-it-in-a-match-without-moving-msg","Q4. Given ",[22,414,415],{},"let msg = Message::Write(String::from(\"hi\"));",", how do you correctly destructure it in a ",[22,418,117],{}," without moving ",[22,421,422],{},"msg",[253,424,425],{"language":247},[256,426,428],{"className":258,"code":427,"language":247,"meta":260,"style":260},"enum Message { Write(String), Quit }\nlet msg = Message::Write(String::from(\"hi\"));\n",[22,429,430,454],{"__ignoreMap":260},[264,431,432,434,436,439,442,444,446,449,451],{"class":266,"line":267},[264,433,271],{"class":270},[264,435,275],{"class":274},[264,437,438],{"class":278}," { ",[264,440,441],{"class":274},"Write",[264,443,322],{"class":278},[264,445,325],{"class":274},[264,447,448],{"class":278},"), ",[264,450,384],{"class":274},[264,452,453],{"class":278}," }\n",[264,455,456,459,462,465,467,470,472,474,476,478,481,483,487],{"class":266,"line":282},[264,457,458],{"class":270},"let",[264,460,461],{"class":278}," msg ",[264,463,464],{"class":270},"=",[264,466,275],{"class":274},[264,468,469],{"class":270},"::",[264,471,441],{"class":274},[264,473,322],{"class":278},[264,475,325],{"class":274},[264,477,469],{"class":270},[264,479,480],{"class":274},"from",[264,482,322],{"class":278},[264,484,486],{"class":485},"sJ6F3","\"hi\"",[264,488,489],{"class":278},"));\n",[31,491,493,501,509,517],{"className":492},[34],[36,494,496,45,498],{"className":495},[39],[41,497],{"disabled":43,"type":44},[22,499,500],{},"match msg { Message::Write(s) => println!(\"{s}\"), Message::Quit => {} }",[36,502,504,45,506],{"className":503},[39],[41,505],{"disabled":43,"type":44},[22,507,508],{},"match &msg { Message::Write(s) => println!(\"{s}\"), Message::Quit => {} }",[36,510,512,45,514],{"className":511},[39],[41,513],{"disabled":43,"type":44},[22,515,516],{},"match msg { Write(s) => println!(\"{s}\"), Quit => {} }",[36,518,520,45,522],{"className":519},[39],[41,521],{"disabled":43,"type":44},[22,523,524],{},"if msg == Message::Write { ... }",[82,526,527,529,535],{},[85,528,87],{},[89,530,531,95,533],{},[92,532,94],{},[22,534,508],{},[89,536,537,539,540,543,544,547,548,551,552,554,555,557,558,560,561,563,564,566,567,569,570,573,574,577,578,580,581,583,584,587,588,591,592,595,596,598,599,244],{},[92,538,102],{}," Matching on ",[22,541,542],{},"&msg"," (a reference) makes the pattern match against borrowed data — ",[22,545,546],{},"s"," is then bound as ",[22,549,550],{},"&String"," via match ergonomics, and ",[22,553,422],{}," itself is not moved, so it remains usable afterward. Option A matches on ",[22,556,422],{}," by value, which moves the ",[22,559,325],{}," out of ",[22,562,422],{}," into ",[22,565,546],{},", making ",[22,568,422],{}," (or at least the moved-out field) unusable afterward — a real gotcha covered further in the edge-case questions. C omits the ",[22,571,572],{},"Message::"," path qualifier, which only works if the variants were brought into scope via ",[22,575,576],{},"use Message::*",", not by default — as bare code it fails to compile with \"cannot find value ",[22,579,441],{},"\". D confuses enums with ",[22,582,117],{}," for a boolean-style ",[22,585,586],{},"=="," comparison; ",[22,589,590],{},"Message::Write"," isn't comparable this way without deriving ",[22,593,594],{},"PartialEq",", and even then this particular syntax is invalid since ",[22,597,441],{}," alone (without its data) isn't a complete pattern for ",[22,600,586],{},[14,602,603,615,655],{},[17,604,606,607,609,610,612,613,29],{"id":605},"q5-what-does-calling-unwrap-on-optiont-do-when-the-value-is-none","Q5. What does calling ",[22,608,126],{}," on ",[22,611,24],{}," do when the value is ",[22,614,113],{},[31,616,618,624,637,646],{"className":617},[34],[36,619,621,623],{"className":620},[39],[41,622],{"disabled":43,"type":44}," Returns the type's default value",[36,625,627,629,630,633,634,636],{"className":626},[39],[41,628],{"disabled":43,"type":44}," Panics immediately with a message like \"called ",[22,631,632],{},"Option::unwrap()"," on a ",[22,635,113],{}," value\"",[36,638,640,642,643,645],{"className":639},[39],[41,641],{"disabled":43,"type":44}," Returns ",[22,644,113],{}," unchanged",[36,647,649,651,652],{"className":648},[39],[41,650],{"disabled":43,"type":44}," Silently converts to ",[22,653,654],{},"Result::Err",[82,656,657,659,668],{},[85,658,87],{},[89,660,661,663,664,633,666,636],{},[92,662,94],{}," B — Panics immediately with a message like \"called ",[22,665,632],{},[22,667,113],{},[89,669,670,45,672,674,675,240,678,680,681,683,684,686,687,690,691,693,694,189,697,700],{},[92,671,102],{},[22,673,126],{}," is explicitly the \"I am certain this is ",[22,676,677],{},"Some",[22,679,239],{},", and if I'm wrong, crash loudly\" escape hatch — on ",[22,682,113],{}," (or ",[22,685,243],{}," for ",[22,688,689],{},"Result::unwrap()",") it triggers a panic that unwinds (or aborts, depending on panic strategy) the current thread. A and C invent silent fallback behaviors that ",[22,692,126],{}," specifically does not provide (that's what ",[22,695,696],{},".unwrap_or_default()",[22,698,699],{},".unwrap_or(default)"," are for). D is a fabricated cross-type conversion that doesn't happen automatically.",[14,702,703,707,742],{},[17,704,706],{"id":705},"q6-whats-the-correct-way-to-define-an-enum-variant-that-carries-multiple-named-fields-similar-to-a-struct","Q6. What's the correct way to define an enum variant that carries multiple named fields, similar to a struct?",[31,708,710,718,724,732],{"className":709},[34],[36,711,713,45,715],{"className":712},[39],[41,714],{"disabled":43,"type":44},[22,716,717],{},"enum Shape { Circle(f64), Rectangle { width: f64, height: f64 } }",[36,719,721,723],{"className":720},[39],[41,722],{"disabled":43,"type":44}," Named fields aren't allowed in enum variants; only tuple-style data is supported",[36,725,727,45,729],{"className":726},[39],[41,728],{"disabled":43,"type":44},[22,730,731],{},"enum Shape { Circle: f64, Rectangle: (f64, f64) }",[36,733,735,737,738,741],{"className":734},[39],[41,736],{"disabled":43,"type":44}," You must define a separate ",[22,739,740],{},"struct Rectangle"," and reference it by name only",[82,743,744,746,752],{},[85,745,87],{},[89,747,748,212,750],{},[92,749,94],{},[22,751,717],{},[89,753,754,756,757,760,761,764,765,767],{},[92,755,102],{}," Rust enum variants can mix tuple-style data (",[22,758,759],{},"Circle(f64)",") and struct-style named fields (",[22,762,763],{},"Rectangle { width: f64, height: f64 }",") within the same enum — each variant chooses its own shape independently. B is false; struct-like variants are a core, commonly used feature. C uses invalid syntax — variant definitions don't use ",[22,766,300],{}," this way. D unnecessarily forces an external struct definition when inline struct-like variants are supported directly.",[14,769,770,782,923,974],{"language":247},[17,771,773,774,776,777,779,780,29],{"id":772},"q7-what-does-do-when-applied-to-a-resultt-e-inside-a-function-that-itself-returns-resultt-e","Q7. What does ",[22,775,29],{}," do when applied to a ",[22,778,154],{}," inside a function that itself returns ",[22,781,154],{},[253,783,784],{"language":247},[256,785,787],{"className":258,"code":786,"language":247,"meta":260,"style":260},"fn read_count(path: &str) -> Result\u003Cu32, std::num::ParseIntError> {\n    let contents = std::fs::read_to_string(path).unwrap_or_default();\n    let n: u32 = contents.trim().parse()?;\n    Ok(n)\n}\n",[22,788,789,839,873,911,919],{"__ignoreMap":260},[264,790,791,794,797,800,802,805,808,811,814,817,820,823,826,828,831,833,836],{"class":266,"line":267},[264,792,793],{"class":270},"fn",[264,795,796],{"class":274}," read_count",[264,798,799],{"class":278},"(path",[264,801,300],{"class":270},[264,803,804],{"class":270}," &",[264,806,807],{"class":274},"str",[264,809,810],{"class":278},") ",[264,812,813],{"class":270},"->",[264,815,816],{"class":274}," Result",[264,818,819],{"class":278},"\u003C",[264,821,822],{"class":274},"u32",[264,824,825],{"class":278},", std",[264,827,469],{"class":270},[264,829,830],{"class":278},"num",[264,832,469],{"class":270},[264,834,835],{"class":274},"ParseIntError",[264,837,838],{"class":278},"> {\n",[264,840,841,844,847,849,852,854,857,859,862,865,867,870],{"class":266,"line":282},[264,842,843],{"class":270},"    let",[264,845,846],{"class":278}," contents ",[264,848,464],{"class":270},[264,850,851],{"class":274}," std",[264,853,469],{"class":270},[264,855,856],{"class":274},"fs",[264,858,469],{"class":270},[264,860,861],{"class":274},"read_to_string",[264,863,864],{"class":278},"(path)",[264,866,244],{"class":270},[264,868,869],{"class":274},"unwrap_or_default",[264,871,872],{"class":278},"();\n",[264,874,875,877,880,882,885,888,891,893,896,899,901,904,906,908],{"class":266,"line":291},[264,876,843],{"class":270},[264,878,879],{"class":278}," n",[264,881,300],{"class":270},[264,883,884],{"class":274}," u32",[264,886,887],{"class":270}," =",[264,889,890],{"class":278}," contents",[264,892,244],{"class":270},[264,894,895],{"class":274},"trim",[264,897,898],{"class":278},"()",[264,900,244],{"class":270},[264,902,903],{"class":274},"parse",[264,905,898],{"class":278},[264,907,29],{"class":270},[264,909,910],{"class":278},";\n",[264,912,913,916],{"class":266,"line":316},[264,914,915],{"class":274},"    Ok",[264,917,918],{"class":278},"(n)\n",[264,920,921],{"class":266,"line":331},[264,922,355],{"class":278},[31,924,926,935,959,965],{"className":925},[34],[36,927,929,931,932,934],{"className":928},[39],[41,930],{"disabled":43,"type":44}," On ",[22,933,243],{},", it panics immediately",[36,936,938,931,940,943,944,947,948,951,952,954,955,958],{"className":937},[39],[41,939],{"disabled":43,"type":44},[22,941,942],{},"Ok(v)",", it unwraps to ",[22,945,946],{},"v","; on ",[22,949,950],{},"Err(e)",", it returns early from the function with ",[22,953,950],{}," (converted via ",[22,956,957],{},"From"," if needed)",[36,960,962,964],{"className":961},[39],[41,963],{"disabled":43,"type":44}," It logs the error and continues with a default value",[36,966,968,970,971],{"className":967},[39],[41,969],{"disabled":43,"type":44}," It only works inside ",[22,972,973],{},"main()",[82,975,976,978,993],{},[85,977,87],{},[89,979,980,982,983,943,985,947,987,951,989,954,991,958],{},[92,981,94],{}," B — On ",[22,984,942],{},[22,986,946],{},[22,988,950],{},[22,990,950],{},[22,992,957],{},[89,994,995,997,998,1000,1001,1004,1005,1007,1008,1012,1013,1015,1016,1018,1019,1021,1022,240,1025,1028,1029,1032,1033,1036,1037,1040,1041,1043,1044,1046],{},[92,996,102],{}," The ",[22,999,29],{}," operator is sugar for \"unwrap on success, early-return on failure,\" and it also calls ",[22,1002,1003],{},"From::from"," on the error to convert it into the function's declared error type if they differ. A is wrong — ",[22,1006,29],{}," explicitly does ",[1009,1010,1011],"em",{},"not"," panic; that's what distinguishes it from ",[22,1014,126],{},". C invents logging\u002Fdefault behavior that ",[22,1017,29],{}," does not perform. D is a common misconception — ",[22,1020,29],{}," works in any function whose return type implements the necessary ",[22,1023,1024],{},"Try",[22,1026,1027],{},"FromResidual"," mechanics (any ",[22,1030,1031],{},"Result","- or ",[22,1034,1035],{},"Option","-returning function, not just ",[22,1038,1039],{},"main",", though ",[22,1042,1039],{}," can also return ",[22,1045,1031],{}," since Rust 2018).",[14,1048,1049,1062,1136,1186],{"language":247},[17,1050,1052,1053,633,1055,1057,1058,1061],{"id":1051},"q8-what-happens-when-you-call-unwrap-on-a-resulterr-in-production-code-with-no-catch_unwind-or-panic-hook-configured","Q8. What happens when you call ",[22,1054,126],{},[22,1056,654],{}," in production code with no ",[22,1059,1060],{},"catch_unwind"," or panic hook configured?",[253,1063,1064],{"language":247},[256,1065,1067],{"className":258,"code":1066,"language":247,"meta":260,"style":260},"fn parse_port(s: &str) -> u16 {\n    s.parse().unwrap()\n}\nlet port = parse_port(\"not_a_number\");\n",[22,1068,1069,1094,1113,1117],{"__ignoreMap":260},[264,1070,1071,1073,1076,1079,1081,1083,1085,1087,1089,1092],{"class":266,"line":267},[264,1072,793],{"class":270},[264,1074,1075],{"class":274}," parse_port",[264,1077,1078],{"class":278},"(s",[264,1080,300],{"class":270},[264,1082,804],{"class":270},[264,1084,807],{"class":274},[264,1086,810],{"class":278},[264,1088,813],{"class":270},[264,1090,1091],{"class":274}," u16",[264,1093,279],{"class":278},[264,1095,1096,1099,1101,1103,1105,1107,1110],{"class":266,"line":282},[264,1097,1098],{"class":278},"    s",[264,1100,244],{"class":270},[264,1102,903],{"class":274},[264,1104,898],{"class":278},[264,1106,244],{"class":270},[264,1108,1109],{"class":274},"unwrap",[264,1111,1112],{"class":278},"()\n",[264,1114,1115],{"class":266,"line":291},[264,1116,355],{"class":278},[264,1118,1119,1121,1124,1126,1128,1130,1133],{"class":266,"line":316},[264,1120,458],{"class":270},[264,1122,1123],{"class":278}," port ",[264,1125,464],{"class":270},[264,1127,1075],{"class":274},[264,1129,322],{"class":278},[264,1131,1132],{"class":485},"\"not_a_number\"",[264,1134,1135],{"class":278},");\n",[31,1137,1139,1151,1157,1169],{"className":1138},[34],[36,1140,1142,45,1144,1147,1148],{"className":1141},[39],[41,1143],{"disabled":43,"type":44},[22,1145,1146],{},"port"," becomes ",[22,1149,1150],{},"0",[36,1152,1154,1156],{"className":1153},[39],[41,1155],{"disabled":43,"type":44}," The thread panics and, by default, unwinds — if this happens on the main thread, the process terminates with a non-zero exit code and a panic message printed to stderr",[36,1158,1160,1162,1163,1166,1167],{"className":1159},[39],[41,1161],{"disabled":43,"type":44}," The compiler rejects this code because ",[22,1164,1165],{},"parse_port","'s return type doesn't mention ",[22,1168,1031],{},[36,1170,1172,45,1174,1177,1178,1181,1182,1185],{"className":1171},[39],[41,1173],{"disabled":43,"type":44},[22,1175,1176],{},"parse()"," silently returns ",[22,1179,1180],{},"65535"," (max ",[22,1183,1184],{},"u16",") for invalid input",[82,1187,1188,1190,1195],{},[85,1189,87],{},[89,1191,1192,1194],{},[92,1193,94],{}," B — The thread panics and, by default, unwinds — if this happens on the main thread, the process terminates with a non-zero exit code and a panic message printed to stderr",[89,1196,1197,45,1199,1202,1203,1205,1206,1208,1209,1211,1212,1215,1216,126,1219,29,1222,1225,1226,117,1229,1231],{},[92,1198,102],{},[22,1200,1201],{},"\"not_a_number\".parse::\u003Cu16>()"," returns ",[22,1204,243],{},", and ",[22,1207,126],{}," on an ",[22,1210,243],{}," panics with a message like ",[22,1213,1214],{},"called \\","Result::unwrap()` on an `Err` value: ParseIntError { ... }",[22,1217,1218],{},". In a real service, this is exactly the kind of ",[22,1220,1221],{},"that takes down a request handler (or the whole process, if on the main thread and not caught) on malformed input. **Debug:** the correct production handling is to propagate the error with",[22,1223,1224],{},"(changing the return type to","Result\u003Cu16, ParseIntError>",[22,1227,1228],{},") or handle it explicitly with ",[22,1230,240],{},"unwrap_or` and a sensible fallback or error response, rather than trusting external input to always parse cleanly. A, C, and D all invent silent-failure behaviors; Rust does not silently coerce a failed parse into a default numeric value.",[14,1233,1234,1246,1292],{},[17,1235,1237,1238,1241,1242,1245],{"id":1236},"q9-what-is-the-size-in-bytes-of-optioni32-on-a-64-bit-platform-compared-to-i32-alone-and-why","Q9. What is the size, in bytes, of ",[22,1239,1240],{},"Option\u003C&i32>"," on a 64-bit platform, compared to ",[22,1243,1244],{},"&i32"," alone, and why?",[31,1247,1249,1264,1273,1281],{"className":1248},[34],[36,1250,1252,1254,1255,1257,1258,1260,1261,1263],{"className":1251},[39],[41,1253],{"disabled":43,"type":44}," 16 bytes for ",[22,1256,1240],{}," vs 8 bytes for ",[22,1259,1244],{}," — the ",[22,1262,1035],{}," tag doubles the size",[36,1265,1267,1269,1270,1272],{"className":1266},[39],[41,1268],{"disabled":43,"type":44}," 8 bytes for both — the compiler uses \"niche optimization,\" repurposing the fact that a valid reference can never be the all-zero bit pattern to represent ",[22,1271,113],{}," as that otherwise-impossible value",[36,1274,1276,45,1278,1280],{"className":1275},[39],[41,1277],{"disabled":43,"type":44},[22,1279,1240],{}," cannot be constructed since references can't be optional",[36,1282,1284,1286,1287,1289,1290],{"className":1283},[39],[41,1285],{"disabled":43,"type":44}," 9 bytes for ",[22,1288,1240],{}," (8 for the pointer + 1 tag byte, unpadded) vs 8 bytes for ",[22,1291,1244],{},[82,1293,1294,1296,1303],{},[85,1295,87],{},[89,1297,1298,1300,1301,1272],{},[92,1299,94],{}," B — 8 bytes for both — the compiler uses \"niche optimization,\" repurposing the fact that a valid reference can never be the all-zero bit pattern to represent ",[22,1302,113],{},[89,1304,1305,45,1307,1310,1311,1313,1314,1316,1317,1319,1320,1322,1323,1325,1326,118,1329,1332,1333,1335],{},[92,1306,102],{},[92,1308,1309],{},"Performance:"," this is a genuinely surprising and important Rust optimization — because a real ",[22,1312,141],{}," reference is guaranteed non-null, ",[22,1315,137],{}," doesn't need a separate discriminant byte at all; the compiler encodes ",[22,1318,113],{}," as the bit pattern that a real reference could never have (all zeros), making ",[22,1321,137],{}," exactly pointer-sized. This is why ",[22,1324,137],{}," (and ",[22,1327,1328],{},"Option\u003CBox\u003CT>>",[22,1330,1331],{},"Option\u003CNonZeroU32>",", etc.) is often used as a zero-overhead nullable pointer. A is the naive \"tag always adds size\" assumption that's true for many enums but not this niche-optimized case. C is false — ",[22,1334,137],{}," is a completely standard, common pattern. D invents padding math that doesn't reflect how niche optimization actually works here.",[14,1337,1338,1348,1422,1460],{"language":247},[17,1339,1341,1342,1344,1345,1347],{"id":1340},"q10-what-does-an-empty-match-on-optiont-that-omits-the-none-arm-do","Q10. What does an empty match on ",[22,1343,24],{}," that omits the ",[22,1346,113],{}," arm do?",[253,1349,1350],{"language":247},[256,1351,1353],{"className":258,"code":1352,"language":247,"meta":260,"style":260},"fn describe(x: Option\u003Ci32>) -> String {\n    match x {\n        Some(n) => n.to_string(),\n    }\n}\n",[22,1354,1355,1384,1392,1413,1418],{"__ignoreMap":260},[264,1356,1357,1359,1362,1365,1367,1370,1372,1374,1377,1379,1382],{"class":266,"line":267},[264,1358,793],{"class":270},[264,1360,1361],{"class":274}," describe",[264,1363,1364],{"class":278},"(x",[264,1366,300],{"class":270},[264,1368,1369],{"class":274}," Option",[264,1371,819],{"class":278},[264,1373,339],{"class":274},[264,1375,1376],{"class":278},">) ",[264,1378,813],{"class":270},[264,1380,1381],{"class":274}," String",[264,1383,279],{"class":278},[264,1385,1386,1389],{"class":266,"line":282},[264,1387,1388],{"class":270},"    match",[264,1390,1391],{"class":278}," x {\n",[264,1393,1394,1397,1400,1403,1405,1407,1410],{"class":266,"line":291},[264,1395,1396],{"class":274},"        Some",[264,1398,1399],{"class":278},"(n) ",[264,1401,1402],{"class":270},"=>",[264,1404,879],{"class":278},[264,1406,244],{"class":270},[264,1408,1409],{"class":274},"to_string",[264,1411,1412],{"class":278},"(),\n",[264,1414,1415],{"class":266,"line":316},[264,1416,1417],{"class":278},"    }\n",[264,1419,1420],{"class":266,"line":331},[264,1421,355],{"class":278},[31,1423,1425,1433,1442,1454],{"className":1424},[34],[36,1426,1428,1430,1431],{"className":1427},[39],[41,1429],{"disabled":43,"type":44}," Compiles, returning an empty string for ",[22,1432,113],{},[36,1434,1436,1438,1439,1441],{"className":1435},[39],[41,1437],{"disabled":43,"type":44}," Fails to compile — \"non-exhaustive patterns: ",[22,1440,113],{}," not covered\"",[36,1443,1445,1447,1448,1451,1452],{"className":1444},[39],[41,1446],{"disabled":43,"type":44}," Compiles, but panics at runtime if ",[22,1449,1450],{},"x"," is ",[22,1453,113],{},[36,1455,1457,1459],{"className":1456},[39],[41,1458],{"disabled":43,"type":44}," Compiles only in debug builds",[82,1461,1462,1464,1471],{},[85,1463,87],{},[89,1465,1466,1468,1469,1441],{},[92,1467,94],{}," B — Fails to compile — \"non-exhaustive patterns: ",[22,1470,113],{},[89,1472,1473,1475,1476,1478,1479,1482,1483,1485,1486,1488],{},[92,1474,102],{}," Rust's ",[22,1477,117],{}," requires exhaustiveness — every possible variant of the matched type must be covered (or a wildcard ",[22,1480,1481],{},"_"," catch-all provided) — and the compiler statically checks this against the enum's known variant set at compile time, so a missing ",[22,1484,113],{}," arm on ",[22,1487,24],{}," is a hard compile error, not a runtime concern. A and C both imagine runtime fallback behavior that never gets the chance to run because compilation fails first. D is false — exhaustiveness checking is not conditional on build profile; it's a fundamental part of type checking.",[14,1490,1491,1499,1529],{},[17,1492,1494,1495,1498],{"id":1493},"q11-enum-never-an-enum-with-zero-variants-what-can-you-do-with-a-value-of-this-type","Q11. ",[22,1496,1497],{},"enum Never {}"," — an enum with zero variants — what can you do with a value of this type?",[31,1500,1502,1511,1517,1523],{"className":1501},[34],[36,1503,1505,1507,1508],{"className":1504},[39],[41,1506],{"disabled":43,"type":44}," Construct it with ",[22,1509,1510],{},"Never::default()",[36,1512,1514,1516],{"className":1513},[39],[41,1515],{"disabled":43,"type":44}," Nothing — it's impossible to construct a value of this type, since there are no variants to build; it's used to statically prove a code path is unreachable",[36,1518,1520,1522],{"className":1519},[39],[41,1521],{"disabled":43,"type":44}," It behaves exactly like a unit struct",[36,1524,1526,1528],{"className":1525},[39],[41,1527],{"disabled":43,"type":44}," It's a compile error to define an enum with no variants",[82,1530,1531,1533,1538],{},[85,1532,87],{},[89,1534,1535,1537],{},[92,1536,94],{}," B — Nothing — it's impossible to construct a value of this type, since there are no variants to build; it's used to statically prove a code path is unreachable",[89,1539,1540,1542,1543,1546,1547,1550,1551,1553,1554,1557,1558,1561,1562,1565],{},[92,1541,102],{}," An enum with zero variants (like the standard library's ",[22,1544,1545],{},"std::convert::Infallible",", which is essentially this) has no possible values at all — it's an \"uninhabited type.\" This is genuinely useful: e.g., ",[22,1548,1549],{},"Result\u003CT, Infallible>"," tells the compiler (and a reader) that the error branch can never actually occur, and ",[22,1552,117],{}," exhaustiveness checking can then treat that branch as impossible to reach. A is wrong — there's no variant to construct, so no ",[22,1555,1556],{},"default()"," could exist. C is wrong — a unit struct ",[1009,1559,1560],{},"can"," be constructed (it has exactly one, trivial value); a zero-variant enum has ",[1009,1563,1564],{},"no"," values at all. D is false — this is valid, if unusual, Rust and compiles fine.",[14,1567,1568,1572,1698,1757],{"language":247},[17,1569,1571],{"id":1570},"q12-whats-the-pitfall-in-this-match-guard-combined-with-binding-when-matching-against-a-mutable-reference","Q12. What's the pitfall in this match guard combined with binding, when matching against a mutable reference?",[253,1573,1574],{"language":247},[256,1575,1577],{"className":258,"code":1576,"language":247,"meta":260,"style":260},"enum Status { Pending, Active(u32), Done }\nlet mut status = Status::Active(5);\nmatch &mut status {\n    Status::Active(n) if *n > 3 => *n += 1,\n    _ => {}\n}\n",[22,1578,1579,1607,1633,1643,1684,1694],{"__ignoreMap":260},[264,1580,1581,1583,1586,1588,1591,1593,1596,1598,1600,1602,1605],{"class":266,"line":267},[264,1582,271],{"class":270},[264,1584,1585],{"class":274}," Status",[264,1587,438],{"class":278},[264,1589,1590],{"class":274},"Pending",[264,1592,118],{"class":278},[264,1594,1595],{"class":274},"Active",[264,1597,322],{"class":278},[264,1599,822],{"class":274},[264,1601,448],{"class":278},[264,1603,1604],{"class":274},"Done",[264,1606,453],{"class":278},[264,1608,1609,1611,1614,1617,1619,1621,1623,1625,1627,1631],{"class":266,"line":282},[264,1610,458],{"class":270},[264,1612,1613],{"class":270}," mut",[264,1615,1616],{"class":278}," status ",[264,1618,464],{"class":270},[264,1620,1585],{"class":274},[264,1622,469],{"class":270},[264,1624,1595],{"class":274},[264,1626,322],{"class":278},[264,1628,1630],{"class":1629},"snvgF","5",[264,1632,1135],{"class":278},[264,1634,1635,1637,1640],{"class":266,"line":291},[264,1636,117],{"class":270},[264,1638,1639],{"class":270}," &mut",[264,1641,1642],{"class":278}," status {\n",[264,1644,1645,1648,1650,1652,1654,1657,1660,1663,1666,1669,1672,1674,1676,1679,1682],{"class":266,"line":316},[264,1646,1647],{"class":274},"    Status",[264,1649,469],{"class":270},[264,1651,1595],{"class":274},[264,1653,1399],{"class":278},[264,1655,1656],{"class":270},"if",[264,1658,1659],{"class":270}," *",[264,1661,1662],{"class":278},"n ",[264,1664,1665],{"class":270},">",[264,1667,1668],{"class":1629}," 3",[264,1670,1671],{"class":270}," =>",[264,1673,1659],{"class":270},[264,1675,1662],{"class":278},[264,1677,1678],{"class":270},"+=",[264,1680,1681],{"class":1629}," 1",[264,1683,288],{"class":278},[264,1685,1686,1689,1691],{"class":266,"line":331},[264,1687,1688],{"class":278},"    _ ",[264,1690,1402],{"class":270},[264,1692,1693],{"class":278}," {}\n",[264,1695,1696],{"class":266,"line":352},[264,1697,355],{"class":278},[31,1699,1701,1707,1731,1748],{"className":1700},[34],[36,1702,1704,1706],{"className":1703},[39],[41,1705],{"disabled":43,"type":44}," This fails to compile — you cannot mutate through a match binding",[36,1708,1710,45,1712,1715,1716,1719,1720,1723,1724,1727,1728],{"className":1709},[39],[41,1711],{"disabled":43,"type":44},[22,1713,1714],{},"n"," binds as ",[22,1717,1718],{},"&mut u32"," due to match ergonomics on ",[22,1721,1722],{},"&mut status",", so ",[22,1725,1726],{},"*n += 1"," correctly mutates the field in place, incrementing it to ",[22,1729,1730],{},"6",[36,1732,1734,1736,1737,1740,1741,1744,1745,1747],{"className":1733},[39],[41,1735],{"disabled":43,"type":44}," The guard ",[22,1738,1739],{},"if *n > 3"," always evaluates to ",[22,1742,1743],{},"false"," because ",[22,1746,1714],{}," hasn't been dereferenced yet at that point",[36,1749,1751,45,1753,1756],{"className":1750},[39],[41,1752],{"disabled":43,"type":44},[22,1754,1755],{},"status"," must first be cloned before matching",[82,1758,1759,1761,1775],{},[85,1760,87],{},[89,1762,1763,95,1765,1715,1767,1719,1769,1723,1771,1727,1773],{},[92,1764,94],{},[22,1766,1714],{},[22,1768,1718],{},[22,1770,1722],{},[22,1772,1726],{},[22,1774,1730],{},[89,1776,1777,1779,1780,1782,1783,1786,1787,1789,1790,1792,1793,1796,1797,1799,1800,1802,1803,1806,1807,1810,1811,1813],{},[92,1778,102],{}," Match ergonomics automatically adjusts binding modes when matching on a reference: matching ",[22,1781,1722],{}," against ",[22,1784,1785],{},"Status::Active(n)"," binds ",[22,1788,1714],{}," as ",[22,1791,1718],{}," rather than requiring you to write ",[22,1794,1795],{},"Status::Active(ref mut n)"," manually. The guard ",[22,1798,1739],{}," correctly dereferences to compare the underlying value, and ",[22,1801,1726],{}," mutates it through the reference — perfectly valid and idiomatic. A is wrong — mutation through a match binding is exactly what ",[22,1804,1805],{},"&mut"," matching enables. C misunderstands dereferencing — ",[22,1808,1809],{},"*n"," in the guard reads the current value just fine, it doesn't require a prior explicit step. D is unnecessary — no clone is needed since matching on ",[22,1812,1722],{}," borrows rather than moves.",[14,1815,1816,1828,1870],{},[17,1817,1819,1820,1823,1824,1827],{"id":1818},"q13-in-enum-shape-circlef64-squaref64-is-circle20-circle20-valid-and-under-what-condition","Q13. In ",[22,1821,1822],{},"enum Shape { Circle(f64), Square(f64) }",", is ",[22,1825,1826],{},"Circle(2.0) == Circle(2.0)"," valid, and under what condition?",[31,1829,1831,1840,1856,1862],{"className":1830},[34],[36,1832,1834,1836,1837,1839],{"className":1833},[39],[41,1835],{"disabled":43,"type":44}," Always valid — all enums support ",[22,1838,586],{}," by default",[36,1841,1843,1845,1846,1849,1850,1852,1853,1855],{"className":1842},[39],[41,1844],{"disabled":43,"type":44}," Only valid if ",[22,1847,1848],{},"Shape"," derives (or manually implements) ",[22,1851,594],{},"; without it, ",[22,1854,586],{}," on enum values is a compile error",[36,1857,1859,1861],{"className":1858},[39],[41,1860],{"disabled":43,"type":44}," Only valid for enums with no data-carrying variants",[36,1863,1865,1867,1868],{"className":1864},[39],[41,1866],{"disabled":43,"type":44}," Always invalid — enums can only be compared with ",[22,1869,117],{},[82,1871,1872,1874,1885],{},[85,1873,87],{},[89,1875,1876,1878,1879,1849,1881,1852,1883,1855],{},[92,1877,94],{}," B — Only valid if ",[22,1880,1848],{},[22,1882,594],{},[22,1884,586],{},[89,1886,1887,1889,1890,1893,1894,1897,1898,240,1900,1903,1904,1906,1907,1909,1910,1912,1913,240,1915,1918,1919,1921],{},[92,1888,102],{}," Rust does not give any type — struct or enum — automatic equality comparison; ",[22,1891,1892],{},"#[derive(PartialEq)]"," (or a manual ",[22,1895,1896],{},"impl",") is required before ",[22,1899,586],{},[22,1901,1902],{},"!="," can be used, and the compiler will reject ",[22,1905,1826],{}," with \"binary operation ",[22,1908,586],{}," cannot be applied\" if the derive is missing. A is the common false assumption carried over from languages with default structural equality. C is fabricated — data-carrying variants can absolutely be compared once ",[22,1911,594],{}," is derived (it compares variant tag and then inner data). D overstates things — ",[22,1914,117],{},[22,1916,1917],{},"matches!"," are alternatives for checking variant identity without full data equality, but ",[22,1920,586],{}," works fine too once derived.",[14,1923,1924,1935,2051,2110],{"language":247},[17,1925,1927,1928,1931,1932,1934],{"id":1926},"q14-what-happens-if-you-match-on-optionstring-and-try-to-move-the-inner-string-out-inside-the-match-arm","Q14. What happens if you match on ",[22,1929,1930],{},"&Option\u003CString>"," and try to move the inner ",[22,1933,325],{}," out inside the match arm?",[253,1936,1937],{"language":247},[256,1938,1940],{"className":258,"code":1939,"language":247,"meta":260,"style":260},"let maybe_name: Option\u003CString> = Some(String::from(\"Ferris\"));\nmatch &maybe_name {\n    Some(s) => {\n        let owned: String = *s;\n        println!(\"{owned}\");\n    }\n    None => {}\n}\n",[22,1941,1942,1980,1989,2001,2020,2032,2036,2046],{"__ignoreMap":260},[264,1943,1944,1946,1949,1951,1953,1955,1957,1960,1962,1965,1967,1969,1971,1973,1975,1978],{"class":266,"line":267},[264,1945,458],{"class":270},[264,1947,1948],{"class":278}," maybe_name",[264,1950,300],{"class":270},[264,1952,1369],{"class":274},[264,1954,819],{"class":278},[264,1956,325],{"class":274},[264,1958,1959],{"class":278},"> ",[264,1961,464],{"class":270},[264,1963,1964],{"class":274}," Some",[264,1966,322],{"class":278},[264,1968,325],{"class":274},[264,1970,469],{"class":270},[264,1972,480],{"class":274},[264,1974,322],{"class":278},[264,1976,1977],{"class":485},"\"Ferris\"",[264,1979,489],{"class":278},[264,1981,1982,1984,1986],{"class":266,"line":282},[264,1983,117],{"class":270},[264,1985,804],{"class":270},[264,1987,1988],{"class":278},"maybe_name {\n",[264,1990,1991,1994,1997,1999],{"class":266,"line":291},[264,1992,1993],{"class":274},"    Some",[264,1995,1996],{"class":278},"(s) ",[264,1998,1402],{"class":270},[264,2000,279],{"class":278},[264,2002,2003,2006,2009,2011,2013,2015,2017],{"class":266,"line":316},[264,2004,2005],{"class":270},"        let",[264,2007,2008],{"class":278}," owned",[264,2010,300],{"class":270},[264,2012,1381],{"class":274},[264,2014,887],{"class":270},[264,2016,1659],{"class":270},[264,2018,2019],{"class":278},"s;\n",[264,2021,2022,2025,2027,2030],{"class":266,"line":331},[264,2023,2024],{"class":274},"        println!",[264,2026,322],{"class":278},[264,2028,2029],{"class":485},"\"{owned}\"",[264,2031,1135],{"class":278},[264,2033,2034],{"class":266,"line":352},[264,2035,1417],{"class":278},[264,2037,2039,2042,2044],{"class":266,"line":2038},7,[264,2040,2041],{"class":274},"    None",[264,2043,1671],{"class":270},[264,2045,1693],{"class":278},[264,2047,2049],{"class":266,"line":2048},8,[264,2050,355],{"class":278},[31,2052,2054,2066,2090,2101],{"className":2053},[34],[36,2055,2057,2059,2060,2063,2064],{"className":2056},[39],[41,2058],{"disabled":43,"type":44}," Compiles fine — ",[22,2061,2062],{},"*s"," copies the ",[22,2065,325],{},[36,2067,2069,2071,2072,1451,2074,2076,2077,2079,2080,1723,2083,2085,2086,2089],{"className":2068},[39],[41,2070],{"disabled":43,"type":44}," Fails to compile — ",[22,2073,546],{},[22,2075,550],{}," here, and ",[22,2078,325],{}," isn't ",[22,2081,2082],{},"Copy",[22,2084,2062],{}," would attempt an illegal move out of a reference; use ",[22,2087,2088],{},"s.clone()"," instead",[36,2091,2093,45,2095,1147,2098,2100],{"className":2092},[39],[41,2094],{"disabled":43,"type":44},[22,2096,2097],{},"maybe_name",[22,2099,113],{}," after this match",[36,2102,2104,2106,2107,2109],{"className":2103},[39],[41,2105],{"disabled":43,"type":44}," This only fails in ",[22,2108,76],{}," blocks",[82,2111,2112,2114,2131],{},[85,2113,87],{},[89,2115,2116,2118,2119,1451,2121,2076,2123,2079,2125,1723,2127,2085,2129,2089],{},[92,2117,94],{}," B — Fails to compile — ",[22,2120,546],{},[22,2122,550],{},[22,2124,325],{},[22,2126,2082],{},[22,2128,2062],{},[22,2130,2088],{},[89,2132,2133,2135,2136,2139,2140,1789,2142,2144,2145,2147,2148,2150,2151,2153,2154,2156,2157,2159,2160,2162,2163,2165,2166,2168,2169,2171,2172,2174,2175,244],{},[92,2134,102],{}," Because the match scrutinee is ",[22,2137,2138],{},"&maybe_name",", match ergonomics binds ",[22,2141,546],{},[22,2143,550],{},", not ",[22,2146,325],{},". Dereferencing with ",[22,2149,2062],{}," to produce an owned ",[22,2152,325],{}," would require moving data out from behind a reference, which the borrow checker forbids (\"cannot move out of ",[22,2155,2062],{}," which is behind a shared reference\") since the original ",[22,2158,2097],{}," still owns that data. The fix is ",[22,2161,2088],{}," to get an owned copy, or restructure to match on ",[22,2164,2097],{}," by value if you intend to consume it. A is wrong — ",[22,2167,325],{}," does not implement ",[22,2170,2082],{}," (it manages heap data), so ",[22,2173,2062],{}," cannot silently copy. C is fabricated. D is false — this is a plain compile-time borrow-checker rejection, unrelated to ",[22,2176,76],{},[14,2178,2179,2190,2241],{},[17,2180,2182,2183,2186,2187,2189],{"id":2181},"q15-when-designing-a-function-that-can-fail-why-is-returning-resultt-myerror-generally-preferred-over-returning-optiont-and-discarding-the-reason-for-failure","Q15. When designing a function that can fail, why is returning ",[22,2184,2185],{},"Result\u003CT, MyError>"," generally preferred over returning ",[22,2188,24],{}," and discarding the reason for failure?",[31,2191,2193,2204,2223,2231],{"className":2192},[34],[36,2194,2196,45,2198,2200,2201,2203],{"className":2195},[39],[41,2197],{"disabled":43,"type":44},[22,2199,24],{}," cannot be used with the ",[22,2202,29],{}," operator at all",[36,2205,2207,45,2209,2211,2212,2215,2216,2218,2219,2222],{"className":2206},[39],[41,2208],{"disabled":43,"type":44},[22,2210,154],{}," preserves ",[1009,2213,2214],{},"why"," the operation failed, which callers (and logs\u002Ferror messages) often need, whereas ",[22,2217,24],{}," only signals ",[1009,2220,2221],{},"that"," it failed",[36,2224,2226,45,2228,2230],{"className":2225},[39],[41,2227],{"disabled":43,"type":44},[22,2229,24],{}," is deprecated in modern Rust",[36,2232,2234,45,2236,2238,2239],{"className":2233},[39],[41,2235],{"disabled":43,"type":44},[22,2237,154],{}," is always smaller in memory than ",[22,2240,24],{},[82,2242,2243,2245,2257],{},[85,2244,87],{},[89,2246,2247,95,2249,2211,2251,2215,2253,2218,2255,2222],{},[92,2248,94],{},[22,2250,154],{},[1009,2252,2214],{},[22,2254,24],{},[1009,2256,2221],{},[89,2258,2259,45,2261,2264,2265,2267,2268,2271,2272,2274,2275,2277,2278,2280,2281,2283,2284,2286,2287,2289,2290,2292,2293,189,2295,244],{},[92,2260,102],{},[92,2262,2263],{},"Idiom:"," the general guideline is: use ",[22,2266,24],{}," when absence is a normal, expected, reason-less outcome (e.g., ",[22,2269,2270],{},"HashMap::get"," — the key simply wasn't there), and use ",[22,2273,154],{}," when failure needs an explanation a caller might inspect, log, or match on (e.g., parse errors, I\u002FO errors, validation failures). Collapsing a rich error into ",[22,2276,24],{}," throws away diagnostic information callers may need later. A is false — ",[22,2279,29],{}," works on ",[22,2282,24],{}," too, propagating ",[22,2285,113],{}," in a function that itself returns ",[22,2288,1035],{},". C is false — ",[22,2291,24],{}," is a completely standard, actively used type, not deprecated. D is not a real or relevant comparison; sizes depend entirely on ",[22,2294,130],{},[22,2296,232],{},[14,2298,2299,2310,2367],{},[17,2300,2302,2303,2306,2307,2309],{"id":2301},"q16-code-review-flags-a-public-function-returning-resultuser-string-where-string-is-just-a-human-readable-error-message-whats-the-idiomatic-improvement-and-why","Q16. Code review flags a public function returning ",[22,2304,2305],{},"Result\u003CUser, String>"," where ",[22,2308,325],{}," is just a human-readable error message. What's the idiomatic improvement, and why?",[31,2311,2313,2322,2344,2354],{"className":2312},[34],[36,2314,2316,2318,2319,2321],{"className":2315},[39],[41,2317],{"disabled":43,"type":44}," Leave it as-is — ",[22,2320,325],{}," errors are always sufficient",[36,2323,2325,2327,2328,2331,2332,2335,2336,2339,2340,2343],{"className":2324},[39],[41,2326],{"disabled":43,"type":44}," Define a proper error enum implementing ",[22,2329,2330],{},"std::error::Error"," (and typically ",[22,2333,2334],{},"Display",") so callers can programmatically distinguish failure kinds (e.g., ",[22,2337,2338],{},"UserError::NotFound"," vs ",[22,2341,2342],{},"UserError::InvalidEmail",") instead of parsing message text",[36,2345,2347,2349,2350,2353],{"className":2346},[39],[41,2348],{"disabled":43,"type":44}," Switch to ",[22,2351,2352],{},"Result\u003CUser, ()>"," since the message isn't needed",[36,2355,2357,2359,2360,2363,2364,2366],{"className":2356},[39],[41,2358],{"disabled":43,"type":44}," Change it to ",[22,2361,2362],{},"Option\u003CUser>"," since ",[22,2365,325],{}," errors aren't real errors",[82,2368,2369,2371,2384],{},[85,2370,87],{},[89,2372,2373,2375,2376,2331,2378,2335,2380,2339,2382,2343],{},[92,2374,94],{}," B — Define a proper error enum implementing ",[22,2377,2330],{},[22,2379,2334],{},[22,2381,2338],{},[22,2383,2342],{},[89,2385,2386,45,2388,45,2390,2392,2393,2396,2397,2399,2400,2402,2403,2405],{},[92,2387,102],{},[92,2389,2263],{},[22,2391,325],{},"-typed errors are a common quick-and-dirty starting point, but they force any caller that needs to branch on failure kind to parse or ",[22,2394,2395],{},".contains()"," a message string, which is brittle and breaks silently if the wording changes. A structured error enum lets callers ",[22,2398,117],{}," on variants directly and lets the type system enforce handling all known failure kinds. A dismisses a real, well-known anti-pattern. C throws away the diagnostic message entirely, making debugging harder. D conflates \"has a reason\" (an error) with \"has no reason\" (",[22,2401,1035],{},"'s use case) — the message shows this function does have failure reasons, so ",[22,2404,1035],{}," is the wrong direction entirely.",[14,2407,2408,2419,2461],{},[17,2409,2411,2412,2415,2416,2418],{"id":2410},"q17-why-is-if-let-somex-maybe_value-often-preferred-over-a-full-match-when-you-only-care-about-one-variant-and-want-to-ignore-the-rest","Q17. Why is ",[22,2413,2414],{},"if let Some(x) = maybe_value { ... }"," often preferred over a full ",[22,2417,117],{}," when you only care about one variant and want to ignore the rest?",[31,2420,2422,2433,2441,2451],{"className":2421},[34],[36,2423,2425,45,2427,2429,2430,2432],{"className":2424},[39],[41,2426],{"disabled":43,"type":44},[22,2428,117],{}," cannot ignore variants; ",[22,2431,121],{}," is required whenever you don't want every arm",[36,2434,2436,45,2438,2440],{"className":2435},[39],[41,2437],{"disabled":43,"type":44},[22,2439,121],{}," is more concise for the single-pattern case, at the cost of losing the compiler's exhaustiveness guarantee for any variants you're not handling",[36,2442,2444,45,2446,2448,2449],{"className":2443},[39],[41,2445],{"disabled":43,"type":44},[22,2447,121],{}," is faster at runtime than ",[22,2450,117],{},[36,2452,2454,45,2456,189,2458,2460],{"className":2453},[39],[41,2455],{"disabled":43,"type":44},[22,2457,121],{},[22,2459,117],{}," are interchangeable with no tradeoffs whatsoever",[82,2462,2463,2465,2471],{},[85,2464,87],{},[89,2466,2467,95,2469,2440],{},[92,2468,94],{},[22,2470,121],{},[89,2472,2473,45,2475,45,2477,2479,2480,2482,2483,2486,2487,2489,2490,2493,2494,2496],{},[92,2474,102],{},[92,2476,2263],{},[22,2478,2414],{}," desugars to a ",[22,2481,117],{}," with one meaningful arm and an implicit ",[22,2484,2485],{},"_ => {}"," — great ergonomics when you truly only care about one case, but it means if a new enum variant is added later, the compiler won't force you to reconsider this call site the way an exhaustive ",[22,2488,117],{}," would. This is a genuine tradeoff to weigh, not a strict upgrade. A is false — ",[22,2491,2492],{},"match _ => {}"," handles the \"ignore the rest\" case just fine within a full ",[22,2495,117],{},". C is a fabricated performance claim; they compile to equivalent code. D dismisses the real exhaustiveness tradeoff just described.",[14,2498,2499,2517,2556],{},[17,2500,2502,2503,2506,2507,2509,2510,2512,2513,2516],{"id":2501},"q18-whats-the-best-practice-reason-to-prefer-let-somex-opt-else-return-let-else-over-a-match-with-an-unreachablepanicking-else-arm-when-you-need-x-bound-in-the-surrounding-scope-rather-than-nested-inside-a-block","Q18. What's the best-practice reason to prefer ",[22,2504,2505],{},"let Some(x) = opt else { return; };"," (\"let-else\") over a ",[22,2508,117],{}," with an unreachable\u002Fpanicking else-arm, when you need ",[22,2511,1450],{}," bound in the ",[1009,2514,2515],{},"surrounding"," scope rather than nested inside a block?",[31,2518,2520,2529,2540,2548],{"className":2519},[34],[36,2521,2523,45,2525,2528],{"className":2522},[39],[41,2524],{"disabled":43,"type":44},[22,2526,2527],{},"let else"," is the only way to bind a variable from a pattern match at all",[36,2530,2532,45,2534,2536,2537,2539],{"className":2531},[39],[41,2533],{"disabled":43,"type":44},[22,2535,2527],{}," keeps ",[22,2538,1450],{}," usable in the rest of the enclosing function body without an extra nested block or indentation level, while still forcing the \"else\" (failure) path to diverge (return, break, panic, etc.)",[36,2541,2543,45,2545,2547],{"className":2542},[39],[41,2544],{"disabled":43,"type":44},[22,2546,117],{}," cannot diverge in its arms",[36,2549,2551,45,2553,2555],{"className":2550},[39],[41,2552],{"disabled":43,"type":44},[22,2554,2527],{}," automatically logs a warning when the else branch runs",[82,2557,2558,2560,2568],{},[85,2559,87],{},[89,2561,2562,95,2564,2536,2566,2539],{},[92,2563,94],{},[22,2565,2527],{},[22,2567,1450],{},[89,2569,2570,45,2572,2574,2575,2577,2578,2580,2581,2584,2585,2587,2588,2590,2591,2593,2594,2596,2597,2600,2601,2603,2604,189,2606,2608,2609,2611,2612,240,2615,2618],{},[92,2571,102],{},[92,2573,2263],{}," with a plain ",[22,2576,117],{},", binding ",[22,2579,1450],{}," for use ",[1009,2582,2583],{},"after"," the match block requires either nesting the rest of the logic inside the ",[22,2586,677],{}," arm (extra indentation) or declaring ",[22,2589,1450],{}," outside and assigning inside (awkward with non-",[22,2592,2082],{},"\u002Fnon-default types). ",[22,2595,2527],{}," solves this cleanly: the happy-path binding flows into the normal scope, and the compiler enforces that the ",[22,2598,2599],{},"else"," block must diverge (never fall through), so ",[22,2602,1450],{}," is always known to be initialized past that point. A is false — ",[22,2605,121],{},[22,2607,117],{}," can both bind variables too. C is false — ",[22,2610,117],{}," arms can absolutely diverge with ",[22,2613,2614],{},"return",[22,2616,2617],{},"panic!","\u002Fetc.; that's exactly what makes the older equivalent pattern work. D is fabricated; no automatic logging happens.",[14,2620,2621,2639,2680],{},[17,2622,2624,2625,2628,2629,2631,2632,118,2635,2638],{"id":2623},"q19-a-team-is-deciding-between-representing-http-methods-as-enum-method-get-post-put-delete-versus-as-string-values-like-get-post-whats-the-best-practice-argument-for-the-enum","Q19. A team is deciding between representing HTTP methods as ",[22,2626,2627],{},"enum Method { Get, Post, Put, Delete }"," versus as ",[22,2630,325],{}," values like ",[22,2633,2634],{},"\"GET\"",[22,2636,2637],{},"\"POST\"",". What's the best-practice argument for the enum?",[31,2640,2642,2650,2663,2674],{"className":2641},[34],[36,2643,2645,45,2647,2649],{"className":2644},[39],[41,2646],{"disabled":43,"type":44},[22,2648,325],{}," comparisons are always slower, so the enum is purely a performance choice",[36,2651,2653,2655,2656,2659,2660,2662],{"className":2652},[39],[41,2654],{"disabled":43,"type":44}," The enum makes invalid states like ",[22,2657,2658],{},"Method::from(\"PATCH_TYPO\")"," unrepresentable — the compiler enforces that only the known, valid variants exist, and ",[22,2661,117],{}," exhaustiveness ensures every call site handles all of them (or is forced to update when a new one is added)",[36,2664,2666,45,2668,2670,2671,2673],{"className":2665},[39],[41,2667],{"disabled":43,"type":44},[22,2669,325],{}," cannot be used in a ",[22,2672,117],{}," statement at all",[36,2675,2677,2679],{"className":2676},[39],[41,2678],{"disabled":43,"type":44}," Enums are required for anything sent over a network",[82,2681,2682,2684,2693],{},[85,2683,87],{},[89,2685,2686,2688,2689,2659,2691,2662],{},[92,2687,94],{}," B — The enum makes invalid states like ",[22,2690,2658],{},[22,2692,117],{},[89,2694,2695,45,2697,2699,2700,2702,2703,2706,2707,2709,2710,240,2712,2715],{},[92,2696,102],{},[92,2698,2263],{}," this is the \"make illegal states unrepresentable\" principle that enums are especially good at — a ",[22,2701,325],{}," can hold literally any text, pushing validation to runtime (and every call site must remember to validate), while ",[22,2704,2705],{},"Method::Get"," is guaranteed by the type system to be one of the defined variants, with typos caught at compile time. A is a plausible-sounding but secondary justification; the primary win here is correctness\u002Fsafety, not raw comparison speed (though it can help too). C is false — ",[22,2708,117],{}," does work on ",[22,2711,325],{},[22,2713,2714],{},"&str"," via literal patterns, it's just less safe since it can't be exhaustive over \"all possible strings\" in a meaningful way. D is a fabricated blanket rule; plenty of network-serialized data uses strings, though enums are still often preferred internally with a serialization layer at the boundary.",[14,2717,2718,2730,2774],{},[17,2719,2721,2722,2725,2726,2729],{"id":2720},"q20-a-struct-field-is-typed-optionvecstring-to-represent-either-no-tags-or-a-list-of-tags-a-reviewer-suggests-changing-it-to-just-vecstring-using-an-empty-vec-for-no-tags-whats-the-tradeoff-to-consider","Q20. A struct field is typed ",[22,2723,2724],{},"Option\u003CVec\u003CString>>"," to represent \"either no tags, or a list of tags.\" A reviewer suggests changing it to just ",[22,2727,2728],{},"Vec\u003CString>"," (using an empty vec for \"no tags\"). What's the tradeoff to consider?",[31,2731,2733,2739,2756,2764],{"className":2732},[34],[36,2734,2736,2738],{"className":2735},[39],[41,2737],{"disabled":43,"type":44}," There's no difference — both represent \"no tags\" identically in every context",[36,2740,2742,45,2744,2746,2747,2750,2751,240,2753,2755],{"className":2741},[39],[41,2743],{"disabled":43,"type":44},[22,2745,2724],{}," distinguishes \"explicitly no tags were provided\u002Floaded\" from \"tags haven't been fetched\u002Fset yet,\" a distinction ",[22,2748,2749],{},"Vec::new()"," alone can't express, but at the cost of an extra ",[22,2752,677],{},[22,2754,113],{}," unwrap at every use site",[36,2757,2759,45,2761,2763],{"className":2758},[39],[41,2760],{"disabled":43,"type":44},[22,2762,2728],{}," cannot ever be empty, so this comparison is invalid",[36,2765,2767,45,2769,2771,2772],{"className":2766},[39],[41,2768],{"disabled":43,"type":44},[22,2770,2724],{}," is always more memory-efficient than ",[22,2773,2728],{},[82,2775,2776,2778,2790],{},[85,2777,87],{},[89,2779,2780,95,2782,2746,2784,2750,2786,240,2788,2755],{},[92,2781,94],{},[22,2783,2724],{},[22,2785,2749],{},[22,2787,677],{},[22,2789,113],{},[89,2791,2792,45,2794,2796,2797,2799,2800,448,2803,2806,2807,2810,2811,2814,2815,2817,2818,2820,2821,2823,2824,2826,2827,2829],{},[92,2793,102],{},[92,2795,2263],{}," this is a genuine, common judgment call — if \"not yet loaded\" and \"loaded but empty\" are meaningfully different states in your domain (e.g., lazily-fetched data, optional JSON fields distinguishing ",[22,2798,28],{}," from ",[22,2801,2802],{},"[]",[22,2804,2805],{},"Option\u003CVec\u003CT>>"," captures that distinction the type system can enforce. If they're not meaningfully different, plain ",[22,2808,2809],{},"Vec\u003CT>"," (empty vec = no tags) is simpler and avoids the extra layer of unwrapping\u002Fmatching at every call site — an empty ",[22,2812,2813],{},"Vec"," is already a perfectly valid, well-supported \"nothing here\" state, so wrapping it in ",[22,2816,1035],{}," for no reason is a common overcomplication. A ignores a real semantic distinction that matters in some domains. C is false — an empty ",[22,2819,2813],{}," is completely valid and common. D is a fabricated blanket memory claim that depends on context (e.g., ",[22,2822,2805],{}," adds a discriminant unless niche-optimized, and ",[22,2825,2813],{},"'s pointer typically isn't null-representable the same simple way ",[22,2828,141],{}," is, so this generalization doesn't reliably hold).",[2831,2832,2833],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}",{"title":260,"searchDepth":282,"depth":282,"links":2835},[2836,2838,2840,2841,2843,2845,2846,2848,2850,2852,2854,2856,2857,2859,2861,2863,2865,2867,2869,2871],{"id":19,"depth":291,"text":2837},"Q1. Why does Rust use Option\u003CT> instead of allowing references and values to be null?",{"id":150,"depth":291,"text":2839},"Q2. What are the two variants of Result\u003CT, E>, and what does each represent?",{"id":250,"depth":291,"text":251},{"id":411,"depth":291,"text":2842},"Q4. Given let msg = Message::Write(String::from(\"hi\"));, how do you correctly destructure it in a match without moving msg?",{"id":605,"depth":291,"text":2844},"Q5. What does calling .unwrap() on Option\u003CT> do when the value is None?",{"id":705,"depth":291,"text":706},{"id":772,"depth":291,"text":2847},"Q7. What does ? do when applied to a Result\u003CT, E> inside a function that itself returns Result\u003CT, E>?",{"id":1051,"depth":291,"text":2849},"Q8. What happens when you call .unwrap() on a Result::Err in production code with no catch_unwind or panic hook configured?",{"id":1236,"depth":291,"text":2851},"Q9. What is the size, in bytes, of Option\u003C&i32> on a 64-bit platform, compared to &i32 alone, and why?",{"id":1340,"depth":291,"text":2853},"Q10. What does an empty match on Option\u003CT> that omits the None arm do?",{"id":1493,"depth":291,"text":2855},"Q11. enum Never {} — an enum with zero variants — what can you do with a value of this type?",{"id":1570,"depth":291,"text":1571},{"id":1818,"depth":291,"text":2858},"Q13. In enum Shape { Circle(f64), Square(f64) }, is Circle(2.0) == Circle(2.0) valid, and under what condition?",{"id":1926,"depth":291,"text":2860},"Q14. What happens if you match on &Option\u003CString> and try to move the inner String out inside the match arm?",{"id":2181,"depth":291,"text":2862},"Q15. When designing a function that can fail, why is returning Result\u003CT, MyError> generally preferred over returning Option\u003CT> and discarding the reason for failure?",{"id":2301,"depth":291,"text":2864},"Q16. Code review flags a public function returning Result\u003CUser, String> where String is just a human-readable error message. What's the idiomatic improvement, and why?",{"id":2410,"depth":291,"text":2866},"Q17. Why is if let Some(x) = maybe_value { ... } often preferred over a full match when you only care about one variant and want to ignore the rest?",{"id":2501,"depth":291,"text":2868},"Q18. What's the best-practice reason to prefer let Some(x) = opt else { return; }; (\"let-else\") over a match with an unreachable\u002Fpanicking else-arm, when you need x bound in the surrounding scope rather than nested inside a block?",{"id":2623,"depth":291,"text":2870},"Q19. A team is deciding between representing HTTP methods as enum Method { Get, Post, Put, Delete } versus as String values like \"GET\", \"POST\". What's the best-practice argument for the enum?",{"id":2720,"depth":291,"text":2872},"Q20. A struct field is typed Option\u003CVec\u003CString>> to represent \"either no tags, or a list of tags.\" A reviewer suggests changing it to just Vec\u003CString> (using an empty vec for \"no tags\"). What's the tradeoff to consider?","md",{},"\u002Frust\u002F12-enums",{"title":5,"description":260},"rust\u002F12-enums","HT0QXHGT2tbDHDxngAjTFAzO1oSyWeczYNysOsNIGL4",1787335398395]