1"use strict";(self.webpackChunkmodular_fe=self.webpackChunkmodular_fe||[]).push([["14855"],{32755(e,t,r){r.r(t),r.d(t,{metadata:()=>n,default:()=>h,frontMatter:()=>o,contentTitle:()=>l,toc:()=>a,assets:()=>d});var n=JSON.parse('{"id":"docs/std/format/Writable","title":"Writable","description":"A trait for types that can format themselves as text.","source":"@site/docs/docs/std/format/Writable.md","sourceDirName":"docs/std/format","slug":"/docs/std/format/Writable","permalink":"/nightly/docs/std/format/Writable","draft":false,"unlisted":false,"editUrl":"https://github.com/modular/modular/edit/main/Mojo/docs/site/std/format/Writable.md","tags":[],"version":"current","frontMatter":{"title":"Writable","version":"1.2.0.dev0","slug":"Writable","type":"trait","module_name":"__init__","namespace":"std.format.__init__","lang":"mojo","show_stability_marker":null,"description":"A trait for types that can format themselves as text."},"sidebar":"stdSidebar","previous":{"title":"format","permalink":"/nightly/docs/std/format/"},"next":{"title":"Writer","permalink":"/nightly/docs/std/format/Writer"}}'),i=r(74848),s=r(28453);let o={title:"Writable",version:"1.2.0.dev0",slug:"Writable",type:"trait",module_name:"__init__",namespace:"std.format.__init__",lang:"mojo",show_stability_marker:null,description:"A trait for types that can format themselves as text."},l,d={},a=[{value:"Implemented traits",id:"implemented-traits",level:2},{value:"Provided methods",id:"provided-methods",level:2},{value:"<code>write_to</code>",id:"write_to",level:3},{value:"<code>write_repr_to</code>",id:"write_repr_to",level:3}];function c(e){let t={a:"a",b:"b",code:"code",div:"div",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",section:"section",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(t.section,{className:"mojo-docs",children:["\n",(0,i.jsx)(t.p,{children:"A trait for types that can format themselves as text."}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Writable"})," trait provides a simple, straightforward interface for types\nthat need to convert themselves to text. Types implementing ",(0,i.jsx)(t.code,{children:"Writable"})," write\ndirectly to a ",(0,i.jsx)(t.code,{children:"Writer"}),", making formatting efficient and allocation-free."]}),"\n",(0,i.jsxs)(t.p,{children:["Both ",(0,i.jsx)(t.code,{children:"write_to()"})," and ",(0,i.jsx)(t.code,{children:"write_repr_to()"})," have default implementations that\nuse reflection to automatically format all fields. This means simple structs\ncan conform to ",(0,i.jsx)(t.code,{children:"Writable"})," without any method implementations:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-mojo",children:"@fieldwise_init\nstruct Point(Writable):\n var x: Int\n var y: Int\n\nvar p = Point(1, 3)\nprint(p) # Point(x=1, y=3)\nprint(repr(p)) # Point(x=Int(1), y=Int(3))\n"})}),"\n",(0,i.jsx)(t.p,{children:"Override either for different normal and debug output:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-mojo",children:'@fieldwise_init\nstruct Point(Writable):\n var x: Float64\n var y: Float64\n\n def write_to(self, mut writer: Some[Writer]):\n writer.write("(", self.x, ", ", self.y, ")")\n\n def write_repr_to(self, mut writer: Some[Writer]):\n writer.write("Point: x=", self.x, ", y=", self.y)\n\nvar p = Point(1.5, 2.7)\nprint(p) # (1.5, 2.7)\nprint(repr(p)) # Point: x=1.5, y=2.7\n'})}),"\n",(0,i.jsxs)(t.p,{children:["Note: The default reflection-based implementations iterate over all fields\nat compile time. For mutually recursive types (e.g., struct ",(0,i.jsx)(t.code,{children:"A"})," has a field\nof type ",(0,i.jsx)(t.code,{children:"List[B]"})," and struct ",(0,i.jsx)(t.code,{children:"B"})," has a field of type ",(0,i.jsx)(t.code,{children:"A"}),"), this creates an\ninfinite monomorphization cycle that causes the compiler to hang. To fix\nthis, provide explicit ",(0,i.jsx)(t.code,{children:"write_to()"})," and ",(0,i.jsx)(t.code,{children:"write_repr_to()"})," implementations\nfor at least one type in the cycle."]}),"\n",(0,i.jsx)(t.h2,{id:"implemented-traits",children:"Implemented traits"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.a,{href:"../../../../docs/std/traits/anytype/AnyType",children:(0,i.jsx)(t.code,{children:"AnyType"})})}),"\n",(0,i.jsx)(t.h2,{id:"provided-methods",children:"Provided methods"}),"\n",(0,i.jsx)(t.h3,{id:"write_to",children:(0,i.jsx)(t.code,{children:"write_to"})}),"\n",(0,i.jsxs)(t.div,{className:"mojo-function-detail",children:["\n",(0,i.jsxs)(t.div,{className:"mojo-function-sig",children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.code,{children:"def write_to(self, mut writer: T)"})}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Write this value's text representation to a writer."}),"\n",(0,i.jsxs)(t.p,{children:["This method is called by ",(0,i.jsx)(t.code,{children:"print()"}),", ",(0,i.jsx)(t.code,{children:"String()"}
1),", and format strings to\nconvert the value to text. Override this method to define how your type\nappears when printed or converted to a string."]}),"\n",(0,i.jsxs)(t.p,{children:["The default implementation uses reflection to format all fields as\n",(0,i.jsx)(t.code,{children:"TypeName(field1=value1, field2=value2, ...)"}),", calling ",(0,i.jsx)(t.code,{children:"write_to()"}),"\non each field. All fields must conform to ",(0,i.jsx)(t.code,{children:"Writable"}),"."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Example:"})}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-mojo",children:'@fieldwise_init\nstruct Point(Writable):\n var x: Float64\n var y: Float64\n\n def write_to(self, mut writer: Some[Writer]):\n writer.write("(", self.x, ", ", self.y, ")")\n'})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Args:"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\u200B",(0,i.jsx)(t.b,{children:"writer"})," (",(0,i.jsx)(t.code,{children:"T"}),"): The destination for formatted output."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"write_repr_to",children:(0,i.jsx)(t.code,{children:"write_repr_to"})}),"\n",(0,i.jsxs)(t.div,{className:"mojo-function-detail",children:["\n",(0,i.jsxs)(t.div,{className:"mojo-function-sig",children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.code,{children:"def write_repr_to(self, mut writer: T)"})}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Write this value's debug representation to a writer."}),"\n",(0,i.jsxs)(t.p,{children:["This method is called by ",(0,i.jsx)(t.code,{children:"repr(value)"})," or the ",(0,i.jsx)(t.code,{children:'"{!r}"'})," format specifier\nand should produce unambiguous, developer-facing output that shows the\ninternal state of the value."]}),"\n",(0,i.jsxs)(t.p,{children:["The default implementation uses reflection to format all fields as\n",(0,i.jsx)(t.code,{children:"TypeName(field1=value1, field2=value2, ...)"}),", calling ",(0,i.jsx)(t.code,{children:"write_repr_to()"}),"\non each field. All fields must conform to ",(0,i.jsx)(t.code,{children:"Writable"}),"."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Example:"})}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-mojo",children:'@fieldwise_init\nstruct Point(Writable):\n var x: Float64\n var y: Float64\n\n def write_repr_to(self, mut writer: Some[Writer]):\n writer.write("Point: x=", self.x, ", y=", self.y)\n'})}),"\n",(0,i.jsxs)(t.p,{children:["Notes:\nMojo's repr always prints single quotes (",(0,i.jsx)(t.code,{children:"'"}),") at the start and end\nof the repr. Any single quote inside a string should be escaped\n(",(0,i.jsx)(t.code,{children:"\\'"}),")."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Args:"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\u200B",(0,i.jsx)(t.b,{children:"writer"})," (",(0,i.jsx)(t.code,{children:"T"}),"): The destination for formatted output."]}),"\n"]}),"\n"]}),"\n"]})}function h(e={}){let{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453(e,t,r){r.d(t,{R:()=>o,x:()=>l});var n=r(96540);let i={},s=n.createContext(i);function o(e){let t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(s.Provider,{value:t},e.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.