[{"data":1,"prerenderedAt":2628},["ShallowReactive",2],{"page-\u002Frust\u002F04-data-types":3},{"id":4,"title":5,"body":6,"description":30,"extension":2622,"meta":2623,"navigation":70,"path":2624,"seo":2625,"stem":2626,"__hash__":2627},"content\u002Frust\u002F04-data-types.md","04 — Data Types",{"type":7,"value":8,"toc":2588},"minimark",[9,13,129,202,359,451,614,699,878,1040,1169,1348,1506,1705,1804,1987,2072,2173,2287,2389,2491,2584],[10,11,5],"h1",{"id":12},"_04-data-types",[14,15,17,22,57,100],"question-wrapper",{"language":16},"rust",[18,19,21],"h3",{"id":20},"q1-what-is-the-default-integer-type-rust-infers-when-no-suffix-or-context-specifies-otherwise","Q1. What is the default integer type Rust infers when no suffix or context specifies otherwise?",[23,24,25],"code-wrapper",{"language":16},[26,27,31],"pre",{"className":28,"code":29,"language":16,"meta":30,"style":30},"language-rust shiki shiki-themes github-light github-dark","let x = 42;\n","",[32,33,34],"code",{"__ignoreMap":30},[35,36,39,43,47,50,54],"span",{"class":37,"line":38},"line",1,[35,40,42],{"class":41},"svdQ7","let",[35,44,46],{"class":45},"ssxIu"," x ",[35,48,49],{"class":41},"=",[35,51,53],{"class":52},"snvgF"," 42",[35,55,56],{"class":45},";\n",[58,59,62,76,84,92],"ul",{"className":60},[61],"contains-task-list",[63,64,67,72,73],"li",{"className":65},[66],"task-list-item",[68,69],"input",{"disabled":70,"type":71},true,"checkbox"," ",[32,74,75],{},"i64",[63,77,79,72,81],{"className":78},[66],[68,80],{"disabled":70,"type":71},[32,82,83],{},"i32",[63,85,87,72,89],{"className":86},[66],[68,88],{"disabled":70,"type":71},[32,90,91],{},"u32",[63,93,95,72,97],{"className":94},[66],[68,96],{"disabled":70,"type":71},[32,98,99],{},"isize",[101,102,103,107,117],"details",{},[104,105,106],"summary",{},"Show Answer",[108,109,110,114,115],"p",{},[111,112,113],"strong",{},"Answer:"," B — ",[32,116,83],{},[108,118,119,122,123,125,126,128],{},[111,120,121],{},"Explanation:"," When an integer literal's type can't be inferred from context (e.g. no explicit annotation, no usage that constrains it), Rust defaults to ",[32,124,83],{},", generally the fastest integer type on modern platforms even on 64-bit systems. ",[32,127,99],{}," (D) is instead the pointer-sized type used for indexing, not the default for bare literals.",[14,130,131,142,169],{},[18,132,134,135,137,138,141],{"id":133},"q2-what-are-isize-and-usize-primarily-used-for","Q2. What are ",[32,136,99],{}," and ",[32,139,140],{},"usize"," primarily used for?",[58,143,145,151,157,163],{"className":144},[61],[63,146,148,150],{"className":147},[66],[68,149],{"disabled":70,"type":71}," They are arbitrary-precision integer types with no fixed size",[63,152,154,156],{"className":153},[66],[68,155],{"disabled":70,"type":71}," Their size is platform-dependent (matching pointer width — e.g. 8 bytes on 64-bit systems), and they're primarily used for indexing collections and representing memory sizes\u002Foffsets",[63,158,160,162],{"className":159},[66],[68,161],{"disabled":70,"type":71}," They are always exactly 32 bits regardless of platform, used for network protocol fields",[63,164,166,168],{"className":165},[66],[68,167],{"disabled":70,"type":71}," They are floating-point types optimized for scientific computation",[101,170,171,173,178],{},[104,172,106],{},[108,174,175,177],{},[111,176,113],{}," B — Their size is platform-dependent, matching pointer width, and they're primarily used for indexing collections and memory sizes",[108,179,180,72,182,184,185,187,188,191,192,194,195,198,199,201],{},[111,181,121],{},[32,183,140],{},"\u002F",[32,186,99],{}," are defined to be exactly as wide as a pointer on the target platform (4 bytes on 32-bit, 8 bytes on 64-bit), which is why ",[32,189,190],{},"Vec::len()"," and slice indexing return\u002Faccept ",[32,193,140],{}," — indices can never exceed addressable memory. ",[111,196,197],{},"Portability:"," code that hardcodes assumptions like \"",[32,200,140],{}," is always 8 bytes\" (as option D of a fixed 32-bit width would imply) can break when cross-compiling to 32-bit or embedded targets.",[14,203,204,212,296,333],{"language":16},[18,205,207,208,211],{"id":206},"q3-what-does-this-program-print-when-run-with-cargo-run-debug-profile-the-default","Q3. What does this program print when run with ",[32,209,210],{},"cargo run"," (debug profile, the default)?",[23,213,214],{"language":16},[26,215,217],{"className":28,"code":216,"language":16,"meta":30,"style":30},"fn main() {\n    let x: u8 = 255;\n    let y = x + 1;\n    println!(\"{y}\");\n}\n",[32,218,219,231,254,274,290],{"__ignoreMap":30},[35,220,221,224,228],{"class":37,"line":38},[35,222,223],{"class":41},"fn",[35,225,227],{"class":226},"sIsaT"," main",[35,229,230],{"class":45},"() {\n",[35,232,234,237,240,243,246,249,252],{"class":37,"line":233},2,[35,235,236],{"class":41},"    let",[35,238,239],{"class":45}," x",[35,241,242],{"class":41},":",[35,244,245],{"class":226}," u8",[35,247,248],{"class":41}," =",[35,250,251],{"class":52}," 255",[35,253,56],{"class":45},[35,255,257,259,262,264,266,269,272],{"class":37,"line":256},3,[35,258,236],{"class":41},[35,260,261],{"class":45}," y ",[35,263,49],{"class":41},[35,265,46],{"class":45},[35,267,268],{"class":41},"+",[35,270,271],{"class":52}," 1",[35,273,56],{"class":45},[35,275,277,280,283,287],{"class":37,"line":276},4,[35,278,279],{"class":226},"    println!",[35,281,282],{"class":45},"(",[35,284,286],{"class":285},"sJ6F3","\"{y}\"",[35,288,289],{"class":45},");\n",[35,291,293],{"class":37,"line":292},5,[35,294,295],{"class":45},"}\n",[58,297,299,312,321,327],{"className":298},[61],[63,300,302,72,304,307,308,311],{"className":301},[66],[68,303],{"disabled":70,"type":71},[32,305,306],{},"0",", because ",[32,309,310],{},"u8"," silently wraps around on overflow",[63,313,315,72,317,320],{"className":314},[66],[68,316],{"disabled":70,"type":71},[32,318,319],{},"256",", because Rust automatically promotes to a wider type on overflow",[63,322,324,326],{"className":323},[66],[68,325],{"disabled":70,"type":71}," It panics at runtime with an \"attempt to add with overflow\" message, because debug builds include overflow checks",[63,328,330,332],{"className":329},[66],[68,331],{"disabled":70,"type":71}," Compile error, because the compiler statically proves this will overflow",[101,334,335,337,342],{},[104,336,106],{},[108,338,339,341],{},[111,340,113],{}," C — It panics at runtime with an \"attempt to add with overflow\" message, because debug builds include overflow checks",[108,343,344,72,346,349,350,354,355,358],{},[111,345,121],{},[111,347,348],{},"Debug:"," in debug\u002Fdev builds, arithmetic overflow triggers a runtime panic by default (a deliberate safety net during development); this is ",[351,352,353],"em",{},"not"," a compile-time error (ruling out D — the compiler doesn't generally prove overflow for non-constant expressions) and there is no automatic widening (ruling out B — Rust never implicitly changes an integer's type). To get the wraparound behavior some beginners expect, you'd need an explicit method like ",[32,356,357],{},"x.wrapping_add(1)",".",[14,360,361,369,413],{},[18,362,364,365,368],{"id":363},"q4-what-is-the-correct-way-to-describe-integer-overflow-behavior-in-release-builds-by-default","Q4. What is the correct way to describe integer overflow behavior in ",[32,366,367],{},"--release"," builds by default?",[58,370,372,378,391,407],{"className":371},[61],[63,373,375,377],{"className":374},[66],[68,376],{"disabled":70,"type":71}," Release builds panic on overflow just like debug builds, for consistency",[63,379,381,383,384,387,388,390],{"className":380},[66],[68,382],{"disabled":70,"type":71}," Release builds disable overflow checks by default and perform two's-complement wraparound silently (e.g., ",[32,385,386],{},"255u8 + 1"," becomes ",[32,389,306],{},") — a deliberate trade-off for performance",[63,392,394,396,397,400,401,403,404],{"className":393},[66],[68,395],{"disabled":70,"type":71}," Release builds return ",[32,398,399],{},"None"," from ",[32,402,268],{}," automatically, requiring ",[32,405,406],{},".unwrap()",[63,408,410,412],{"className":409},[66],[68,411],{"disabled":70,"type":71}," Overflow is undefined behavior in release builds, same as in C",[101,414,415,417,422],{},[104,416,106],{},[108,418,419,421],{},[111,420,113],{}," B — Release builds disable overflow checks by default and perform two's-complement wraparound silently — a deliberate trade-off for performance",[108,423,424,72,426,429,430,433,434,437,438,137,441,437,444,447,448,450],{},[111,425,121],{},[111,427,428],{},"Performance:"," the ",[32,431,432],{},"overflow-checks"," profile setting defaults to ",[32,435,436],{},"true"," in ",[32,439,440],{},"dev",[32,442,443],{},"false",[32,445,446],{},"release",", so the exact same overflowing code that panics in debug (Q3) silently wraps to ",[32,449,306],{}," in release — a classic and dangerous debug\u002Frelease behavior divergence. Unlike C's undefined behavior for signed overflow (D is false for Rust — Rust always defines wraparound as two's-complement, never UB, unlike C\u002FC++), so this is technically safe but can still produce silently wrong application results if unnoticed.",[14,452,453,461,524,568],{"language":16},[18,454,456,457,460],{"id":455},"q5-what-does-casting-with-as-do-in-this-example","Q5. What does casting with ",[32,458,459],{},"as"," do in this example?",[23,462,463],{"language":16},[26,464,466],{"className":28,"code":465,"language":16,"meta":30,"style":30},"fn main() {\n    let x: i32 = 300;\n    let y = x as u8;\n    println!(\"{y}\");\n}\n",[32,467,468,476,494,510,520],{"__ignoreMap":30},[35,469,470,472,474],{"class":37,"line":38},[35,471,223],{"class":41},[35,473,227],{"class":226},[35,475,230],{"class":45},[35,477,478,480,482,484,487,489,492],{"class":37,"line":233},[35,479,236],{"class":41},[35,481,239],{"class":45},[35,483,242],{"class":41},[35,485,486],{"class":226}," i32",[35,488,248],{"class":41},[35,490,491],{"class":52}," 300",[35,493,56],{"class":45},[35,495,496,498,500,502,504,506,508],{"class":37,"line":256},[35,497,236],{"class":41},[35,499,261],{"class":45},[35,501,49],{"class":41},[35,503,46],{"class":45},[35,505,459],{"class":41},[35,507,245],{"class":226},[35,509,56],{"class":45},[35,511,512,514,516,518],{"class":37,"line":276},[35,513,279],{"class":226},[35,515,282],{"class":45},[35,517,286],{"class":285},[35,519,289],{"class":45},[35,521,522],{"class":37,"line":292},[35,523,295],{"class":45},[58,525,527,539,545,557],{"className":526},[61],[63,528,530,532,533,536,537],{"className":529},[66],[68,531],{"disabled":70,"type":71}," Compile error: ",[32,534,535],{},"300"," does not fit in a ",[32,538,310],{},[63,540,542,544],{"className":541},[66],[68,543],{"disabled":70,"type":71}," Panics at runtime with an overflow error, same as arithmetic overflow",[63,546,548,72,550,553,554,556],{"className":547},[66],[68,549],{"disabled":70,"type":71},[32,551,552],{},"44"," — ",[32,555,459],{}," performs a truncating cast that keeps only the low 8 bits of the value's two's-complement representation, silently discarding the rest, in both debug and release",[63,558,560,72,562,307,565,567],{"className":559},[66],[68,561],{"disabled":70,"type":71},[32,563,564],{},"255",[32,566,459],{}," saturates to the target type's maximum value",[101,569,570,572,582],{},[104,571,106],{},[108,573,574,576,577,553,579,581],{},[111,575,113],{}," C — ",[32,578,552],{},[32,580,459],{}," performs a truncating cast that keeps only the low 8 bits, silently discarding the rest, in both debug and release",[108,583,584,586,587,589,590,592,593,595,596,599,600,603,604,607,608,611,612,358],{},[111,585,121],{}," Unlike arithmetic operators, ",[32,588,459],{}," numeric casts are ",[111,591,353],{}," checked for overflow in either debug or release — ",[32,594,535],{}," in binary is ",[32,597,598],{},"0b1_0010_1100","; truncating to 8 bits keeps ",[32,601,602],{},"0b0010_1100 = 44",". This silent truncation (no panic, no error, consistent across profiles) is a well-known gotcha distinct from arithmetic overflow's debug-only panic behavior (Q3\u002FQ4) — if you want saturating or checked conversion instead, use ",[32,605,606],{},"u8::try_from(x)"," (returns ",[32,609,610],{},"Result",") or the saturating conversion methods, not a bare ",[32,613,459],{},[14,615,616,624,663],{},[18,617,619,620,623],{"id":618},"q6-which-statement-correctly-describes-rusts-char-type","Q6. Which statement correctly describes Rust's ",[32,621,622],{},"char"," type?",[58,625,627,636,647,655],{"className":626},[61],[63,628,630,632,633,635],{"className":629},[66],[68,631],{"disabled":70,"type":71}," A ",[32,634,622],{}," is always exactly 1 byte, like in C",[63,637,639,632,641,643,644,646],{"className":638},[66],[68,640],{"disabled":70,"type":71},[32,642,622],{}," represents a single Unicode scalar value and is always 4 bytes in memory, which is not the same as \"one byte\" or even always \"one visual character\" (e.g. some emoji\u002Fgrapheme clusters require multiple ",[32,645,622],{},"s)",[63,648,650,632,652,654],{"className":649},[66],[68,651],{"disabled":70,"type":71},[32,653,622],{}," is a UTF-8 encoded byte sequence of variable length",[63,656,658,632,660,662],{"className":657},[66],[68,659],{"disabled":70,"type":71},[32,661,622],{}," can only represent ASCII characters",[101,664,665,667,675],{},[104,666,106],{},[108,668,669,671,672,674],{},[111,670,113],{}," B — A ",[32,673,622],{}," represents a single Unicode scalar value and is always 4 bytes in memory",[108,676,677,679,680,682,683,686,687,689,690,692,693,695,696,698],{},[111,678,121],{}," Rust's ",[32,681,622],{}," is a 32-bit value representing any Unicode Scalar Value (a subset of all Unicode code points, excluding surrogate halves), not a raw byte — this is different from indexing into a ",[32,684,685],{},"String","'s UTF-8 bytes, where individual bytes are ",[32,688,310],{},", not ",[32,691,622],{},". It's also not always one \"visual glyph\" — a grapheme cluster like a flag emoji or accented character built from combining marks can require multiple ",[32,694,622],{},"s to represent, which trips up naive character-counting code (contradicting the assumption in A that mirrors C's 1-byte ",[32,697,622],{},").",[14,700,701,705,799,844],{"language":16},[18,702,704],{"id":703},"q7-what-is-the-difference-between-a-tuple-and-an-array-in-rust","Q7. What is the difference between a tuple and an array in Rust?",[23,706,707],{"language":16},[26,708,710],{"className":28,"code":709,"language":16,"meta":30,"style":30},"let t: (i32, f64, bool) = (1, 2.0, true);\nlet a: [i32; 3] = [1, 2, 3];\n",[32,711,712,758],{"__ignoreMap":30},[35,713,714,716,719,721,724,726,729,732,734,737,740,742,744,747,749,752,754,756],{"class":37,"line":38},[35,715,42],{"class":41},[35,717,718],{"class":45}," t",[35,720,242],{"class":41},[35,722,723],{"class":45}," (",[35,725,83],{"class":226},[35,727,728],{"class":45},", ",[35,730,731],{"class":226},"f64",[35,733,728],{"class":45},[35,735,736],{"class":226},"bool",[35,738,739],{"class":45},") ",[35,741,49],{"class":41},[35,743,723],{"class":45},[35,745,746],{"class":52},"1",[35,748,728],{"class":45},[35,750,751],{"class":52},"2.0",[35,753,728],{"class":45},[35,755,436],{"class":52},[35,757,289],{"class":45},[35,759,760,762,765,767,770,772,775,778,781,783,785,787,789,792,794,796],{"class":37,"line":233},[35,761,42],{"class":41},[35,763,764],{"class":45}," a",[35,766,242],{"class":41},[35,768,769],{"class":45}," [",[35,771,83],{"class":226},[35,773,774],{"class":45},"; ",[35,776,777],{"class":52},"3",[35,779,780],{"class":45},"] ",[35,782,49],{"class":41},[35,784,769],{"class":45},[35,786,746],{"class":52},[35,788,728],{"class":45},[35,790,791],{"class":52},"2",[35,793,728],{"class":45},[35,795,777],{"class":52},[35,797,798],{"class":45},"];\n",[58,800,802,815,832,838],{"className":801},[61],[63,803,805,807,808,137,811,814],{"className":804},[66],[68,806],{"disabled":70,"type":71}," They are identical; ",[32,809,810],{},"(i32, f64, bool)",[32,812,813],{},"[i32; 3]"," are just two syntaxes for the same thing",[63,816,818,820,821,824,825,728,828,831],{"className":817},[66],[68,819],{"disabled":70,"type":71}," A tuple can hold elements of different types with a fixed length known at compile time; an array holds elements of a single type with a fixed length known at compile time — arrays are indexed with ",[32,822,823],{},"[]",", tuples with ",[32,826,827],{},".0",[32,829,830],{},".1",", etc.",[63,833,835,837],{"className":834},[66],[68,836],{"disabled":70,"type":71}," Arrays can hold mixed types, but tuples cannot",[63,839,841,843],{"className":840},[66],[68,842],{"disabled":70,"type":71}," Tuples are heap-allocated and growable, while arrays are always stack-allocated and fixed-size",[101,845,846,848,861],{},[104,847,106],{},[108,849,850,852,853,855,856,184,858,860],{},[111,851,113],{}," B — A tuple can hold elements of different types with a fixed compile-time length; an array holds a single element type with a fixed compile-time length; arrays use ",[32,854,823],{}," indexing, tuples use ",[32,857,827],{},[32,859,830],{},"\u002Fetc.",[108,862,863,865,866,869,870,873,874,877],{},[111,864,121],{}," Both are fixed-size, stack-allocatable (unless boxed) compound types, but they differ in type homogeneity and access syntax — ",[32,867,868],{},"t.0"," accesses a tuple field, while ",[32,871,872],{},"a[0]"," accesses an array element. Option D is backwards regarding growability: neither is growable — that's what ",[32,875,876],{},"Vec"," is for — and both are typically stack-allocated by default, not heap-allocated.",[14,879,880,884,942,1001],{"language":16},[18,881,883],{"id":882},"q8-what-happens-when-this-floating-point-comparison-runs","Q8. What happens when this floating-point comparison runs?",[23,885,886],{"language":16},[26,887,889],{"className":28,"code":888,"language":16,"meta":30,"style":30},"fn main() {\n    let x = 0.1 + 0.2;\n    println!(\"{}\", x == 0.3);\n}\n",[32,890,891,899,918,938],{"__ignoreMap":30},[35,892,893,895,897],{"class":37,"line":38},[35,894,223],{"class":41},[35,896,227],{"class":226},[35,898,230],{"class":45},[35,900,901,903,905,907,910,913,916],{"class":37,"line":233},[35,902,236],{"class":41},[35,904,46],{"class":45},[35,906,49],{"class":41},[35,908,909],{"class":52}," 0.1",[35,911,912],{"class":41}," +",[35,914,915],{"class":52}," 0.2",[35,917,56],{"class":45},[35,919,920,922,924,927,930,933,936],{"class":37,"line":256},[35,921,279],{"class":226},[35,923,282],{"class":45},[35,925,926],{"class":285},"\"{}\"",[35,928,929],{"class":45},", x ",[35,931,932],{"class":41},"==",[35,934,935],{"class":52}," 0.3",[35,937,289],{"class":45},[35,939,940],{"class":37,"line":276},[35,941,295],{"class":45},[58,943,945,960,987,995],{"className":944},[61],[63,946,948,72,950,952,953,956,957],{"className":947},[66],[68,949],{"disabled":70,"type":71},[32,951,436],{},", since ",[32,954,955],{},"0.1 + 0.2"," is mathematically ",[32,958,959],{},"0.3",[63,961,963,72,965,967,968,728,971,974,975,977,978,980,981,984,985],{"className":962},[66],[68,964],{"disabled":70,"type":71},[32,966,443],{}," — IEEE 754 binary floating-point cannot represent ",[32,969,970],{},"0.1",[32,972,973],{},"0.2",", or ",[32,976,959],{}," exactly, so ",[32,979,955],{}," yields ",[32,982,983],{},"0.30000000000000004",", which is not bit-for-bit equal to the literal ",[32,986,959],{},[63,988,990,992,993],{"className":989},[66],[68,991],{"disabled":70,"type":71}," Compile error: floating-point values cannot be compared with ",[32,994,932],{},[63,996,998,1000],{"className":997},[66],[68,999],{"disabled":70,"type":71}," It depends on whether the build is debug or release",[101,1002,1003,1005,1021],{},[104,1004,106],{},[108,1006,1007,114,1009,967,1011,728,1013,974,1015,977,1017,980,1019],{},[111,1008,113],{},[32,1010,443],{},[32,1012,970],{},[32,1014,973],{},[32,1016,959],{},[32,1018,955],{},[32,1020,983],{},[108,1022,1023,1025,1026,1028,1029,1031,1032,1035,1036,1039],{},[111,1024,121],{}," This is Rust's version of the classic cross-language floating-point \"wat\": ",[32,1027,731],{}," uses base-2 (binary) fractional representation, and decimal fractions like 0.1 are repeating binary fractions that get rounded to the nearest representable ",[32,1030,731],{},", so accumulated rounding error makes ",[32,1033,1034],{},"0.1 + 0.2 != 0.3"," bit-for-bit. Unlike overflow (Q3\u002FQ4), this behavior is identical in debug and release (ruling out D) — the fix in production code is comparing with an epsilon tolerance (e.g. ",[32,1037,1038],{},"(x - 0.3).abs() \u003C f64::EPSILON",") or using a decimal\u002Ffixed-point type when exactness matters.",[14,1041,1042,1046,1115,1144],{"language":16},[18,1043,1045],{"id":1044},"q9-what-is-the-result-of-indexing-an-array-out-of-bounds-with-a-compile-time-constant-index-as-shown-here","Q9. What is the result of indexing an array out of bounds with a compile-time-constant index, as shown here?",[23,1047,1048],{"language":16},[26,1049,1051],{"className":28,"code":1050,"language":16,"meta":30,"style":30},"fn main() {\n    let a = [1, 2, 3];\n    let x = a[5];\n    println!(\"{x}\");\n}\n",[32,1052,1053,1061,1084,1100,1111],{"__ignoreMap":30},[35,1054,1055,1057,1059],{"class":37,"line":38},[35,1056,223],{"class":41},[35,1058,227],{"class":226},[35,1060,230],{"class":45},[35,1062,1063,1065,1068,1070,1072,1074,1076,1078,1080,1082],{"class":37,"line":233},[35,1064,236],{"class":41},[35,1066,1067],{"class":45}," a ",[35,1069,49],{"class":41},[35,1071,769],{"class":45},[35,1073,746],{"class":52},[35,1075,728],{"class":45},[35,1077,791],{"class":52},[35,1079,728],{"class":45},[35,1081,777],{"class":52},[35,1083,798],{"class":45},[35,1085,1086,1088,1090,1092,1095,1098],{"class":37,"line":256},[35,1087,236],{"class":41},[35,1089,46],{"class":45},[35,1091,49],{"class":41},[35,1093,1094],{"class":45}," a[",[35,1096,1097],{"class":52},"5",[35,1099,798],{"class":45},[35,1101,1102,1104,1106,1109],{"class":37,"line":276},[35,1103,279],{"class":226},[35,1105,282],{"class":45},[35,1107,1108],{"class":285},"\"{x}\"",[35,1110,289],{"class":45},[35,1112,1113],{"class":37,"line":292},[35,1114,295],{"class":45},[58,1116,1118,1124,1130,1138],{"className":1117},[61],[63,1119,1121,1123],{"className":1120},[66],[68,1122],{"disabled":70,"type":71}," It compiles and panics at runtime with an index-out-of-bounds message",[63,1125,1127,1129],{"className":1126},[66],[68,1128],{"disabled":70,"type":71}," Compile error — since both the array's length and the index are known constants at compile time, the compiler statically rejects this rather than deferring to a runtime panic",[63,1131,1133,1135,1136],{"className":1132},[66],[68,1134],{"disabled":70,"type":71}," It compiles and returns a default value of ",[32,1137,306],{},[63,1139,1141,1143],{"className":1140},[66],[68,1142],{"disabled":70,"type":71}," It compiles and returns garbage\u002Fundefined memory contents, as in C",[101,1145,1146,1148,1153],{},[104,1147,106],{},[108,1149,1150,1152],{},[111,1151,113],{}," B — Compile error, because both the array's length and the index are known constants, letting the compiler statically reject it",[108,1154,1155,72,1157,1160,1161,1164,1165,1168],{},[111,1156,121],{},[111,1158,1159],{},"Safety:"," when the index and array size are both compile-time constants, ",[32,1162,1163],{},"rustc"," performs constant evaluation and rejects out-of-bounds access with a hard compile error (",[32,1166,1167],{},"this operation will panic at runtime"," \u002F index out of bounds lint promoted to a hard error) rather than waiting for a runtime panic. This is a genuine edge case beginners often get backwards — they expect all indexing errors to be runtime-only (as in the more general case of Q10, where the index is not a compile-time constant), but constant-folded indices are checked earlier. Undefined behavior (D) never occurs in safe Rust indexing, unlike C's raw array access.",[14,1170,1171,1175,1278,1314],{"language":16},[18,1172,1174],{"id":1173},"q10-what-happens-with-a-runtime-computed-non-constant-out-of-bounds-index","Q10. What happens with a runtime-computed (non-constant) out-of-bounds index?",[23,1176,1177],{"language":16},[26,1178,1180],{"className":28,"code":1179,"language":16,"meta":30,"style":30},"fn main() {\n    let a = [1, 2, 3];\n    let i = get_index();\n    println!(\"{}\", a[i]);\n}\n\nfn get_index() -> usize {\n    5\n}\n",[32,1181,1182,1190,1212,1227,1238,1242,1248,1267,1273],{"__ignoreMap":30},[35,1183,1184,1186,1188],{"class":37,"line":38},[35,1185,223],{"class":41},[35,1187,227],{"class":226},[35,1189,230],{"class":45},[35,1191,1192,1194,1196,1198,1200,1202,1204,1206,1208,1210],{"class":37,"line":233},[35,1193,236],{"class":41},[35,1195,1067],{"class":45},[35,1197,49],{"class":41},[35,1199,769],{"class":45},[35,1201,746],{"class":52},[35,1203,728],{"class":45},[35,1205,791],{"class":52},[35,1207,728],{"class":45},[35,1209,777],{"class":52},[35,1211,798],{"class":45},[35,1213,1214,1216,1219,1221,1224],{"class":37,"line":256},[35,1215,236],{"class":41},[35,1217,1218],{"class":45}," i ",[35,1220,49],{"class":41},[35,1222,1223],{"class":226}," get_index",[35,1225,1226],{"class":45},"();\n",[35,1228,1229,1231,1233,1235],{"class":37,"line":276},[35,1230,279],{"class":226},[35,1232,282],{"class":45},[35,1234,926],{"class":285},[35,1236,1237],{"class":45},", a[i]);\n",[35,1239,1240],{"class":37,"line":292},[35,1241,295],{"class":45},[35,1243,1245],{"class":37,"line":1244},6,[35,1246,1247],{"emptyLinePlaceholder":70},"\n",[35,1249,1251,1253,1255,1258,1261,1264],{"class":37,"line":1250},7,[35,1252,223],{"class":41},[35,1254,1223],{"class":226},[35,1256,1257],{"class":45},"() ",[35,1259,1260],{"class":41},"->",[35,1262,1263],{"class":226}," usize",[35,1265,1266],{"class":45}," {\n",[35,1268,1270],{"class":37,"line":1269},8,[35,1271,1272],{"class":52},"    5\n",[35,1274,1276],{"class":37,"line":1275},9,[35,1277,295],{"class":45},[58,1279,1281,1287,1293,1301],{"className":1280},[61],[63,1282,1284,1286],{"className":1283},[66],[68,1285],{"disabled":70,"type":71}," Compile error, identical to the constant-index case",[63,1288,1290,1292],{"className":1289},[66],[68,1291],{"disabled":70,"type":71}," It compiles successfully and panics at runtime with an \"index out of bounds\" message when executed",[63,1294,1296,1298,1299],{"className":1295},[66],[68,1297],{"disabled":70,"type":71}," It compiles and silently returns ",[32,1300,306],{},[63,1302,1304,1306,1307,1310,1311],{"className":1303},[66],[68,1305],{"disabled":70,"type":71}," It compiles and wraps around to ",[32,1308,1309],{},"a[5 % 3]",", i.e. ",[32,1312,1313],{},"a[2]",[101,1315,1316,1318,1323],{},[104,1317,106],{},[108,1319,1320,1322],{},[111,1321,113],{}," B — It compiles successfully and panics at runtime with an \"index out of bounds\" message when executed",[108,1324,1325,72,1327,1329,1330,1333,1334,1337,1338,1341,1342,723,1345,1347],{},[111,1326,121],{},[111,1328,1159],{}," because ",[32,1331,1332],{},"i","'s value isn't known until runtime, the compiler cannot statically reject it as it did in Q9 — instead, array\u002Fslice indexing always performs a bounds check at runtime, panicking (",[32,1335,1336],{},"index out of bounds: the len is 3 but the index is 5",") rather than silently wrapping (D, a C-like buffer-overrun assumption) or returning a default (C). The safe alternative to avoid the panic is ",[32,1339,1340],{},"a.get(i)",", which returns ",[32,1343,1344],{},"Option\u003C&i32>",[32,1346,399],{}," here) instead of panicking.",[14,1349,1350,1354,1419,1462],{"language":16},[18,1351,1353],{"id":1352},"q11-what-is-the-result-of-this-signedunsigned-cast","Q11. What is the result of this signed\u002Funsigned cast?",[23,1355,1356],{"language":16},[26,1357,1359],{"className":28,"code":1358,"language":16,"meta":30,"style":30},"fn main() {\n    let x: i32 = -1;\n    let y = x as u32;\n    println!(\"{y}\");\n}\n",[32,1360,1361,1369,1388,1405,1415],{"__ignoreMap":30},[35,1362,1363,1365,1367],{"class":37,"line":38},[35,1364,223],{"class":41},[35,1366,227],{"class":226},[35,1368,230],{"class":45},[35,1370,1371,1373,1375,1377,1379,1381,1384,1386],{"class":37,"line":233},[35,1372,236],{"class":41},[35,1374,239],{"class":45},[35,1376,242],{"class":41},[35,1378,486],{"class":226},[35,1380,248],{"class":41},[35,1382,1383],{"class":41}," -",[35,1385,746],{"class":52},[35,1387,56],{"class":45},[35,1389,1390,1392,1394,1396,1398,1400,1403],{"class":37,"line":256},[35,1391,236],{"class":41},[35,1393,261],{"class":45},[35,1395,49],{"class":41},[35,1397,46],{"class":45},[35,1399,459],{"class":41},[35,1401,1402],{"class":226}," u32",[35,1404,56],{"class":45},[35,1406,1407,1409,1411,1413],{"class":37,"line":276},[35,1408,279],{"class":226},[35,1410,282],{"class":45},[35,1412,286],{"class":285},[35,1414,289],{"class":45},[35,1416,1417],{"class":37,"line":292},[35,1418,295],{"class":45},[58,1420,1422,1428,1434,1454],{"className":1421},[61],[63,1423,1425,1427],{"className":1424},[66],[68,1426],{"disabled":70,"type":71}," Compile error: cannot cast a negative value to an unsigned type",[63,1429,1431,1433],{"className":1430},[66],[68,1432],{"disabled":70,"type":71}," Panics at runtime: negative value cannot be represented as unsigned",[63,1435,1437,72,1439,1442,1443,1446,1447,1450,1451],{"className":1436},[66],[68,1438],{"disabled":70,"type":71},[32,1440,1441],{},"4294967295"," — the cast reinterprets ",[32,1444,1445],{},"-1","'s two's-complement bit pattern (",[32,1448,1449],{},"0xFFFFFFFF",") as an unsigned value, i.e. ",[32,1452,1453],{},"u32::MAX",[63,1455,1457,72,1459,1461],{"className":1456},[66],[68,1458],{"disabled":70,"type":71},[32,1460,306],{},", because negative values saturate to the unsigned minimum",[101,1463,1464,1466,1477],{},[104,1465,106],{},[108,1467,1468,576,1470,1442,1472,1474,1475],{},[111,1469,113],{},[32,1471,1441],{},[32,1473,1445],{},"'s two's-complement bit pattern as an unsigned value, i.e. ",[32,1476,1453],{},[108,1478,1479,1481,1482,1484,1485,1488,1489,1491,1492,1494,1495,1497,1498,1501,1502,1505],{},[111,1480,121],{}," As with the truncating cast in Q5, ",[32,1483,459],{}," between integer types of the same width just reinterprets the bit pattern rather than doing \"safe\" numeric conversion — ",[32,1486,1487],{},"-1i32","'s bits are all ones, which as ",[32,1490,91],{}," is the maximum value ",[32,1493,1441],{},". This silent, non-panicking reinterpretation (no compile error, no runtime panic, consistent in debug and release) is a frequent source of subtle bugs when developers assume ",[32,1496,459],{}," behaves like a checked conversion; use ",[32,1499,1500],{},"u32::try_from(x)"," if you want a ",[32,1503,1504],{},"Result::Err"," on negative input instead.",[14,1507,1508,1516,1608,1659],{"language":16},[18,1509,1511,1512,1515],{"id":1510},"q12-what-does-this-code-do-with-an-empty-tuple","Q12. What does this code do with an empty tuple ",[32,1513,1514],{},"()","?",[23,1517,1518],{"language":16},[26,1519,1521],{"className":28,"code":1520,"language":16,"meta":30,"style":30},"fn log_event(msg: &str) -> () {\n    println!(\"{msg}\");\n}\n\nfn main() {\n    let result = log_event(\"started\");\n    println!(\"{result:?}\");\n}\n",[32,1522,1523,1548,1559,1563,1567,1575,1593,1604],{"__ignoreMap":30},[35,1524,1525,1527,1530,1533,1535,1538,1541,1543,1545],{"class":37,"line":38},[35,1526,223],{"class":41},[35,1528,1529],{"class":226}," log_event",[35,1531,1532],{"class":45},"(msg",[35,1534,242],{"class":41},[35,1536,1537],{"class":41}," &",[35,1539,1540],{"class":226},"str",[35,1542,739],{"class":45},[35,1544,1260],{"class":41},[35,1546,1547],{"class":45}," () {\n",[35,1549,1550,1552,1554,1557],{"class":37,"line":233},[35,1551,279],{"class":226},[35,1553,282],{"class":45},[35,1555,1556],{"class":285},"\"{msg}\"",[35,1558,289],{"class":45},[35,1560,1561],{"class":37,"line":256},[35,1562,295],{"class":45},[35,1564,1565],{"class":37,"line":276},[35,1566,1247],{"emptyLinePlaceholder":70},[35,1568,1569,1571,1573],{"class":37,"line":292},[35,1570,223],{"class":41},[35,1572,227],{"class":226},[35,1574,230],{"class":45},[35,1576,1577,1579,1582,1584,1586,1588,1591],{"class":37,"line":1244},[35,1578,236],{"class":41},[35,1580,1581],{"class":45}," result ",[35,1583,49],{"class":41},[35,1585,1529],{"class":226},[35,1587,282],{"class":45},[35,1589,1590],{"class":285},"\"started\"",[35,1592,289],{"class":45},[35,1594,1595,1597,1599,1602],{"class":37,"line":1250},[35,1596,279],{"class":226},[35,1598,282],{"class":45},[35,1600,1601],{"class":285},"\"{result:?}\"",[35,1603,289],{"class":45},[35,1605,1606],{"class":37,"line":1269},[35,1607,295],{"class":45},[58,1609,1611,1619,1637,1650],{"className":1610},[61],[63,1612,1614,532,1616,1618],{"className":1613},[66],[68,1615],{"disabled":70,"type":71},[32,1617,1514],{}," is not a valid return type",[63,1620,1622,1624,1625,1628,1629,952,1631,1633,1634],{"className":1621},[66],[68,1623],{"disabled":70,"type":71}," It compiles and prints ",[32,1626,1627],{},"started"," followed by ",[32,1630,1514],{},[32,1632,1514],{}," (the \"unit type\") is the zero-sized type conventionally used to mean \"no meaningful value,\" and it implements ",[32,1635,1636],{},"Debug",[63,1638,1640,1642,1643,1646,1647,1649],{"className":1639},[66],[68,1641],{"disabled":70,"type":71}," It compiles but ",[32,1644,1645],{},"result"," cannot be printed because ",[32,1648,1514],{}," has no fields",[63,1651,1653,72,1655,1658],{"className":1652},[66],[68,1654],{"disabled":70,"type":71},[32,1656,1657],{},"-> ()"," is redundant syntax error; functions with no return type must omit the arrow entirely",[101,1660,1661,1663,1677],{},[104,1662,106],{},[108,1664,1665,1667,1668,1628,1670,774,1672,1674,1675],{},[111,1666,113],{}," B — It compiles and prints ",[32,1669,1627],{},[32,1671,1514],{},[32,1673,1514],{}," is the unit type conventionally used for \"no meaningful value,\" and it implements ",[32,1676,1636],{},[108,1678,1679,72,1681,1683,1684,1687,1688,1690,1691,1693,1694,1696,1697,1700,1701,1704],{},[111,1680,121],{},[32,1682,1514],{},", the unit type, is what a function implicitly returns when no ",[32,1685,1686],{},"-> Type"," is written at all (",[32,1689,1657],{}," here is just the explicit, equivalent spelling — idiomatically omitted, but not an error, contradicting D). It's a real, zero-sized value that implements ",[32,1692,1636],{}," (printing as literally ",[32,1695,1514],{},"), so ",[32,1698,1699],{},"println!(\"{result:?}\")"," works fine — it's not the absence of a value like ",[32,1702,1703],{},"void"," conceptually implies in some other languages, but an actual (if trivial) value that can be bound, passed around, and matched on.",[14,1706,1707,1714,1757],{},[18,1708,1710,1711,1713],{"id":1709},"q13-what-is-the-maximum-safely-representable-integer-using-f64-such-that-all-integers-up-to-that-value-can-be-represented-exactly","Q13. What is the maximum safely representable integer using ",[32,1712,731],{}," such that all integers up to that value can be represented exactly?",[58,1715,1717,1729,1740,1751],{"className":1716},[61],[63,1718,1720,72,1722,1725,1726,1728],{"className":1719},[66],[68,1721],{"disabled":70,"type":71},[32,1723,1724],{},"2^53"," (about 9 quadrillion), because ",[32,1727,731],{}," has a 52-bit mantissa (53 bits with the implicit leading bit), beyond which not every integer has an exact representation",[63,1730,1732,72,1734,1736,1737,1739],{"className":1731},[66],[68,1733],{"disabled":70,"type":71},[32,1735,731],{}," can represent all ",[32,1738,75],{}," integers exactly with no limit, since it's a 64-bit type",[63,1741,1743,72,1745,1748,1749],{"className":1742},[66],[68,1744],{"disabled":70,"type":71},[32,1746,1747],{},"2^32",", matching ",[32,1750,1453],{},[63,1752,1754,1756],{"className":1753},[66],[68,1755],{"disabled":70,"type":71}," There is no such limit; floating point can represent any integer exactly",[101,1758,1759,1761,1771],{},[104,1760,106],{},[108,1762,1763,1765,1766,307,1768,1770],{},[111,1764,113],{}," A — ",[32,1767,1724],{},[32,1769,731],{},"'s 52-bit mantissa (plus implicit leading bit) limits exact integer representation beyond that point",[108,1772,1773,1775,1776,1778,1779,1781,1782,1784,1785,1787,1788,1790,1791,1794,1795,1798,1799,184,1801,358],{},[111,1774,121],{}," An IEEE 754 ",[32,1777,731],{}," has 1 sign bit, 11 exponent bits, and 52 explicit mantissa bits (53 bits of precision including the implicit leading ",[32,1780,746],{},"), so integers beyond ",[32,1783,1724],{}," start silently losing precision when represented as ",[32,1786,731],{}," — a tempting-but-wrong assumption (B) is that all 64-bit values fit, since ",[32,1789,731],{},"'s ",[351,1792,1793],{},"total"," bit width is 64 but its ",[351,1796,1797],{},"mantissa"," width is what actually limits integer precision, unlike a genuinely 64-bit-precision integer type like ",[32,1800,75],{},[32,1802,1803],{},"u64",[14,1805,1806,1810,1871,1923],{"language":16},[18,1807,1809],{"id":1808},"q14-what-happens-when-parsing-an-out-of-range-value-into-a-fixed-width-integer-type","Q14. What happens when parsing an out-of-range value into a fixed-width integer type?",[23,1811,1812],{"language":16},[26,1813,1815],{"className":28,"code":1814,"language":16,"meta":30,"style":30},"fn main() {\n    let result: Result\u003Cu8, _> = \"300\".parse();\n    println!(\"{result:?}\");\n}\n",[32,1816,1817,1825,1857,1867],{"__ignoreMap":30},[35,1818,1819,1821,1823],{"class":37,"line":38},[35,1820,223],{"class":41},[35,1822,227],{"class":226},[35,1824,230],{"class":45},[35,1826,1827,1829,1832,1834,1837,1840,1842,1845,1847,1850,1852,1855],{"class":37,"line":233},[35,1828,236],{"class":41},[35,1830,1831],{"class":45}," result",[35,1833,242],{"class":41},[35,1835,1836],{"class":226}," Result",[35,1838,1839],{"class":45},"\u003C",[35,1841,310],{"class":226},[35,1843,1844],{"class":45},", _> ",[35,1846,49],{"class":41},[35,1848,1849],{"class":285}," \"300\"",[35,1851,358],{"class":41},[35,1853,1854],{"class":226},"parse",[35,1856,1226],{"class":45},[35,1858,1859,1861,1863,1865],{"class":37,"line":256},[35,1860,279],{"class":226},[35,1862,282],{"class":45},[35,1864,1601],{"class":285},[35,1866,289],{"class":45},[35,1868,1869],{"class":37,"line":276},[35,1870,295],{"class":45},[58,1872,1874,1886,1905,1913],{"className":1873},[61],[63,1875,1877,72,1879,1882,1883,1885],{"className":1876},[66],[68,1878],{"disabled":70,"type":71},[32,1880,1881],{},"Ok(44)",", applying the same truncation behavior as an ",[32,1884,459],{}," cast",[63,1887,1889,72,1891,307,1894,1897,1898,1901,1902,1904],{"className":1888},[66],[68,1890],{"disabled":70,"type":71},[32,1892,1893],{},"Err(ParseIntError { .. })",[32,1895,1896],{},".parse()"," performs a checked conversion and returns an ",[32,1899,1900],{},"Err"," when the value doesn't fit the target type, unlike ",[32,1903,459],{}," which silently truncates",[63,1906,1908,1910,1911],{"className":1907},[66],[68,1909],{"disabled":70,"type":71}," It panics at runtime instead of returning a ",[32,1912,610],{},[63,1914,1916,1918,1919,1922],{"className":1915},[66],[68,1917],{"disabled":70,"type":71}," Compile error, because ",[32,1920,1921],{},"\"300\""," is a string literal too large for the target type",[101,1924,1925,1927,1940],{},[104,1926,106],{},[108,1928,1929,114,1931,307,1933,1897,1935,1937,1938],{},[111,1930,113],{},[32,1932,1893],{},[32,1934,1896],{},[32,1936,1900],{}," when the value doesn't fit, unlike ",[32,1939,459],{},[108,1941,1942,72,1944,1947,1948,1950,1951,1954,1955,1957,1958,1961,1962,1965,1966,1968,1969,1971,1972,1974,1975,728,1978,974,1980,184,1983,1986],{},[111,1943,121],{},[32,1945,1946],{},"str::parse::\u003Cu8>()"," explicitly checks that the parsed numeric value fits within ",[32,1949,310],{},"'s range (",[32,1952,1953],{},"0..=255",") and returns ",[32,1956,1900],{}," (specifically a ",[32,1959,1960],{},"ParseIntError"," with kind ",[32,1963,1964],{},"PosOverflow",") rather than truncating — this is a deliberate contrast with ",[32,1967,459],{},"'s silent truncation (Q5), and a good example of why ",[32,1970,1896],{}," is the safer choice for untrusted\u002Fexternal input. The correct way to handle this ",[32,1973,1900],{}," case is via ",[32,1976,1977],{},"match",[32,1979,1515],{},[32,1981,1982],{},".unwrap_or_default()",[32,1984,1985],{},".unwrap_or(default)"," depending on whether the caller can recover, rather than assuming parsing always succeeds.",[14,1988,1989,2002,2044],{},[18,1990,1992,1993,1996,1997,1999,2000,1515],{"id":1991},"q15-when-should-you-prefer-an-explicit-width-integer-type-like-u16-or-i64-over-the-default-i32","Q15. When should you prefer an explicit-width integer type like ",[32,1994,1995],{},"u16"," or ",[32,1998,75],{}," over the default ",[32,2001,83],{},[58,2003,2005,2014,2032,2038],{"className":2004},[61],[63,2006,2008,2010,2011,2013],{"className":2007},[66],[68,2009],{"disabled":70,"type":71}," Never — always use ",[32,2012,83],{}," everywhere for consistency regardless of the value's actual domain",[63,2015,2017,2019,2020,2022,2023,184,2025,2027,2028,2031],{"className":2016},[66],[68,2018],{"disabled":70,"type":71}," When the value's valid domain and required range are known and meaningful (e.g. a ",[32,2021,1995],{}," port number capped at 65535, or an ",[32,2024,75],{},[32,2026,1803],{}," for a value that can exceed ",[32,2029,2030],{},"i32::MAX"," like a file size in bytes or a timestamp) — this documents intent and avoids both wasted space and overflow risk",[63,2033,2035,2037],{"className":2034},[66],[68,2036],{"disabled":70,"type":71}," Only when targeting embedded\u002Fno_std platforms; on desktop\u002Fserver code, width never matters",[63,2039,2041,2043],{"className":2040},[66],[68,2042],{"disabled":70,"type":71}," Always prefer the smallest type that compiles without error, regardless of whether the value could plausibly grow",[101,2045,2046,2048,2053],{},[104,2047,106],{},[108,2049,2050,2052],{},[111,2051,113],{}," B — When the value's valid domain and required range are known and meaningful, choosing an explicit width documents intent and avoids wasted space or overflow risk",[108,2054,2055,72,2057,2060,2061,2063,2064,184,2066,2068,2069,2071],{},[111,2056,121],{},[111,2058,2059],{},"Idiom:"," using ",[32,2062,1995],{}," for a network port or ",[32,2065,75],{},[32,2067,1803],{}," for byte counts\u002Ftimestamps is self-documenting and prevents a class of bugs where a value that can legitimately exceed ",[32,2070,2030],{}," (about 2.1 billion — easily exceeded by file sizes or millisecond timestamps) silently overflows in release builds (recall Q4). Blindly picking the smallest type that merely compiles today (D) is a trap — it says nothing about whether the value could grow beyond that type's range in production, which is exactly the kind of \"compiles now, panics\u002Fwraps later\" bug this rule of thumb prevents.",[14,2073,2074,2084,2133],{},[18,2075,2077,2078,2080,2081,2083],{"id":2076},"q16-what-is-the-idiomatic-way-to-convert-between-numeric-types-when-the-values-validity-at-the-target-type-must-be-guaranteed-rather-than-assumed-eg-converting-a-user-supplied-i64-amount-into-a-u32-quantity-field","Q16. What is the idiomatic way to convert between numeric types when the value's validity at the target type must be guaranteed rather than assumed, e.g. converting a user-supplied ",[32,2079,75],{}," amount into a ",[32,2082,91],{}," quantity field?",[58,2085,2087,2096,2118,2127],{"className":2086},[61],[63,2088,2090,2092,2093,2095],{"className":2089},[66],[68,2091],{"disabled":70,"type":71}," Always use ",[32,2094,459],{},", since it's the shortest syntax and Rust guarantees it never loses data",[63,2097,2099,2101,2102,2105,2106,2108,2109,728,2111,2113,2114,2117],{"className":2098},[66],[68,2100],{"disabled":70,"type":71}," Use ",[32,2103,2104],{},"u32::try_from(value)",", which returns a ",[32,2107,610],{}," that must be handled (via ",[32,2110,1515],{},[32,2112,1977],{},", or explicit ",[32,2115,2116],{},".expect()"," with a justified message), making conversion failure an explicit, visible part of the control flow",[63,2119,2121,2101,2123,2126],{"className":2120},[66],[68,2122],{"disabled":70,"type":71},[32,2124,2125],{},"unsafe { std::mem::transmute(value) }"," to reinterpret the bits directly",[63,2128,2130,2132],{"className":2129},[66],[68,2131],{"disabled":70,"type":71}," Multiply and divide by powers of two manually to simulate the conversion",[101,2134,2135,2137,2147],{},[104,2136,106],{},[108,2138,2139,2141,2142,2105,2144,2146],{},[111,2140,113],{}," B — Use ",[32,2143,2104],{},[32,2145,610],{}," that must be handled, making conversion failure explicit",[108,2148,2149,72,2151,72,2153,184,2156,2159,2160,2162,2163,2165,2166,2168,2169,2172],{},[111,2150,121],{},[111,2152,1159],{},[32,2154,2155],{},"TryFrom",[32,2157,2158],{},"TryInto"," conversions surface out-of-range or negative values as an ",[32,2161,1900],{}," at the call site instead of silently truncating\u002Freinterpreting bits the way ",[32,2164,459],{}," does (Q5, Q11) — critical for values crossing a trust boundary (user input, network data, file parsing). ",[32,2167,459],{}," (A) is the tempting-but-dangerous default precisely because it \"just works\" syntactically while silently corrupting out-of-range values with no warning; ",[32,2170,2171],{},"transmute"," (C) is unrelated and unsafe low-level bit reinterpretation, wildly inappropriate for a simple numeric conversion.",[14,2174,2175,2179,2221,2260],{"language":16},[18,2176,2178],{"id":2177},"q17-what-is-the-idiomatic-and-safe-way-to-compare-two-floating-point-values-for-near-equality-avoiding-the-pitfall-in-q8","Q17. What is the idiomatic and safe way to compare two floating-point values for near-equality, avoiding the pitfall in Q8?",[23,2180,2181],{"language":16},[26,2182,2184],{"className":28,"code":2183,"language":16,"meta":30,"style":30},"let a = 0.1_f64 + 0.2;\nlet b = 0.3_f64;\n",[32,2185,2186,2205],{"__ignoreMap":30},[35,2187,2188,2190,2192,2194,2197,2199,2201,2203],{"class":37,"line":38},[35,2189,42],{"class":41},[35,2191,1067],{"class":45},[35,2193,49],{"class":41},[35,2195,2196],{"class":52}," 0.1_",[35,2198,731],{"class":226},[35,2200,912],{"class":41},[35,2202,915],{"class":52},[35,2204,56],{"class":45},[35,2206,2207,2209,2212,2214,2217,2219],{"class":37,"line":233},[35,2208,42],{"class":41},[35,2210,2211],{"class":45}," b ",[35,2213,49],{"class":41},[35,2215,2216],{"class":52}," 0.3_",[35,2218,731],{"class":226},[35,2220,56],{"class":45},[58,2222,2224,2233,2242,2251],{"className":2223},[61],[63,2225,2227,72,2229,2232],{"className":2226},[66],[68,2228],{"disabled":70,"type":71},[32,2230,2231],{},"a == b",", trusting exact equality since both are the same type",[63,2234,2236,72,2238,2241],{"className":2235},[66],[68,2237],{"disabled":70,"type":71},[32,2239,2240],{},"(a - b).abs() \u003C f64::EPSILON"," or a domain-appropriate tolerance, since binary floating-point arithmetic accumulates rounding error and exact equality is unreliable for computed values",[63,2243,2245,2247,2248,2250],{"className":2244},[66],[68,2246],{"disabled":70,"type":71}," Convert both to ",[32,2249,685],{}," and compare the strings",[63,2252,2254,72,2256,2259],{"className":2253},[66],[68,2255],{"disabled":70,"type":71},[32,2257,2258],{},"a.round() == b.round()",", since rounding always eliminates floating-point error",[101,2261,2262,2264,2271],{},[104,2263,106],{},[108,2265,2266,114,2268,2270],{},[111,2267,113],{},[32,2269,2240],{}," or a domain-appropriate tolerance, since binary floating-point arithmetic accumulates rounding error",[108,2272,2273,72,2275,1329,2277,2279,2280,2282,2283,2286],{},[111,2274,121],{},[111,2276,2059],{},[32,2278,731],{}," cannot exactly represent most decimal fractions (Q8), idiomatic Rust (like most languages using IEEE 754) compares floats with an epsilon-based tolerance rather than ",[32,2281,932],{},", especially after any arithmetic has occurred. Rounding first (D) is a fragile workaround that only coincidentally works for values far from a rounding boundary and breaks down near ",[32,2284,2285],{},"x.5"," boundaries or when more precision is actually needed; string comparison (C) is needlessly indirect and has its own formatting-precision pitfalls.",[14,2288,2289,2303,2349],{},[18,2290,2292,2293,2295,2296,2299,2300,1515],{"id":2291},"q18-a-function-needs-to-represent-a-2d-coordinate-pair-that-will-always-have-exactly-two-f64-values-and-no-more-what-is-more-idiomatic-a-tuple-f64-f64-or-a-two-element-vecf64","Q18. A function needs to represent \"a 2D coordinate pair\" that will always have exactly two ",[32,2294,731],{}," values and no more. What is more idiomatic — a tuple ",[32,2297,2298],{},"(f64, f64)"," or a two-element ",[32,2301,2302],{},"Vec\u003Cf64>",[58,2304,2306,2314,2330,2340],{"className":2305},[61],[63,2307,2309,72,2311,2313],{"className":2308},[66],[68,2310],{"disabled":70,"type":71},[32,2312,2302],{},", since vectors are always more efficient than tuples",[63,2315,2317,2319,2320,2322,2323,2326,2327,2329],{"className":2316},[66],[68,2318],{"disabled":70,"type":71}," A tuple ",[32,2321,2298],{},", or better yet a small named ",[32,2324,2325],{},"struct Point { x: f64, y: f64 }"," — since the size (2) is fixed and known, a ",[32,2328,876],{}," would incorrectly imply a runtime-variable length and adds unnecessary heap allocation and indirection",[63,2331,2333,2335,2336,2339],{"className":2332},[66],[68,2334],{"disabled":70,"type":71}," Neither; only arrays ",[32,2337,2338],{},"[f64; 2]"," are valid for fixed-size numeric data",[63,2341,2343,2345,2346,2348],{"className":2342},[66],[68,2344],{"disabled":70,"type":71}," It makes no practical difference; ",[32,2347,876],{},", tuple, and array are fully interchangeable in all Rust APIs",[101,2350,2351,2353,2367],{},[104,2352,106],{},[108,2354,2355,2357,2358,2360,2361,2363,2364,2366],{},[111,2356,113],{}," B — A tuple ",[32,2359,2298],{},", or better a named ",[32,2362,2325],{}," — since size is fixed, ",[32,2365,876],{}," wrongly implies variable length and adds needless heap allocation",[108,2368,2369,72,2371,72,2373,2376,2377,184,2380,2383,2384,184,2386,2388],{},[111,2370,121],{},[111,2372,2059],{},[32,2374,2375],{},"Vec\u003CT>"," is heap-allocated and growable\u002Fshrinkable at runtime — reaching for it when the length is a fixed, compile-time-known constant (like a 2D point) is both a performance cost (unnecessary allocation\u002Findirection) and a readability\u002FAPI-design smell, since it implies the length could vary when it never does. A named struct is generally preferred over a bare tuple once fields have clear semantic roles (",[32,2378,2379],{},"x",[32,2381,2382],{},"y"," versus ",[32,2385,827],{},[32,2387,830],{},"), improving self-documentation, though the tuple is not wrong, just less expressive.",[14,2390,2391,2398,2451],{},[18,2392,2394,2395,2397],{"id":2393},"q19-what-is-the-best-practice-way-to-handle-a-computation-that-might-overflow-in-a-context-where-overflow-represents-a-genuine-expected-possibility-eg-summing-user-supplied-quantities-that-could-exceed-u32max-rather-than-a-programmer-bug","Q19. What is the best-practice way to handle a computation that might overflow in a context where overflow represents a genuine, expected possibility (e.g. summing user-supplied quantities that could exceed ",[32,2396,1453],{},"), rather than a programmer bug?",[58,2399,2401,2407,2428,2441],{"className":2400},[61],[63,2402,2404,2406],{"className":2403},[66],[68,2405],{"disabled":70,"type":71}," Rely on debug-mode panics to catch it during testing and ship release builds as-is, trusting silent wraparound is fine for production",[63,2408,2410,2101,2412,1341,2415,723,2418,2420,2421,184,2424,2427],{"className":2409},[66],[68,2411],{"disabled":70,"type":71},[32,2413,2414],{},"checked_add",[32,2416,2417],{},"Option\u003CT>",[32,2419,399],{}," on overflow), or ",[32,2422,2423],{},"saturating_add",[32,2425,2426],{},"wrapping_add"," depending on whether the correct domain behavior is to clamp, wrap, or explicitly reject the overflowing case — chosen deliberately rather than relying on the default panic\u002Fwrap split between debug and release",[63,2429,2431,2433,2434,184,2437,2440],{"className":2430},[66],[68,2432],{"disabled":70,"type":71}," Always cast to ",[32,2435,2436],{},"i128",[32,2438,2439],{},"u128"," everywhere to make overflow effectively impossible in every context",[63,2442,2444,2446,2447,2450],{"className":2443},[66],[68,2445],{"disabled":70,"type":71}," Catch the debug-mode panic with ",[32,2448,2449],{},"std::panic::catch_unwind"," in production release builds",[101,2452,2453,2455,2470],{},[104,2454,106],{},[108,2456,2457,2141,2459,607,2461,2464,2465,184,2467,2469],{},[111,2458,113],{},[32,2460,2414],{},[32,2462,2463],{},"Option","), or ",[32,2466,2423],{},[32,2468,2426],{}," depending on the correct domain behavior, chosen deliberately",[108,2471,2472,72,2474,2476,2477,184,2480,184,2483,2486,2487,2490],{},[111,2473,121],{},[111,2475,1159],{}," relying on the implicit debug-panic\u002Frelease-wrap split (A) means the exact same overflow bug behaves completely differently between environments — code that \"worked\" in every debug test can silently corrupt data in production release builds. The explicit ",[32,2478,2479],{},"checked_*",[32,2481,2482],{},"saturating_*",[32,2484,2485],{},"wrapping_*"," family of methods makes the overflow-handling policy a deliberate, visible choice in the code rather than an accident of build profile; ",[32,2488,2489],{},"catch_unwind"," (D) is a heavyweight, inappropriate tool for ordinary expected-value validation, not a substitute for correct arithmetic handling.",[14,2492,2493,2504,2550],{},[18,2494,2496,2497,2500,2501,2503],{"id":2495},"q20-when-choosing-between-an-array-t-n-and-a-vect-for-function-parametersreturn-types-what-is-the-idiomatic-guidance","Q20. When choosing between an array ",[32,2498,2499],{},"[T; N]"," and a ",[32,2502,2375],{}," for function parameters\u002Freturn types, what is the idiomatic guidance?",[58,2505,2507,2515,2530,2539],{"className":2506},[61],[63,2508,2510,2092,2512,2514],{"className":2509},[66],[68,2511],{"disabled":70,"type":71},[32,2513,2375],{}," even for fixed, compile-time-known sizes, since it's more \"flexible\" by default",[63,2516,2518,2101,2520,2522,2523,2526,2527,2529],{"className":2517},[66],[68,2519],{"disabled":70,"type":71},[32,2521,2499],{}," (or a slice ",[32,2524,2525],{},"&[T]",") when the length is fixed and known at compile time, giving stack allocation and compile-time length guarantees; reach for ",[32,2528,2375],{}," when the length is only known at runtime or needs to grow\u002Fshrink",[63,2531,2533,2535,2536,2538],{"className":2532},[66],[68,2534],{"disabled":70,"type":71}," Arrays and ",[32,2537,876],{}," are chosen purely based on personal preference with no technical trade-offs",[63,2540,2542,72,2544,2546,2547,2549],{"className":2541},[66],[68,2543],{"disabled":70,"type":71},[32,2545,2499],{}," should be avoided entirely in idiomatic Rust in favor of ",[32,2548,2375],{}," for all collections",[101,2551,2552,2554,2567],{},[104,2553,106],{},[108,2555,2556,2141,2558,2560,2561,2563,2564,2566],{},[111,2557,113],{},[32,2559,2499],{}," (or ",[32,2562,2525],{},") when the length is fixed and compile-time known; reach for ",[32,2565,2375],{}," when the length is runtime-determined or needs to grow\u002Fshrink",[108,2568,2569,72,2571,2573,2574,2576,2577,2580,2581,2583],{},[111,2570,121],{},[111,2572,2059],{}," fixed-size arrays avoid heap allocation entirely and encode the exact length in the type system (catching size-mismatch bugs at compile time, as seen with Q9's constant-index rejection), which is strictly better than ",[32,2575,876],{}," whenever the size genuinely never changes — e.g. ",[32,2578,2579],{},"[u8; 32]"," for a fixed-size hash digest. Defaulting to ",[32,2582,876],{}," everywhere (A) throws away those compile-time guarantees and adds unnecessary heap allocation\u002Findirection for data whose size was never actually variable.",[2585,2586,2587],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}",{"title":30,"searchDepth":233,"depth":233,"links":2589},[2590,2591,2593,2595,2597,2599,2601,2602,2603,2604,2605,2606,2608,2610,2611,2613,2615,2616,2618,2620],{"id":20,"depth":256,"text":21},{"id":133,"depth":256,"text":2592},"Q2. What are isize and usize primarily used for?",{"id":206,"depth":256,"text":2594},"Q3. What does this program print when run with cargo run (debug profile, the default)?",{"id":363,"depth":256,"text":2596},"Q4. What is the correct way to describe integer overflow behavior in --release builds by default?",{"id":455,"depth":256,"text":2598},"Q5. What does casting with as do in this example?",{"id":618,"depth":256,"text":2600},"Q6. Which statement correctly describes Rust's char type?",{"id":703,"depth":256,"text":704},{"id":882,"depth":256,"text":883},{"id":1044,"depth":256,"text":1045},{"id":1173,"depth":256,"text":1174},{"id":1352,"depth":256,"text":1353},{"id":1510,"depth":256,"text":2607},"Q12. What does this code do with an empty tuple ()?",{"id":1709,"depth":256,"text":2609},"Q13. What is the maximum safely representable integer using f64 such that all integers up to that value can be represented exactly?",{"id":1808,"depth":256,"text":1809},{"id":1991,"depth":256,"text":2612},"Q15. When should you prefer an explicit-width integer type like u16 or i64 over the default i32?",{"id":2076,"depth":256,"text":2614},"Q16. What is the idiomatic way to convert between numeric types when the value's validity at the target type must be guaranteed rather than assumed, e.g. converting a user-supplied i64 amount into a u32 quantity field?",{"id":2177,"depth":256,"text":2178},{"id":2291,"depth":256,"text":2617},"Q18. A function needs to represent \"a 2D coordinate pair\" that will always have exactly two f64 values and no more. What is more idiomatic — a tuple (f64, f64) or a two-element Vec\u003Cf64>?",{"id":2393,"depth":256,"text":2619},"Q19. What is the best-practice way to handle a computation that might overflow in a context where overflow represents a genuine, expected possibility (e.g. summing user-supplied quantities that could exceed u32::MAX), rather than a programmer bug?",{"id":2495,"depth":256,"text":2621},"Q20. When choosing between an array [T; N] and a Vec\u003CT> for function parameters\u002Freturn types, what is the idiomatic guidance?","md",{},"\u002Frust\u002F04-data-types",{"title":5,"description":30},"rust\u002F04-data-types","DlEQ7lynxxMPYEllpEyKXjq11_2P_hGWOQUocpBA8T8",1787335398362]