Go-idiomatic naming of slice types - go

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.

Related

Why can you assign a slice to an empty interface but not cast it to the same empty interface

Why does golang not support casting a slice to an empty interface? You can however work around it, by declaring a variable with an empty interface as type and assinging the slice to that variable. Why are those not the same thing?
Example: https://play.golang.com/p/r4LXmR4JhF0
First, Go doesn't support casting at all.
There simply is no type casting in Go*.
What you're attempting to do is a type assertion.
There are two reasons your attempt fails. Both are explained by the compiler:
invalid type assertion: slice.(<inter>) (non-interface type []interface {} on left)
You cannot type-assert any non-interface type to an interface.
non-name *castedSlice on left side of :=
*castedSlice is invalid in this context.
Assignment is the correct approach if you want to store a slice in a variable of type interface{}. You can do this a few ways:
As you have discovered, this works:
var result interface{}
result = slice
You can combine those two lines:
var result interface{} = slice
You can also do a short variable declaration:
result := interface{}{slice}
*lest anyone nitpick the statement: It is technically possible to accomplish the same as type casting in Go, with use of the unsafe package, but as this is outside of the language spec, and is, by definition, unsafe, I think it's still a reasonable statement that Go does not support type casting.

What does the double curly brace mean in []interface{}{}

Please note this is double curly braces in this format{}{}, and not nested curly braces {{}}. I am also unsure if this is an empty interface issue, a slice issue or a struct issue. I am guessing it is a combination of at least two of these.
I am learning Golang and I have reached empty interfaces. I see I need to declare a slice of empty interfaces as
[]interface{}{}
or for instance
[]interface{}{"aa","bb"}
I don't just want to blindly start using it. Whereas I understand the idea of empty interfaces, and that an interface contains two portions of data, the value and the type, I just don't understand the {}{} structure? I learned that slices are created with make() or for instance
[]int{}
What is the extra {} for when using empty interfaces?
Thank you
I have googled it, and went through my tutorials. I also compared it to what I know about structs as I suspect a interface is a struct. My attempts to google golang interfaces yields mainly normal interfaces, with which I have no problem.
[]interface{} is the type: a slice [] of empty interface interface{} (which is actually an anonymous inline type declaration). The second set of braces instantiates an instance of that type, so []interface{}{} is an empty slice of empty interface, []interface{}{"aa","bb"} is a slice of empty interface with two items. That could also be []string{"aa","bb"}, a slice of string with two items, which is the same thing with a different type (string in place of interface{}).
You could also have a non-empty interface, like []interface{SomeFunc()}{} being an empty slice of interface{SomeFunc()}, a non-empty anonymous interface type. Or you could do it with an anonymous struct type, like []struct{Foo string}{{"bar"},{"baz"}}. Here there's even more braces - the first pair around the type definition body, the second pair around the slice literal, and within that, one pair each around two struct literals.
interface{} is the empty interface type
[]interface{} is a slice of type empty interface
interface{}{} is an empty interface type composite literal
[]interface{}{} is a slice of type empty interface composite literals
The Go Programming Language Specification
Interface types
Slice types
Composite literals
Take the Go Tour: A Tour of Go

Assigning types to variables in Go

How to have a variable whose type is a variable type?
What do I mean by that? I have a python and java background. In both languages I can do things like assigning a class name to variable.
#Python
class A:
def __init__(self):
self.a = "Some Value"
# And asigning the class name to a variable
class_A = A
# And create instance from class A by using class_A
a = class_A()
Is there such a mechanism in go that allows me to do that? I couldn't know where to look at for such things in their documentation. Honestly, generally I don't know what these are called in programming languages.
For example I would like to be able to do:
// For example, what would be the type of myType?
var myType type = int
I will use this mechanism to take "type" arguments. For example:
func Infer(value interface{}, type gotype) {...}
Is there such a mechanism in go that allows me to do that?
The short answer is: No.
The long answer is: This sounds like an XY Problem, so depending on what you're actually trying to accomplish, there may be a way. Jump to the end to see where I address your specific use-case.
I suspect that if you want to store a data type in a variable, it's because you either want to compare some other variable's type against it, or perhaps you want to create a variable of this otherwise unknown type. These two scenarios can be accomplished in Go.
In the first case, just use a type switch:
switch someVar.(type) {
case string:
// Do stringy things
case int:
// Do inty things
}
Semantically, this looks a lot like assigning the type of someVar to the implicit switch comparison variable, then comparing against various types.
In the second case I mentioned, if you want to create a variable of an unknown type, this can be done in a round-about way using reflection:
type := reflect.TypeOf(someVar)
newVar := reflect.New(type).Interface()
Here newVar is now an interface{} that wraps a variable of the same type as someVar.
In your specific example:
I will use this mechanism to take "type" arguments. For example:
func Infer(value interface{}, type gotype) {...}
No, there's no way to do this. And it actually has much less to do with Go's variable support than it does with the fact that Go is compiled.
Variables are entirely a runtime concept. Function signatures (like all other types in Go) are fixed at compilation time. It's therefore impossible for runtime variables to affect the compilation stage. This is true in any compiled language, not a special feature (or lack thereof) in Go.
Is there such a mechanism in go that allows me to do that?
No there is not.
Use the empty interface:
var x, y interface{}
var a uint32
a = 255
x = int8(a)
y = uint8(a)
Playground example

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

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.

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.

Resources