Is there a Go equivalent of `ToString()` that `fmt.Print` will use? - go

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.

Related

Get the underlying type from a string in go? [duplicate]

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

Polymorphism without methods in go

Note: I'm editing this question to a concrete example of why I want to do this, which is why some of the answers might no longer make sense in context.
I am writing a bit of code that passes data from an input. The data is in the form of tags that have an identifier of what kind of data they contain and then the data.
Unfortunately I have no control over the input and don't know in advance what tags will be in it, one might be an int another might be a string, yet another might be an array of ints.
The problem arises when I need to handle all tags like the same type, for instance if I have a slice of tags, of a function that either accepts or returns a tag.
The solutions I have so far seen to this is to define the slices/functions with an empty interface which would allow me to do so, however that is kinda undesirable as it would not tell anything to other people using the package about what types are expected and also kinda defies the point of having a typed language in the first place.
Interfaces does however seem to be the solution here, and i would love to have a Tag interface to pass around, that does require though that I define methods on them, and there are really no methods they need.
My current solution looks like this
type Tag interface{
implementTag()
}
type TagInt int
func (tag TagInt) implementTag() {}
type TagString string
func (tag TagInt) implementTag() {}
While this does indeed work and solves my problem, having to define dummy methods just for that feels very wrong.
So my question sums up in this: Are there any way that I can define that something is a Tag without having to define dummy methods?
And now want to make a slice that can hold both t1 and t2 but nothing else.
You cannot do that. Sorry.
What I would do in your scenario is accept any type in the parameters with an empty interface then use a type assertion inside to confirm that it's the type that you want.
if t1, ok := interfaceInput.(t1); !ok{
// handle it being the wrong type here
return
}
Also if you want the tight coupling between a data type and it's method, namely an object, what's so wrong with having it be a method of the object?
You can use []interface{} for a "slice of any type" but then it's up to you to use type assertions and/or type switches to discover the actual runtime types of that slice's members.
Learn more about empty interfaces in the Tour of Go
And now want to make a slice that can hold both t1 and t2 but nothing
else.
This is quite an unusual requirement and you're unlikely to need this in Go. But you could also do your own discriminated union with:
type item struct {
typeSelector int
t1Value t1
t2Value t2
}
And then use []item, checking typeSelector at runtime to see which value is populated.
Alternatively you could even use *t1 and *t2 and have nil signify "no value in this field".

Go-idiomatic naming of slice types

When I need methods on slices I have to declare a new type. But what should I name it?
type SliceSomething []Something or type SomethingSlice []Something?
Since it's read as "slice of something" the first one seems better, but autocomplete would probably prefer the second one.
The CodeReview wiki page
Variable names in Go should be short rather than long.
This is especially true for local variables with limited scope.
Prefer c to lineCount. Prefer i to sliceIndex.
The basic rule: the further from its declaration that a name is used, the more descriptive the name must be.
That is why you won't find "Slice" often in the go sources, except in:
encoding/gob/encoder_test.go:335: type recursiveSlice []recursiveSlice
encoding/json/encode_test.go:107: type renamedByteSlice []byte
encoding/json/encode_test.go:108: type renamedRenamedByteSlice []renamedByte
regexp/onepass.go:283: type runeSlice []rune
sort/sort.go:233: type IntSlice []int
sort/sort.go:243: type Float64Slice []float64
sort/sort.go:258: type StringSlice []string
unicode/maketables.go:1118: type runeSlice []rune
So if you have to put 'Slice' in the name, it would be type SomethingSlice []Something rather than type SliceSomething []Something.
Check out Go source code for generally recognized idioms.

golang bug with sprintf when giving string as argument to %09d

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.

What is ...interface{} as an argument

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.

Resources