I am writing a parser in Go for Go, and to test it I downloaded a bunch of files from github projects.
In https://github.com/andlabs/ui I bumped into a file containing this piece of code:
func moveLabel(*Button) {
from := movingCurrent
to := 0
if from == 0 {
to = 1
}
movingBoxes[from].Delete(0)
movingBoxes[to].Append(movingLabel, false)
movingCurrent = to
}
It confuse me a bit to see a pointer to a Button without a name as a function argument, which makes it impossible to reference from inside the function.
However, it seems to be syntactically correct given that the compiler doesn't complains.
What is the purpose of unamed functions arguments in Go?
Unnamed parameters are perfectly valid. The Parameter declaration from the spec:
ParameterDecl = [ IdentifierList ] [ "..." ] Type .
As you can see, the IdentifierList (the identifier name or names) is in square brackets, which means it's optional. Only the Type is required.
The reason for this is because the names are not really important for someone calling a method or a function. What matters is the types of the parameters and their order. This is detailed in this answer: Getting method parameter names in Golang
Generally you name variables and parameters so that you can refer to them.
When you don't name something, it's because you don't want to refer to it.
So the question should rather be: Why would I not want to refer to a parameter?
For example because the parameter "is there" (it is passed), but you don't need it, you don't want to use it. Why would it be there if I don't need it?
Because someone or something dictates for specific parameters to be there. For example you want to implement an interface, or you want to pass a function value whose signature is defined by the function type that is expected.
Let's see an example. We have the following MyWriter interface:
type MyWriter interface {
Write(p []byte) error
}
A simplified io.Writer which only returns an error, but does not report the number of bytes written. If you'd want to provide an implementation which just discards the data (similar to ioutil.Discard), then the implementation does not use (does not need to use) its argument:
type DiscardWriter struct{}
func (DiscardWriter) Write([]byte) error { return nil }
And that's all: we don't use the receiver, we don't use the argument. Both can be unnamed. And the implementation does exactly what it should.
Doing so (using unnamed parameters) also documents that the value is not used / referred to.
Another reason can be to provide forward compatibility. If you release a library, you can't change or extend the parameter list without breaking backward compatibility (and in Go there is no function overloading: if you want 2 variants with different parameters, their names must be different too). So you may declare an exported function or method with additional parameters early, but since you don't use them yet, you may leave them unnamed. An example of this is detailed in this answer: Why does Go allow compilation of unused function parameters?
One thing to note here is that you can't mix named and unnamed parameters. If you name some, you must name all. If you don't need all, you may use the blank identifier like in this example:
A simple web server which responds with the "Hello" text to all requests:
http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
io.WriteString(w, "Hello")
})
panic(http.ListenAndServe(":8080", nil))
The handler function sending back the "Hello" text only uses the response writer w, but not the request structure, so the blank identifier is used as its name.
Another related question:
Why must we declare a variable name when adding a method to a struct in Golang?
Also somewhat related, but regarding using / naming returned values:
Return map like 'ok' in Golang on normal functions
And regarding getting method / function parameter names:
Getting method parameter names in Golang
Unnamed parameters are valid but not referenceable.
They're just for satisfaction of interfaces and signatures.
The purpose of unnamed function arguments is for arguments (which are local variables of the function) which are not referred to in the function's code, and therefore do not need a name. An interesting note about anonymous variables is that they are actually used more commonly than you may think. In Go, a function's return value(s) are usually listed as types, but actually they are also local variables of the function which can be named and manipulated.
See this example in the "Effective Go" page on golang.org
https://golang.org/doc/effective_go.html#named-results
func ReadFull(r Reader, buf []byte) (n int, err error) {
for len(buf) > 0 && err == nil {
var nr int
nr, err = r.Read(buf)
n += nr
buf = buf[nr:]
}
return
}
Related
I have a function that's called quite a few times. How do I now add an additional parameter to that function without having to modify all the call-sites (essentially intruding the default value there and adding a bunch of noise) as well as keeping type safety?
All the languages I have previously used either support default arguments or overloading, so I am quite lost as to how I would do that.
Go doesn't have default arguments, neither it has function overloading. I think, the best you can do without changing the rest of the code is:
Rename the function Func() to FuncWithNewArg()
Add a new argument to FuncWithNewArg()
Create a new function named Func() with the original signature. Func() will call FuncWithNewArg() passing all its argument plus the default value for the new one.
The only way to add an optional argument to a function in Go is with a variadic function. As long as your function doesn't already have any variadic variables, you can add one without requiring all the existing callers to update. However, this does change the function signature, so if you have anything depending on that signature (i.e. assigning the function to a variable), such things may break.
To illustrate, suppose your function is:
func Foo(count int) error {
// do stuff
}
You could add an optional variadic variable at the end:
func Foo(count int, optional ...string) error {
// do stuff
}
You then access the optional variable as as a slice of the designated type ([]string in this case).
Now Foo() can be called as either Foo(3) or Foo(3, "bar").
Actually, it can be called with any number of arguments, so long as they match the type of the variadic variable. I.e. Foo(3, "bar", "baz", "qux") is also valid.
A function can take only a single variadic variable, and it must be the last one. This means you can't mix and match types. For example, this is invalid:
func Foo(count int, optional ...string, alsoOptional ...float64) error
If you need something more flexible than this, your best bet is to add a new function, as suggested in #bereal's answer:
func Foo(count int) error { ... }
func FooWithOther(count int, other string) error { ... }
func FooWithMany(count, int, other string, more bool) error { ... }
I try to check when Golang return a local value as nil, then I use this code.
package main
import (
"fmt"
)
type S struct{}
func InitEfacePointer() interface{} {
var s *S
println(s)
return s
}
func main() {
s := InitEfacePointer()
fmt.Println(s)
//println(s)
}
The output is
0x0
But when I just use println to output value.
package main
type S struct{}
func InitEfacePointer() interface{} {
var s *S
println(s)
return s
}
func main() {
s := InitEfacePointer()
println(s)
}
The output changed to
0x0
(0x93d40,0x0)
Could anyone explain the mechanism of this behavior? Thanks!
You shouldn't be using the builtin println, it clearly states:
The println built-in function formats its arguments in an
implementation-specific way and writes the result to standard error.
Spaces are always added between arguments and a newline is appended.
Println is useful for bootstrapping and debugging; it is not
guaranteed to stay in the language.
And the spec also mentions:
Current implementations provide several built-in functions useful
during bootstrapping. These functions are documented for completeness
but are not guaranteed to stay in the language. They do not return a
result.
Implementation restriction: print and println need not
accept arbitrary argument types, but printing of boolean, numeric, and
string types must be supported.
This is it. print and println are useful debugging tools but should not be relied upon to:
provide a specific output
provide the same output on different platforms
provide the same output over time
exist
That said, I'm guessing that in your case it is printing the internal interface fields: a pointer to a type, and a value.
First of all, fmt.Println and builtin println are very different matteres: they are different both in implentation and in purpose. fmt.Println deals with many complex cases using reflect while println only deal with some base cases and is only for "bootstrap or debug" (as the spec says).
In this specific case, you are printing an interface{} you returned from InitEfacePointer(). The fmt.Println looks into the interface using reflect and gets the underlying data: a nil pointer to a string and it then prints it out: 0x0. On the other hand, builtin println takes the interface and by magic of the compiler (or not), it recognize it is an interface. As this post, golang interface are auctually two pointers, one to information about the type stored and one to the underlying data. So the builtin printlngoes into the interface details, 0x93d40 being the "type info" and 0x0 being the underlying data. (The first 0x0 is from the function call).
Furthermore, testing whether the returned interface is nil seems like a common mistake. Read here: https://golang.org/doc/faq#nil_error
What I'm trying to do:
I have a library package which defines a few types, all implementing a given interface. Throughout the code, there are callbacks involved, and instead of writing the callback type everywhere I defined a type for it.
type Foo interface {
Bar()
}
type MyCallback func(f Foo)
type CoolFoo int
type BadFoo int
func (cf *CoolFoo) Bar(cb MyCallback) {
}
func (bf *BadFoo) Bar(cb MyCallback) {
}
Then later from client code using that library, I want to call using callbacks. If I call it by using the interface type it works:
cf := &CoolFoo{}
cf.Bar(func(f packageName.Foo) {
})
But I would rather have more self documenting code, and proper type hinting in my IDE, so I try to call it using the implementor type, such as this:
cf := &CoolFoo{}
cf.Bar(func(f packageName.CoolFoo) {
})
Which fails to compile, with the error:
cannot use func literal (type func(packageName.CoolFoo)) as type
packageName.MyCallback in argument to cf.Bar
Is it not possible, or am I making some dummy mistake ? I'm not very experienced in go dev, and I've tried looking around, but couldn't find the solution here.
What I've found is passing it as a Foo or an interface{} and then casting in the callback to what I want, but I would like to avoid it as it feels messy
Thanks for any help
The function signature is func(f Foo), so that is exactly what must be passed. The reason is simple: if your method expects a callback function of that signature, it can pass in any type that implements Foo. If you passed in a function that only accepted CoolFoo, the caller could still pass in BadFoo, because the types you've defined allow it. Thus, the compiler requires that the types match precisely. Likewise, if your callback function tries to cast to a concrete type, but that isn't the type that was passed to it, it will fail, because you're making an assumption that isn't supported by the code.
If your callback will only pass in CoolFoo, maybe that should be the type you use in the signature. If CoolFoo and BadFoo will each only pass in their respective types to their callbacks, maybe you need two different callback signatures. If they really are interchangeable, then the case you describe (a function taking CoolFoo specifically) isn't a problem with the language, it's a problem with your design.
On the book The Go Programming Language Phrasebook said:
If you require performance, then you can use statically
typed definitions and avoid the dynamic lookup.
If you require flexibility, then you can use the
late binding mechanism of interfaces
Can someone explain me what "statically typed definitions" and "dynamic lookup" are for methods and functions in Go?
Imagine that we have the following code:
type A struct {}
func (a A) Foo() {
fmt.Println("Foo called")
}
type I interface {
Foo()
}
I can now create a variable of type A and call this method:
a := A{}
a.Foo()
The compiler knows the static type of the variable, so knows that the method call refers to the A.Foo method. So it can compile the above code to use a direct call to A.Foo, which will be as fast as a normal function call.
If instead we use a variable of type I, things are different:
var i I = A{}
i.Foo()
The variable i can hold any type that has a Foo method. In this particular case it is holding an A value, but won't necessarily know this at compile time. So instead the compiler generates code to check the dynamic type of i, look up the associated Foo method and finally call that method. This form of dispatch is slower than the first, but has the benefit the code will work for any type implementing the interface.
This is similar to C++'s distinction between virtual and non-virtual methods, except rather than the type of dispatch being fixed for a method at its definition, it depends on the type of variable you use in Go.
What the book refers to when it says using static types is using non interface types:
func Foo(v int, s string) { ... }
The other option is using interface:
func Bar(a interface{}, b interface{}) { ... }
Because with the first option, Go will know at compile time what type of value the function will retrieve (int and string in this case), it will compile the code specifically for those types.
With the second option, you will have to use reflection at runtime in order to know the values contained in the interfaces. This is a bit of overhead, but it allows you to pass different types of values as parameters to the function, thus being more dynamic.
Further reading: Laws of Reflection in Go
A package I am using, gosqlite, has a method with a variadic parameter where its type is the empty interface.
func (s *Stmt) Exec(args ...interface{}) os.Error
I can call this fine if explicitly pass individual parameters:
statement := blah()
error := statement.Exec("hello", 3.0, true) // works fine
However, as the variadic parameter corresponds to placeholders within the in operator of my SQL statement's select, the number of these placeholders is not known at compile time but dynamically changes at run time depending upon what the user is doing. E.g. I end up with SQL akin to the following if the user enters four values:
SELECT * FROM sky WHERE name IN (?,?,?,?)
So naturally I would like to call the Exec method with a slice of strings:
var values []string = getValuesFromUser()
statement := createStatementWithSufficientNumberOfPlaceholders(len(values))
_ := statement.Exec(values...) // compiler doesn't like this
This does not compile. I can get around this problem by creating an empty interface slice and copying the references over:
values2 := make([]interface{}, len(values))
for index, value := range values { values2[index] = value }
_ := statement.Exec(values2...) // compiler happy but I'm not
And this works fine but it feels a bit clunky. I was wondering if there was some trick to be able to pass values directly to this function or, failing that, a neater way of converting the string slice to an empty interface one?
Many thanks.
There is no way to pass a []string directly to a ...interface{} parameter. Doing this requires a linear time copy (with n + 1 allocations!). If the language hid this from you, it would be a significant hidden cost. Normally, passing a slice to a variadic argument just passes the slice into the function.
As for other ways of doing this, you could make it cleaner by writing a function that takes a []string and returns the corresponding []interface{}. Of course, you'll have to write it again for each []T -> []interface{} conversion you want to do, but its a rather short function, and all that changes is the signature. You could use reflection, which comes with an inherent runtime cost, to make the function "generic", such as in:
valuesVal := reflect.ValueOf(values)
...
for i := range values2 { values2[i] = valuesVal.Index(i).Interface() }
I don't have an answer. And I don't suppose there is one since even built-in and variadic copy and append have the same (or compatible concrete) element type "blockhead", but I have two obvious suggestions:
do not return []string from getValuesFromUser() (i.e. pass still unadorned []interface{}),
on the other type end wrap calls to statement.Exec() with a func making []string to []interface{} conversion.
Or on the same, third, obvious note extend type statement with Exec(args ...string).
P.S. I haven't made any benchmarks myself but I don't think this kind of conversion is highly expensive as interface{} feels like a reference type and compiler is probably doing some dirty trickstery behind the curtain... then again perhaps not, though, I'd be happy, too, to learn of an actual solution.
You need to pass a varargs slice of interface{} type like this to the method.
var paramArray []interface{}
paramArray = append(paramArray, "test1")
paramArray = append(paramArray, "test2")
varargsFunc(paramArray...)