Don't understand variables - go

I'm confused with variables.
Case 1:
package main
var a = "F"
func main() {
n()
m()
n()
}
func n() {
print(a)
}
func m() {
a = "O"
print(a)
}
result = FOO
But when I change a = "O" on (var a = "O" or a := "O") result is FOF.

var a = "O" and a := "O" both declares new variables. That means the a inside m is a different a then the global variable, so setting it to O doesn't change the value of the global one.
You are allowed to shadow variables like this if they are in different scopes, which they are in this case.
One is in the global scope, and one is in the scope of m function.

Related

How to make nil interface to struct in golang

I'm new in Golang.
I executed the code below. I get empty humans array in the end.
What should I do in func F?
For testing(monkeypatch) sake. I have to follow the way how the origin func is called.
package main
import (
"fmt"
)
type Human struct {
Name string
}
type Cat struct {
Name string
}
func F(arr interface{}) {
switch arr.(type) {
case *[]*Human:
arr = &[]*Human{{Name: "abc"}}
arr = arr.(*[]*Human)
case *[]*Cat:
arr = &[]*Cat{{Name: "meow"}}
arr = arr.(*[]*Cat)
}
}
func main() {
var humans []*Human
F(&humans)
fmt.Println(humans)
var cats []*Cat
F(&cats)
fmt.Println(cats)
}
The answer, and the main issue cause as well, is that Go always uses pass by value (or copy of the value) when arguments are passed around to function or assigned to variables.
Your function F takes an arr argument:
func F(arr interface{}) {
//...
}
When called from your main function, you are passing an []*Human pointer as an argument, which values will be copied and fed to your function F for execution.
Going back to your function F body, the arr will be having the same value passed by main, which happens to be the address to the original []*Human struct. Upon assigning a new value to arr:
func F(arr interface{}) {
switch arr.(type) {
case *[]*Human:
arr = &[]*Human{{Name: "abc"}}
// ...
}
}
You are assigning a new value to the local arr variable and not to the original pointer, which remains, indeed, unchanged.
To update the value toward which the argument pointer is referring to, you should used the dereferrence symbol:
func F(arr interface{}) {
switch arr := arr.(type) {
case *[]*Human:
*arr = []*Human{&Human{Name: "abc"}}
fmt.Println(arr)
// ...
}
}
Note the switch arr := arr.(type) statement which creates a new arr variable (shadowing the argument arr) with the interface dynamic type to be able to assign the proper value to it.

How to declare variable types for loop variables in Go?

See this code.
package main
import (
"fmt"
)
func main() {
var arr [4]string = [4]string{"foo", "bar", "baz", "qux"}
for a, b := range arr {
fmt.Println(a, b)
}
// How can I fix this code?
/*
for x int, y string = range arr {
fmt.Println(a, b)
}
*/
}
The first for loop uses the := operator to automatically deduce the types of a and b. But what if I want to explicitly specify the types of the loop variables? My attempt to do this is in the second block of commented code which of course failed with the following error.
# command-line-arguments
./foo.go:15: syntax error: unexpected name, expecting {
./foo.go:18: syntax error: unexpected }
Can you help me fix the second block of code such that I can specify the types of x and y explicitly?
Unfortunately the language specification doesn't allow you to declare the variable type in the for loop. The closest you could get is this:
var a int
var b string
for a, b = range arr {
fmt.Println(a, b)
}
But normally if you give your variable meaningful names, their type would be clear as well:
for index, element := range arr {
fmt.Println(index, element)
}
You need to declare first the vars.
var x int
var y string ...// now it should be ok.
for x,y = range arr {
fmt.Println(x, y) // it should be x and y instead of a,b
}
Check the fiddle
First of all your code is not a valid Go code. The for range loop returns the index and the value of an array, slice, string, or map, so there is no reason the explicitly specify the type of the value and the index.
You are specifying the type of the values at the variable initialization, and the language will deduce the type on the range iteration.
One special case is when you are using interface{} as variable type. In this case, you if you need to know the type of the value you can use the reflect package to deduce the type of the value.
switch reflect.TypeOf(t).Kind() {
case reflect.Slice:
s := reflect.ValueOf(t)
for i := 0; i < s.Len(); i++ {
fmt.Println(s.Index(i))
}
}
It's not possible as you are trying to declare two different types of data in same line, if you want explicitly declare variables, then you need to declare them before itself like above answers, but if you want them to be of other type then you need to covert them as for your needs,
package main
import (
"fmt"
)
func main() {
var arr = [4]string{"foo", "bar", "baz", "qux"}
var x int64
var b []byte
for x = 0; x < int64(len(arr)); x++ {
b = []byte(arr[x])
fmt.Println(x, b)
}
}

Allowing for a variable number of return values in method declaration

I have a function that solves the problem of Go not allowing for the setting of default values in method declarations. I want to make it just a little bit better by allowing for a variable number of return variables. I understand that I can allow for an array of interfaces as a return type and then create an interface array with all the variables to return, like this:
func SetParams(params []interface{}, args ...interface{}) (...[]interface{}) {
var values []interface{}
for i := range params {
var value interface{}
paramType := reflect.TypeOf(params[i])
if len(args) < (i + 1) {
value = params[i]
} else {
argType := reflect.TypeOf(args[i])
if paramType != argType {
value = params[i]
}
value = args[i]
}
values = append(values, value)
}
return values
}
This is an example of a method you want to define default values for. You build it as a variadic function (allowing a variable number of parameters) and then define the default values of the specific params you are looking for inside the function instead of in the declaration line.
func DoSomething(args ...interface{}) {
//setup default values
str := "default string 1"
num := 1
str2 := "default string 2"
//this is fine
values := SetParams([]interface{str, num, str2}, args)
str = values[0].(string)
num = values[1].(int)
str = values[2].(string)
//I'd rather support this
str, num, str2 = SetParams(params, args)
}
I understand that
[]interface{str, num, str2}
in the above example is not syntactically correct. I did it that way to simplify my post. But, it represents another function that builds the array of interfaces.
I would like to support this:
str, num, str2 = SetParams(params, args)
instead of having to do this:
values := SetParams([]interface{str, num, str2}, args)
str = values[0].(string)
num = values[1].(int)
str = values[2].(string)
Any advice? Help?
Please don't write horrible (and ineffective due to reflect) code to solve nonexistent problem.
As was indicated in comments, turning a language into
one of your previous languages is indeed compelling
after a switch, but this is counterproductive.
Instead, it's better to work with the idioms and approaches
and best practices the language provides --
even if you don't like them (yet, maybe).
For this particular case you can roll like this:
Make the function which wants to accept
a list of parameters with default values
accept a single value of a custom struct type.
For a start, any variable of such type, when allocated,
has all its fields initialized with the so-called "zero values"
appropriate to their respective types.
If that's enough, you can stop there: you will be able
to pass values of your struct type to your functions
by producing them via literals right at the call site --
initializing only the fields you need.
Otherwise have pre-/post- processing code which
would provide your own "zero values" for the fields
you need.
Update on 2016-08-29:
Using a struct type to simulate optional parameters
using its fields being assigned default values which happen
to be Go's native zero values for their respective data types:
package main
import (
"fmt"
)
type params struct {
foo string
bar int
baz float32
}
func myfun(params params) {
fmt.Printf("%#v\n", params)
}
func main() {
myfun(params{})
myfun(params{bar: 42})
myfun(params{foo: "xyzzy", baz: 0.3e-2})
}
outputs:
main.params{foo:"", bar:0, baz:0}
main.params{foo:"", bar:42, baz:0}
main.params{foo:"xyzzy", bar:0, baz:0.003}
As you can see, Go initializes the fields of our params type
with the zero values appropriate to their respective types
unless we specify our own values when we define our literals.
Playground link.
Providing default values which are not Go-native zero values for
the fields of our custom type can be done by either pre-
or post-processing the user-submitted value of a compound type.
Post-processing:
package main
import (
"fmt"
)
type params struct {
foo string
bar int
baz float32
}
func (pp *params) setDefaults() {
if pp.foo == "" {
pp.foo = "ahem"
}
if pp.bar == 0 {
pp.bar = -3
}
if pp.baz == 0 { // Can't really do this to FP numbers; for demonstration purposes only
pp.baz = 0.5
}
}
func myfun(params params) {
params.setDefaults()
fmt.Printf("%#v\n", params)
}
func main() {
myfun(params{})
myfun(params{bar: 42})
myfun(params{foo: "xyzzy", baz: 0.3e-2})
}
outputs:
main.params{foo:"ahem", bar:-3, baz:0.5}
main.params{foo:"ahem", bar:42, baz:0.5}
main.params{foo:"xyzzy", bar:-3, baz:0.003}
Playground link.
Pre-processing amounts to creating a "constructor" function
which would return a value of the required type pre-filled
with the default values your choice for its fields—something
like this:
func newParams() params {
return params{
foo: "ahem",
bar: -3,
baz: 0.5,
}
}
so that the callers of your function could call newParams(),
tweak its fields if they need and then pass the resulting value
to your function:
myfunc(newParams())
ps := newParams()
ps.foo = "xyzzy"
myfunc(ps)
This approach is maybe a bit more robust than post-processing but
it precludes using of literals to construct the values to pass to
your function right at the call site which is less "neat".
Recently I was playing with anonymous functions in Go and implemented an example which accepts and returns undefined parameters:
func functions() (funcArray []func(args ... interface{}) (interface{}, error)) {
type ret struct{
first int
second string
third bool
}
f1 := func(args ... interface{}) (interface{}, error){
a := args[0].(int)
b := args[1].(int)
return (a < b), nil
}
funcArray = append(funcArray , f1)
f2 := func(args ... interface{}) (interface{}, error){
return (args[0].(string) + args[1].(string)), nil
}
funcArray = append(funcArray , f2)
f3 := func(args ... interface{}) (interface{}, error){
return []int{1,2,3}, nil
}
funcArray = append(funcArray , f3)
f4 := func(args ... interface{}) (interface{}, error){
return ret{first: 1, second: "2", third: true} , nil
}
funcArray = append(funcArray , f4)
return funcArray
}
func main() {
myFirst_Function := functions()[0]
mySecond_Function := functions()[1]
myThird_Function := functions()[2]
myFourth_Function := functions()[3]
fmt.Println(myFirst_Function(1,2))
fmt.Println(mySecond_Function("1","2"))
fmt.Println(myThird_Function())
fmt.Println(myFourth_Function ())
}
I hope it helps you.
https://play.golang.org/p/d6dSYLwbUB9

Pass By reference in golang [duplicate]

Say I want to pass a pointer to a function and change the value of a struct which that pointer points to by doing so. I would normally do this by dereferencing the pointer:
type Test struct { Value int}
func main() {
var i Test = Test {2}
var p *Test = &i
f(p)
println(i.Value) // 4
}
func f(p *Test) {
*p = Test{4}
}
My question is, why this code doesn't change the value
type Test struct { Value int}
func main() {
var i Test = Test {2}
var p *Test = &i
f(p)
println(i.Value) // 2
}
func f(p *Test) {
// ?
p = &Test{4}
}
while this one does:
type Test struct { Value int}
func main() {
var i Test = Test {2}
var p *Test = &i
f(p)
println(i.Value) // 4
}
func f(p *Test) {
p.Value = 4
}
Because this line:
p = &Test{4}
Just assigns a new pointer value to the p variable. Inside the f() function, p is just a local variable. By assigning any new value to p, you are just changing the value of the local variable and not the pointed value.
The p local variable in f() has nothing to do with the p local variable in main(). If you change p in f(), it will not change p in main() (and it won't change the pointed struct value either).
In your second example:
p.Value = 4
It is a shorthand for:
(*p).Value = 4
This changes the pointed value, hence you will observe the change when f() returns.
Note:
Just as a side note, if in your main() function you would pass the address of p (the local variable in main() which is a pointer) to function f(), you could modify the address stored in main's p:
func f(p **Test) {
*p = &Test{4}
}
And from main(), call it like:
var i Test = Test{2}
var p *Test = &i
f(&p)
println(i.Value) // 2 - Note that 'i' won't change!
println(p.Value) // 4 - Only the address in 'p' to the new struct value created in f()
But obviously passing a single pointer *Test and modifying the pointed value (p.Value = 4) is more efficient, much more convenient and much cleaner.

What's the difference between these functions in golang?

I'm new to Go programming and wondering what's the difference (if any) there between
a.
func DoSomething(a *A) {
b = a
}
b.
func DoSomething(a A) {
b = &a
}
If you are actually asking what the difference of those b's are, one is a pointer to the object passed as an argument to DoSomething, and the other is a pointer to a copy of the object passed as an argument to DoSomething.
https://play.golang.org/p/ush0hDZsdE
type A struct {
f string
}
func DoSomethingPtr(a *A) {
b := a
b.f = "hi"
}
func DoSomething(a A) {
b := &a
b.f = "hey"
}
func main() {
x := A{"hello"}
DoSomething(x)
fmt.Println(x)
DoSomethingPtr(&x)
fmt.Println(x)
}
The variable b would be assigned a different value in each function. The values are different because one is passing a copied value and the other is passing a pointer to the original value in memory.
package main
import "fmt"
type A string
func DoSomethingPtr(a *A) {
fmt.Println(a)
}
func DoSomething(a A) {
fmt.Println(&a)
}
func main() {
x := A("hello")
DoSomething(x)
DoSomethingPtr(&x)
}
Here is the executable proof.
In general, these two functions will assign different values to b. The second one makes a copy of the argument, and so the a inside the function generally has a different memory address than whatever input is passed into the function. See this playground example
package main
type A struct{
x int
}
var b *A
func d(a *A) {
b = a
}
func e(a A) {
b = &a
}
func main() {
var a = A{3}
println(&a)
d(&a)
println(b)
e(a)
println(b)
}
Interestingly, if you make the type A an empty struct instead, and initialize var a = A{}, you actually see the same value for b in the println statements.
That's because for the empty-struct type, there can only really only ever be 1 value, and its immutable, so all instances of it share the same memory address?

Resources