From 6c08859b0e95839d0dfbd9047d6d789b180d0bad Mon Sep 17 00:00:00 2001
From: Rob Pike
-The control structures of Go are related to those of C but different
+The control structures of Go are related to those of C but differ
in important ways.
There is no
-Within the function Control structures
do or while loop, only a
slightly generalized
@@ -1308,22 +1308,24 @@ to print in the format
Our String() method is able to call Sprintf because the
print routines are fully reentrant and can be used recursively.
We can even go one step further and pass a print routine's arguments directly to another such routine.
-The signature of Printf uses the ...
-type for its final argument to specify that an arbitrary number of parameters can appear
-after the format.
+The signature of Printf uses the type ...interface{}
+for its final argument to specify that an arbitrary number of parameters (of arbitrary type)
+can appear after the format.
-func Printf(format string, v ...) (n int, errno os.Error) {
+func Printf(format string, v ...interface{}) (n int, errno os.Error) {
Printf, v is a variable that can be passed,
-for instance, to another print routine. Here is the implementation of the
+Within the function Printf, v acts like a variable of type
+[]interface{} but if it is passed to another variadic function, it acts like
+a regular list of arguments.
+Here is the implementation of the
function log.Stderr we used above. It passes its arguments directly to
fmt.Sprintln for the actual formatting.
// Stderr is a helper function for easy logging to stderr. It is analogous to Fprint(os.Stderr).
-func Stderr(v ...) {
+func Stderr(v ...interface{}) {
stderr.Output(2, fmt.Sprintln(v)) // Output takes parameters (int, string)
}
@@ -1331,6 +1333,21 @@ func Stderr(v ...) {
There's even more to printing than we've covered here. See the godoc documentation
for package fmt for the details.
+By the way, a ... parameter can be of a specific type, for instance ...int
+for a min function that chooses the least of a list of integers:
+
+func Min(a ...int) int {
+ min := int(^uint(0) >> 1) // largest int
+ for _, i := range a {
+ if i < min {
+ min = i
+ }
+ }
+ return min
+}
+
The Job type now has the Log, Logf
and other
-methods of log.Logger. We could have given the Logger
+methods of *log.Logger. We could have given the Logger
a field name, of course, but it's not necessary to do so. And now, once
initialized, we can
log to the Job:
@@ -1993,7 +2010,7 @@ of Job would dominate it.
Second, if the same name appears at the same nesting level, it is usually an error;
-it would be erroneous to embed log.Logger if Job struct
+it would be erroneous to embed log.Logger if the Job struct
contained another field or method called Logger.
However, if the duplicate name is never mentioned in the program outside the type definition, it is OK.
This qualification provides some protection against changes made to types embedded from outside; there
--
2.52.0