Attention is currently required from: Russ Cox.
Rob Pike would like Russ Cox to review this change.
fmt: add Append, Appenln, Appendf
These are straightforward variants of the existing Sprintf etc.,
but append the resulting bytes to a provided buffer rather than
returning a string.
Internally, there is potentially some allocation because the package
uses a pool of buffers to build its output. We make no attempt to
override that, so the result is first printed into the pool and
then copied to the output. Since it is a managed pool, asymptotically
there should be no extra allocation.
Fixes #47579
Change-Id: Icef797f9b6f0c84d03e7035d95c06cdb819e2649
---
M src/fmt/fmt_test.go
M src/fmt/print.go
2 files changed, 82 insertions(+), 0 deletions(-)
diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go
index a4c65b8..2594126 100644
--- a/src/fmt/fmt_test.go
+++ b/src/fmt/fmt_test.go
@@ -1896,3 +1896,33 @@
}
}
}
+
+// Test the various Append printers. The details are well tested above;
+// here we just make sure the byte slice is updated.
+
+func TestAppendf(t *testing.T) {
+ b := []byte("hello ")
+ got := string(Appendf(b, "world, %d", 23))
+ const want = "hello world, 23"
+ if got != want {
+ t.Fatalf("Appendf returns %q not %q\n", got, want)
+ }
+}
+
+func TestAppend(t *testing.T) {
+ b := []byte("hello ")
+ got := string(Append(b, "world", ", ", 23))
+ const want = "hello world, 23"
+ if got != want {
+ t.Fatalf("Append returns %q not %q\n", got, want)
+ }
+}
+
+func TestAppendln(t *testing.T) {
+ b := []byte("hello ")
+ got := string(Appendln(b, "world,", 23))
+ const want = "hello world, 23\n"
+ if got != want {
+ t.Fatalf("Appendln returns %q not %q\n", got, want)
+ }
+}
diff --git a/src/fmt/print.go b/src/fmt/print.go
index 33f5541..2af7bd0 100644
--- a/src/fmt/print.go
+++ b/src/fmt/print.go
@@ -222,6 +222,16 @@
return s
}
+// Appendf formats according to a format specifier, appends the result to the byte
+// slice, and returns the updated slice.
+func Appendf(b []byte, format string, a ...any) []byte {
+ p := newPrinter()
+ p.doPrintf(format, a)
+ b = append(b, p.buf...)
+ p.free()
+ return b
+}
+
// These routines do not take a format string
// Fprint formats using the default formats for its operands and writes to w.
@@ -252,6 +262,16 @@
return s
}
+// Append formats using the default formats for its operands, appends the result to
+// the byte slice, and returns the updated slice.
+func Append(b []byte, a ...any) []byte {
+ p := newPrinter()
+ p.doPrint(a)
+ b = append(b, p.buf...)
+ p.free()
+ return b
+}
+
// These routines end in 'ln', do not take a format string,
// always add spaces between operands, and add a newline
// after the last operand.
@@ -284,6 +304,17 @@
return s
}
+// Appendln formats using the default formats for its operands, appends the result
+// to the byte slice, and returns the updated slice. Spaces are always added
+// between operands and a newline is appended.
+func Appendln(b []byte, a ...any) []byte {
+ p := newPrinter()
+ p.doPrintln(a)
+ b = append(b, p.buf...)
+ p.free()
+ return b
+}
+
// getField gets the i'th field of the struct value.
// If the field is itself is an interface, return a value for
// the thing inside the interface, not the interface itself.
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Russ Cox.
Rob Pike uploaded patch set #2 to this change.
fmt: add Append, Appenln, Appendf
These are straightforward variants of the existing Sprintf etc.,
but append the resulting bytes to a provided buffer rather than
returning a string.
Internally, there is potentially some allocation because the package
uses a pool of buffers to build its output. We make no attempt to
override that, so the result is first printed into the pool and
then copied to the output. Since it is a managed pool, asymptotically
there should be no extra allocation.
Fixes #47579
Change-Id: Icef797f9b6f0c84d03e7035d95c06cdb819e2649
---
M src/fmt/fmt_test.go
M src/fmt/print.go
2 files changed, 96 insertions(+), 0 deletions(-)
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Russ Cox.
Rob Pike uploaded patch set #3 to this change.
fmt: add Append, Appendln, Appendf
These are straightforward variants of the existing Sprintf etc.,
but append the resulting bytes to a provided buffer rather than
returning a string.
Internally, there is potentially some allocation because the package
uses a pool of buffers to build its output. We make no attempt to
override that, so the result is first printed into the pool and
then copied to the output. Since it is a managed pool, asymptotically
there should be no extra allocation.
Fixes #47579
Change-Id: Icef797f9b6f0c84d03e7035d95c06cdb819e2649
---
M src/fmt/fmt_test.go
M src/fmt/print.go
2 files changed, 96 insertions(+), 0 deletions(-)
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Rob Pike, Russ Cox.
1 comment:
Patchset:
RELNOTE=yes
In the current api checking scheme, you'll need to add a new file $GOROOT/api/next describing the new functions with a format like the existing files in that directory. You can test this via "go tool dist test -run=api".
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Rob Pike, Russ Cox.
Rob Pike uploaded patch set #4 to this change.
fmt: add Append, Appendln, Appendf
These are straightforward variants of the existing Sprintf etc.,
but append the resulting bytes to a provided buffer rather than
returning a string.
Internally, there is potentially some allocation because the package
uses a pool of buffers to build its output. We make no attempt to
override that, so the result is first printed into the pool and
then copied to the output. Since it is a managed pool, asymptotically
there should be no extra allocation.
Fixes #47579
RELNOTE=yes
Change-Id: Icef797f9b6f0c84d03e7035d95c06cdb819e2649
---
A api/next/47579.txt
M src/fmt/fmt_test.go
M src/fmt/print.go
3 files changed, 101 insertions(+), 0 deletions(-)
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Russ Cox.
Patch set 4:Run-TryBot +1
Attention is currently required from: Russ Cox.
1 comment:
Patchset:
1 of 30 TryBots failed. […]
Not sure what I am supposed to do here. How can one coordinate updates to two different repos? Should I change x/tools to use a different test package?
Goldens that depend on other repos are a Really Bad Idea.
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Rob Pike, Russ Cox.
1 comment:
Patchset:
Not sure what I am supposed to do here. […]
I sent CL 406357 to make the example not assume that no new names are ever added to the fmt package.
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Russ Cox.
1 comment:
Patchset:
I sent CL 406357 to make the example not assume that no new names are ever added to the fmt package.
Thanks, I approved that CL.
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Rob Pike.
Ian Lance Taylor removed a vote from this change.
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Rob Pike, Russ Cox.
Ian Lance Taylor removed a vote from this change.
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Rob Pike, Russ Cox.
Ian Lance Taylor removed a vote from this change.
Attention is currently required from: Ian Lance Taylor, Rob Pike, Russ Cox.
Ian Lance Taylor removed a vote from this change.
Attention is currently required from: Rob Pike, Russ Cox.
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Rob Pike, Russ Cox.
Patch set 4:Code-Review +2
Attention is currently required from: Rob Pike, Russ Cox.
Patch set 4:Code-Review +1
Rob Pike submitted this change.
fmt: add Append, Appendln, Appendf
These are straightforward variants of the existing Sprintf etc.,
but append the resulting bytes to a provided buffer rather than
returning a string.
Internally, there is potentially some allocation because the package
uses a pool of buffers to build its output. We make no attempt to
override that, so the result is first printed into the pool and
then copied to the output. Since it is a managed pool, asymptotically
there should be no extra allocation.
Fixes #47579
RELNOTE=yes
Change-Id: Icef797f9b6f0c84d03e7035d95c06cdb819e2649
Reviewed-on: https://go-review.googlesource.com/c/go/+/406177
Reviewed-by: Ian Lance Taylor <ia...@google.com>
Run-TryBot: Ian Lance Taylor <ia...@golang.org>
Reviewed-by: Michael Knyszek <mkny...@google.com>
TryBot-Result: Gopher Robot <go...@golang.org>
---
A api/next/47579.txt
M src/fmt/fmt_test.go
M src/fmt/print.go
3 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/api/next/47579.txt b/api/next/47579.txt
new file mode 100644
index 0000000..a5d4d9f
--- /dev/null
+++ b/api/next/47579.txt
@@ -0,0 +1,3 @@
+pkg fmt, func Append([]uint8, ...interface{}) []uint8 #47579
+pkg fmt, func Appendf([]uint8, string, ...interface{}) []uint8 #47579
+pkg fmt, func Appendln([]uint8, ...interface{}) []uint8 #47579
diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go
index a4c65b8..aaeac38 100644
--- a/src/fmt/fmt_test.go
+++ b/src/fmt/fmt_test.go
@@ -1896,3 +1896,47 @@
}
}
}
+
+// Test the various Append printers. The details are well tested above;
+// here we just make sure the byte slice is updated.
+
+const (
+ appendResult = "hello world, 23"
+ hello = "hello "
+)
+
+func TestAppendf(t *testing.T) {
+ b := make([]byte, 100)
+ b = b[:copy(b, hello)]
+ got := Appendf(b, "world, %d", 23)
+ if string(got) != appendResult {
+ t.Fatalf("Appendf returns %q not %q", got, appendResult)
+ }
+ if &b[0] != &got[0] {
+ t.Fatalf("Appendf allocated a new slice")
+ }
+}
+
+func TestAppend(t *testing.T) {
+ b := make([]byte, 100)
+ b = b[:copy(b, hello)]
+ got := Append(b, "world", ", ", 23)
+ if string(got) != appendResult {
+ t.Fatalf("Append returns %q not %q", got, appendResult)
+ }
+ if &b[0] != &got[0] {
+ t.Fatalf("Append allocated a new slice")
+ }
+}
+
+func TestAppendln(t *testing.T) {
+ b := make([]byte, 100)
+ b = b[:copy(b, hello)]
+ got := Appendln(b, "world,", 23)
+ if string(got) != appendResult+"\n" {
+ t.Fatalf("Appendln returns %q not %q", got, appendResult+"\n")
+ }
+ if &b[0] != &got[0] {
+ t.Fatalf("Appendln allocated a new slice")
To view, visit change 406177. To unsubscribe, or for help writing mail filters, visit settings.