Skip to content

fmt: add Append, Appendf, Appendln #47579

Closed
@seebs

Description

@seebs

What version of Go are you using (go version)?

1.16

Does this issue reproduce with the latest release?

Sure.

What operating system and processor architecture are you using (go env)?

N/A

What did you do?

Profiled something that was using Sprintf in a minor way.

What did you expect to see?

Less Sprintf in the profile.

What did you see instead?

So much Sprintf.

The issue here is that most of what's happening is WAY cheaper than allocations. strconv has AppendInt, but that can't do formatting.

It makes sense, for most uses, that fmt.Sprintf is an allocator that produces a string, but there are times when you want formatted-output, but want to write into a []byte. And you can do that with bytes.Buffer and fmt.Fprintf, but creating a bytes.Buffer around a []byte is... an allocation. And fmt.Fprintf does an allocation. (Curiously, if I do fmt.Fprintf into a bytes.Buffer I just made for that purpose, I only get the one allocation.)

What I want: Something like Sprintf, but that can write into a []byte, and can fail gracefully if there's not enough space to write things.

Proposed name: fmt.Snprintf, because snprintf is what you call when you already have a buffer you want written to and you have a length limit in mind.

So, fmt.Snprintf(dest []byte, fmt string, args ...interface{}) (int, error), perhaps. The C standard's answer to "what if n isn't big enough" is "you report the n you would have used if n had been big enough", which exists to allow a single-pass process to figure out how much space you actually need. Alternatively, it could return number of bytes actually written, and if it didn't fit, an error with a concrete type that indicates space needed.

I note, browsing source, that fmt already has fmtBytes, although this doesn't do quite the thing this would need.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions