1"use strict";(globalThis.webpackChunkdocs=globalThis.webpackChunkdocs||[]).push([[2937],{89479(n,e,i){i.r(e),i.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>g,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"libraries/standard_library/logging","title":"Logging and Panics","description":"Learn how to use the println statement for debugging in Noir with this tutorial. Understand the basics of logging in Noir and how to implement it in your code.","source":"@site/versioned_docs/version-v1.0.0-rc.1/libraries/standard_library/logging.md","sourceDirName":"libraries/standard_library","slug":"/libraries/standard_library/logging","permalink":"/docs/v1.0.0-rc.1/libraries/standard_library/logging","draft":false,"unlisted":false,"editUrl":"https://github.com/noir-lang/noir/edit/master/docs/versioned_docs/version-v1.0.0-rc.1/libraries/standard_library/logging.md","tags":[],"version":"v1.0.0-rc.1","frontMatter":{"title":"Logging and Panics","description":"Learn how to use the println statement for debugging in Noir with this tutorial. Understand the basics of logging in Noir and how to implement it in your code.","keywords":["noir logging","println statement","print statement","panic","debugging in noir","noir std library","logging tutorial","basic logging in noir","noir logging implementation","noir debugging techniques","rust"]},"sidebar":"sidebar","previous":{"title":"Is Unconstrained Function","permalink":"/docs/v1.0.0-rc.1/libraries/standard_library/is_unconstrained"},"next":{"title":"Memory Module","permalink":"/docs/v1.0.0-rc.1/libraries/standard_library/mem"}}');var r=i(74848),s=i(28453);
1const o={title:"Logging and Panics",description:"Learn how to use the println statement for debugging in Noir with this tutorial. Understand the basics of logging in Noir and how to implement it in your code.",keywords:["noir logging","println statement","print statement","panic","debugging in noir","noir std library","logging tutorial","basic logging in noir","noir logging implementation","noir debugging techniques","rust"]},a=void 0,l={},c=[{value:"<code>panic</code>",id:"panic",level:2}];function d(n){const e={code:"code",h2:"h2",p:"p",pre:"pre",...(0,s.R)(),...n.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(e.p,{children:["The standard library provides two familiar statements you can use: ",(0,r.jsx)(e.code,{children:"println"})," and ",(0,r.jsx)(e.code,{children:"print"}),". Despite being a limited implementation of rust's ",(0,r.jsx)(e.code,{children:"println!"})," and ",(0,r.jsx)(e.code,{children:"print!"})," macros, these constructs can be useful for debugging."]}),"\n",(0,r.jsxs)(e.p,{children:["You can print the output of both statements in your Noir code by using the ",(0,r.jsx)(e.code,{children:"nargo execute"})," command or the ",(0,r.jsx)(e.code,{children:"--show-output"})," flag when using ",(0,r.jsx)(e.code,{children:"nargo test"})," (provided there are print statements in your tests)."]}),"\n",(0,r.jsxs)(e.p,{children:["It is recommended to use ",(0,r.jsx)(e.code,{children:"nargo execute"})," if you want to debug failing constraints with ",(0,r.jsx)(e.code,{children:"println"})," or ",(0,r.jsx)(e.code,{children:"print"})," statements. This is due to every input in a test being a constant rather than a witness, so we issue an error during compilation while we only print during execution (which comes after compilation). Neither ",(0,r.jsx)(e.code,{children:"println"}),", nor ",(0,r.jsx)(e.code,{children:"print"})," are callable for failed constraints caught at compile time."]}),"\n",(0,r.jsxs)(e.p,{children:["Both ",(0,r.jsx)(e.code,{children:"print"})," and ",(0,r.jsx)(e.code,{children:"println"})," are generic functions which can work on integers, fields, strings, and even structs or expressions. For example:"]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-rust",children:'struct Person {\n age: u32,\n height: u32,\n}\n\nfn main(age: u32, height: u32) {\n let person = Person {\n age: age,\n height: height,\n };\n println(person);\n println(age + height);\n println("Hello world!");\n}\n'})}),"\n",(0,r.jsxs)(e.p,{children:["You can print different types in the same statement (including strings) with a type called ",(0,r.jsx)(e.code,{children:"fmtstr"}),'. It can be specified in the same way as a normal string, just prepended with an "f" character:']}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-rust",children:' let fmt_str = f"i: {i}, j: {j}";\n println(fmt_str);\n\n let s = myStruct { y: x, x: y };\n println(s);\n\n println(f"i: {i}, s: {s}");\n\n println(x);\n println([x, y]);\n\n let foo = fooStruct { my_struct: s, foo: 15 };\n println(f"s: {s}, foo: {foo}");\n\n println(15); // prints 0x0f, implicit Field\n println(-1 as u8); // prints 255\n println(-1 as i8); // prints -1\n'})}),"\n",(0,r.jsxs)(e.p,{children:["Examples shown above are interchangeable between the two ",(0,r.jsx)(e.code,{children:"print"})," statements:"]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-rust",children:'let person = Person { age : age, height : height };\n\nprintln(person);\nprint(person);\n\nprintln("Hello world!"); // Prints with a newline at the end of the input\nprint("Hello world!"); // Prints the input and keeps cursor on the same line\n'})}),"\n",(0,r.jsx)(e.h2,{id:"panic",children:(0,r.jsx)(e.code,{children:"panic"})}),"\n",(0,r.jsxs)(e.p,{children:["The ",(0,r.jsx)(e.code,{children:"panic"})," function halts execution with an error message. It is auto-imported via the prelude, so no ",(0,r.jsx)(e.code,{children:"use"})," statement is needed."]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-rust",children:"fn panic<T, U>(message: T) -> U where T: StringLike\n"})}),"\n",(0,r.jsxs)(e.p,{children:["The message can be a string literal or a format str
1ing. The return type is polymorphic, so ",(0,r.jsx)(e.code,{children:"panic"})," can be used in any expression position:"]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-rust",children:'fn divide(x: Field, y: Field) -> Field {\n if y == 0 {\n panic("division by zero")\n } else {\n x / y\n }\n}\n'})}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-rust",children:'fn example(x: u32) {\n if x > 100 {\n panic(f"value too large: {x}");\n }\n}\n'})})]})}function g(n={}){const{wrapper:e}={...(0,s.R)(),...n.components};return e?(0,r.jsx)(e,{...n,children:(0,r.jsx)(d,{...n})}):d(n)}},28453(n,e,i){i.d(e,{R:()=>o,x:()=>a});var t=i(96540);const r={},s=t.createContext(r);function o(n){const e=t.useContext(s);return t.useMemo(function(){return"function"==typeof n?n(e):{...e,...n}},[e,n])}function a(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(r):n.components||r:o(n.components),t.createElement(s.Provider,{value:e},n.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.