Why doesnt this give a compile error, is it a bug in golang or do I miss something?
intPadded := fmt.Sprintf("%09d", "i am a string" )
fmt.Println("bah" + intPadded)
when executed it gives
bah%!d(string=i am a string)
It's your bug. The compiler can only check that the fmt.Sprintf arguments have the proper type; all types implement the empty interface. Use the Go vet command.
func Sprintf
func Sprintf(format string, a ...interface{}) string
Sprintf formats according to a format specifier and returns the
resulting string.
Interface types
An interface type specifies a method set called its interface. A
variable of interface type can store a value of any type with a method
set that is any superset of the interface. Such a type is said to
implement the interface.
A type implements any interface comprising any subset of its methods
and may therefore implement several distinct interfaces. For instance,
all types implement the empty interface:
interface{}
Command vet
Vet examines Go source code and reports suspicious constructs, such as
Printf calls whose arguments do not align with the format string.
"If an invalid argument is given for a verb, such as providing a string to %d, the generated string will contain a description of the problem" per http://golang.org/pkg/fmt/
It doesn't give a compile-time error because there is no compile-time error. fmt.Sprintf() is defined as taking ...interface{} for its last argument, which is valid for any sequence of types. The checking is done only at runtime.
Related
Is there a way to use the reflection libraries in Go to go from the name of a type to its Type representation?
I've got a library where the user needs to provide Type representations for some code generation. I know it must be possible (in a sense) because they can just create a variable of that type and call the TypeOf function, but is there a way to circumvent this and just get representation from the name?
The question is not quite explicit, it can be interpreted in 2 ways, to one of which the answer is no, not possible; and the other to which the answer is yes, it's possible.
At runtime
If the type name is provided as a string value, then at runtime it's not possible as types that are not referred to explicitly may not get compiled into the final executable binary (and thus obviously become unreachable, "unknown" at runtime). For details see Splitting client/server code. For possible workarounds see Call all functions with special prefix or suffix in Golang.
At "coding" time
If we're talking about "coding" time (source code writing / generating), then it's possible without creating / allocating a variable of the given type and calling reflect.TypeOf() and passing the variable.
You may start from the pointer to the type, and use a typed nil pointer value without allocation, and you can navigate from its reflect.Type descriptor to the descriptor of the base type (or element type) of the pointer using Type.Elem().
This is how it looks like:
t := reflect.TypeOf((*YourType)(nil)).Elem()
The type descriptor t above will be identical to t2 below:
var x YourType
t2 := reflect.TypeOf(x)
fmt.Println(t, t2)
fmt.Println(t == t2)
Output of the above application (try it on the Go Playground):
main.YourType main.YourType
true
In the Go language specification its said things which needs to be exported outside package must starts with capital letter. I am wondering how error interface is exposed outside and can be accessible anywhere even though it starts with small letter unlike other interfaces starts with capital letter like Stringer.
error is a builtin type just like int, bool, string etc. I guess you've never wondered why int is available despite starting with a lowecased letter.
Builtin types are predeclared identifiers, they are implicitly declared in the universe block and so available everywhere without any imports or qualifiers.
error is a special case, defined in the language spec:
The predeclared type error is defined as
type error interface {
Error() string
}
It is the conventional interface for representing an error condition, with the nil value representing no error. For instance, a function to read data from a file might be defined:
func Read(f *File, b []byte) (n int, err error)
As historical trivia, in a pre-release version of Go, it was part of a standard library package, but this lead to a dependency nightmare, so they made it a special case.
I've looked in the documentation and couldn't find this info.
Given a struct, is it possible to implement a method (say, func (k Koala) String() string) that will automatically be used by the fmt.Print family when printing a struct?
Maybe there's an interface somewhere, but I didn't find it.
Yes, it's called fmt.Stringer()
Stringer is implemented by any value that has a String method, which defines the “native” format for that value. The String method is used to print values passed as an operand to any format that accepts a string or to an unformatted printer such as Print.
type Stringer interface {
String() string
}
The *print* functions don't accept a Stringer() interface themselves because fmt.Println("foo") and fmt.Println(someStringer) are equally valid. I recommend you go through the print.go source code to see exactly how this works, but in brief the *print* functions:
accept an interface{};
check if it's a built-in type (e.g. string, int, etc.) and format it accordingly if it is;
check if the type has a .String() method and use that if it exists.
The precise logic is a bit more involved. As mentioned, I encourage you to go through the source code yourself. It's all just plain readable Go.
Is there a way to use the reflection libraries in Go to go from the name of a type to its Type representation?
I've got a library where the user needs to provide Type representations for some code generation. I know it must be possible (in a sense) because they can just create a variable of that type and call the TypeOf function, but is there a way to circumvent this and just get representation from the name?
The question is not quite explicit, it can be interpreted in 2 ways, to one of which the answer is no, not possible; and the other to which the answer is yes, it's possible.
At runtime
If the type name is provided as a string value, then at runtime it's not possible as types that are not referred to explicitly may not get compiled into the final executable binary (and thus obviously become unreachable, "unknown" at runtime). For details see Splitting client/server code. For possible workarounds see Call all functions with special prefix or suffix in Golang.
At "coding" time
If we're talking about "coding" time (source code writing / generating), then it's possible without creating / allocating a variable of the given type and calling reflect.TypeOf() and passing the variable.
You may start from the pointer to the type, and use a typed nil pointer value without allocation, and you can navigate from its reflect.Type descriptor to the descriptor of the base type (or element type) of the pointer using Type.Elem().
This is how it looks like:
t := reflect.TypeOf((*YourType)(nil)).Elem()
The type descriptor t above will be identical to t2 below:
var x YourType
t2 := reflect.TypeOf(x)
fmt.Println(t, t2)
fmt.Println(t == t2)
Output of the above application (try it on the Go Playground):
main.YourType main.YourType
true
I am referring to the source of func Printf on http://golang.org/pkg/log/
func Printf(format string, v ...interface{})
Printf calls Output to print to the standard logger. Arguments are handled in the manner of fmt.Printf.
I have two questions:
What is the '...' ?
What does ...interface{} mean?
Thank you very much
This isn't exactly specific to go, so unlike the other answerers I'll go the more general route.
On Variable Arguments (...)
... here, called "ellipsis", indicates the function can receive a variable number of arguments, often referred to as varargs (or var-args, or other spellings). This is called a variadic function.
It simply means that, according to the following signature:
func Printf(format string, v ...interface{}) (n int, err error) {}
Printf will expect a first argument of type string, and then between 0 and N arguments of type interface{}. More on that type in the next section.
While the ability to supply any number of arguments can seem very handy, and without going into too much details here for risk of going off-topic, it comes with a few caveats depending on the implementation in the language:
increase in memory consumption,
decrease in readability,
decrease in code security.
I'll leave it up to you to look up why from the resources above.
On the Empty Interface (interface{})
This syntax bit is a bit more Go-specific, but the hint is in the name: interface.
An interface (or closer to Go's paradigm, a protocol), is a type that defines a contract for other objects to comply to. According to this Wikipedia article on interfaces in computing (emphasis in bold mine and corrections in italics mine):
In object-oriented languages, **the term "interface" is often used to define an abstract type that contains no data, but exposes behaviors defined as methods. A class having all the methods corresponding to that interface is said to implement that interface. Furthermore, a class can [in some languages]) implement multiple interfaces, and hence can be of different types at the same time.
An interface is hence a type definition; anywhere an object can be exchanged (in a function or method call) the type of the object to be exchanged can be defined in terms of an interface instead of a specific class. This allows later code to use the same function exchanging different object types; _[aiming to be]_ generic and reusable.
Now back to Go's Empty Interface
Go is a strongly typed language, with several built-in types, including Interface Types, which they describe as gollows in the current (1.1) language specifications:
An interface type specifies a method set called its interface. A variable of interface type can store a value of any type with a method set that is any superset of the interface. Such a type is said to implement the interface.
Futher down, you are introduced to the construct you see in Printf's signature, interface{} (emphasis in bold mine):
A type implements any interface comprising any subset of its methods and may therefore implement several distinct interfaces. For instance, all types implement the empty interface:
interface{}
This basically means that any type an be represented as the "empty interface", and thus that Printf can accept variables of any type for these varargs.
A Quick Comparison with Other Languages
Historically, the name printf comes from the C function and from the binary of the same name, printf meaning "print formatted", though there were variadic print functions in earlier languages, and variadic functions are used for many other scenarios. However, printf is often considered the prime example of such a use. It's signature in C is:
int printf(const char *format, ...);
As a result of their practicality, varargs and printf's familiar face show up in most languages...
In Java, printf exists under multiple forms, notably from the PrintStream class:
public PrintStream printf(String format, Object... args)
Some other langauges do not bother with specifying variable arguments and make it implicit, for instance in JavaScript, the arguments special variable within a function allows to access any arguments passed to a function, whether they match the prototype or not.
The console.log() method would be an example similar to printf, with the following pseudo-signature expanded for clarity (but actually simply using arguments):
console.log(obj1 [, obj2, ..., objN);
console.log(msg [, subst1, ..., substN);
The documentation directly answers to your question. Here is the link and the related part:
http://golang.org/doc/effective_go.html
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 ...interface{}) (n int, err error) {
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.Println we used above. It passes its arguments directly to fmt.Sprintln for the actual formatting.
// Println prints to the standard logger in the manner of fmt.Println.
func Println(v ...interface{}) {
std.Output(2, fmt.Sprintln(v...)) // Output takes parameters (int, string)
}
We write ... after v in the nested call to Sprintln to tell the compiler to treat v as a list of arguments; otherwise it would just pass v as a single slice argument.
The Go documentation is pretty good and the Language specification is really well written and understandable. Why not have a look?
http://golang.org/ref/spec#Function_types
http://golang.org/ref/spec#Passing_arguments_to_..._parameters
http://golang.org/ref/spec#Interface_types
Ctrl-F in your browser and looking for ... and interface{} will enlighten you.