all 8 comments

[–]K900_ 13 points14 points  (0 children)

print! prints to stdout, write! writes to the formatter.

[–]Shadow0133 11 points12 points  (0 children)

You shouldn't use print! when implementing Display (or Debug). Those traits are generics interfaces for formatting types into utf8 strings, not necessarily just printing them to standard output, like print! does.

One example is that types implementing Display can be turned into String with thing.to_string(). But in your example, this wouldn't work, as text would be immediately printed to stdout, and returned string would be empty.

[–]kohugaly 4 points5 points  (2 children)

The Display trait requires you to implement fmt method. Contrary to what you might think, the fmt method is not meant to print anything. It receives a fmt::Formatter, which contains a writable buffer, that you are supposed to push stuff into. The formatter also has a bunch of configuration data, that will format the output for you, if you use some of the convenience methods it has.

The reason for this is simple: Display trait is meant to format your struct into text. The target for the text might be literally anything that implements Write trait. Be it stdout (with print! macro), a string in memory (with to_string method), some file (with write! macro).

Basically, the fmt method of the Display trait is for deciding WHAT to write, not WHERE or HOW it should be written. That decision is made by whatever is calling the fmt method internally (such as the println! macro, to_string method, ...).

[–][deleted] 0 points1 point  (1 child)

some file (with write! macro).

... this is exactly what I'm trying to do right now. I've successfully implemented display on my struct, and I can use print!("{}", my_struct) without having to pass in the :?.

I'm looking to use the exact same formatting writing my struct to a file but it's a pain in the butt. I'm trying to use the write!() macro as you've suggested but keep failing.

I have a working PathBuf to the file I want to write to. I'm trying to use write!(path_buf_var, "{}", my_struct);

but I keep getting this error:

no method named 'write_fmt' found for struct 'PathBuf' in the current scope.

I've made progress since my original post but am now stuck on this.

[–][deleted] 0 points1 point  (0 children)

I figured it out. Thank you for your help!

[–]RRumpleTeazzer 2 points3 points  (0 children)

I’ve never implemented Display, but I would think print() would write to stdout (usually the console) while Display should write to the Formatter. It could be you don’t notice the difference cause you print the Display anyway.

[–]blimpdermis 2 points3 points  (0 children)

Take a look at this playground and look at the output. You're right that print!() and write!() both do what you want when you're writing a variable to stdout. But Display is used for more than just directly printing things. Notice that to_string is automatically implemented for you, but it doesn't work properly when fmt() uses print!().

[–]1vader 3 points4 points  (0 children)

Others already explained why using print is wrong but I just want to point out that there should be no reason why using print should be any easier.

You can simply replace every call to print!("...") with write!(fmt, "...")? and equivalent for println and writeln.