Understanding the switch statement and pointers in Go [closed] - go

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I can't figure out why this Go code with pointers and using the switch statement prints out "a":
import "fmt"
func main() {
var a, b int
var c = &b
switch *c {
case a:
fmt.Println("a")
case b:
fmt.Println("b")
default:
fmt.Println("c")
}
}
Any hints to this?

a and b are both zero (the zero value for integers).
Initializing c = &b means that c is a *int pointing to b.
Moving on to the switch statement, we are checking the value of *c which dereferences c and is the value of b, which is 0.
Since a is also zero, the first case matches.
You can swap the case a and case b statements and put b first. In that case, it will print b since it is now the first matching case:
package main
import "fmt"
func main() {
var a, b int
var c = &b
switch *c {
case b:
fmt.Println("b")
case a:
fmt.Println("a")
default:
fmt.Println("c")
}
}

Related

Trying to understand structs in Golang? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 days ago.
Improve this question
I don't seem to understand why I cannot re-assignee inner struct?
I have two structs, outer and inner. I am able to manipulate with primitive values, but not with nested struct values.
type Vertex struct {
X int
Y int
K VertexInner
}
type VertexInner struct {
X int
Y int
}
func main2() {
inner := VertexInner{3,4}
v := Vertex{1, 2, inner}
p := &v
p.X = 1e9
var newInner *VertexInner
newInner = new(VertexInner)
newInner2 := VertexInner{
X: 1,
Y: 22,
}
p.K = newInner; // NOT WORKING
p.K := newInner2 ; // NOT WORKING
}

Technical reasons behind Go's strange syntax [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I recently started learning to Go, and I am quite confused as to why it has a strange "non-traditional" syntax unlike other languages (C, C++, C#, JAVA)
For example, a code like this in Go:
package main
import "fmt"
func sum(a int, b int) int {
return a + b
}
func main() {
numbers := [4] int {1, 2, 3, 4}
for _,n := range numbers {
result := sum(n, 2)
fmt.Println(result)
}
}
But, could be written something like in some languages:
package main
import "io"
int sum(int a, int b) {
return a + b
}
void main() {
int numbers[4] = {1, 2, 3, 4}
foreach (n in range(numbers)) {
result = sum(n, 2)
io.print(result)
}
}
So my question is, is there any technical reason behind this syntax, or is it just a personal preference of the team? Especially that the team behind Go used "C Language" to write Go, which means it would've made much more sense to type it in C-Style syntax ?
Few points that I'd like to highlight:
Go is inspired by many languages and not just C.
C: statement and expression syntax
Pascal: declaration syntax
Modula 2, Oberon 2: packages
CSP, Occam, Newsqueak, Limbo, Alef: concurrency
BCPL: the semicolon rule
Smalltalk: methods
Newsqueak: <-, :=
APL: iota
There are more
From when foreach and range become C-style syntax?
Third, don't confuse "For" statements with for clause and range clause. Read the spec.
In Go, you can do this is as well:
for i := 0; i < len(numbers); i++
But range clause is much more powerful once you understand it and yes it is not strange syntax. I'd suggest to read the spec and see a few examples.
Also, it's Go and not GoLang (Read). Always prefer the former over the latter.
Try the Go Tour. Some concepts are explained well.
Also, read Go's FAQ and Pike's blog on declaration syntax. The FAQ should answer many such queries.
import "io"
Go has fmt and io packages, although they do have some overlap. For example, fmt.Fprint lets you write to any io.Writer, and fmt.Fscan lets you read from any io.Reader.
Similarly you can write to console with io.Copy(os.Stdout, something), and read from console with io.Copy(something, os.Stdin).
int sum(int a, int b) {
I think I read that by having func first, it makes lexical parsing much faster. Also Go function can have named return values:
func sum(a int, b int) (n int)
I am not sure how you'd do that with the other syntax.
int numbers[4] = {1, 2, 3, 4}
Go syntax allows you to omit the type, which you can't do with C.
foreach (n in range(numbers))
Go doesn't have a while keyword, for the reason that less keywords again makes for faster lexical parsing. Instead you have different for invocations:
var n int
for {
if n > 9 {
break
}
println(n)
n++
}
var n int
for n < 9 {
println(n)
n++
}
for n := 0; n < 9; n++ {
println(n)
}
for range numbers {
println("hello")
}
for index := range numbers {
println(index)
}
for index, value := range numbers {
println(index, value)
}
For this:
result = sum(n, 2)
Go has two different syntax for variable assignment:
result := 1
result = 2
First is a declaration, second is assigning to an already declared variable.
io.print(result)
fmt.Println is uppercase, because any function that starts with an uppercase letter is a "public" function. This saves on typing public or pub everywhere.

How to parse slice from an other function [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I have the following Go snippet. I have a slice
package main
import "fmt"
func main() {
y := []int{0, 1, 1, 2, 3, 5, 8}
return y
}
func toParseY(int y) {
for i, v := range y {
fmt.Println(i, v)
}
}
I know that I have to pass the slice as argument to the toParseY function, but when I try it I get this error (the compiler doesn't even get the
# command-line-arguments
./ude.go:8:2: too many arguments to return
have ([]int)
want ()
./ude.go:11:19: undefined: y
./ude.go:12:20: undefined: y
What's the proper way to achieve it in Go?
Here is the corrected code...
package main
import "fmt"
func main() {
y := []int{0, 1, 1, 2, 3, 5, 8}
toParseY(y)
}
func toParseY(y []int) {
for i, v := range y {
fmt.Println(i, v)
}
}
Issues:
Don't return y from main. Instead, call toParseY() from main.
You needed to fix the data type that toParseY accepts to be a slice of int and correct the order in which you declare the parameter. It should be parameter name, followed by data type: toParseY(y []int)
Output:

Why do we add & in the following script, if it does not make any change on the result? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
package main
import (
"fmt"
"math"
"reflect"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4} // Whether or not with "&", the values don't change below.
fmt.Printf("Before scaling: %+v, Abs: %v\n", v, v.Abs())
v.Scale(5)
fmt.Printf("After scaling: %+v, Abs: %v\n", v, v.Abs())
fmt.Println(reflect.TypeOf(Vertex{3,4}))
}
Hello, I am learning golang now. I do not understand what is the use of adding "&", if it does not make any change on the result value?
I thought we add "&" to variables to get the memory address. If we can add "&" to Vertex{3,4}, does this mean it is variable? Confused.
I assume you're talking about Vertex vs &Vertex? Yes, adding & means that v now contains an address to a struct of type Vertex, whereas without the &, v would hold the struct directly.
In your example, using the address, or the struct directly, makes no difference. In many other cases, the distinction is very important.

Precision loss when printing floats as strings [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
It just happened to me that if I store int number into a struct and later apply division with them. The precision would be lost.
func main() {
var x = 94911151
var y = 94911150
// If we use the value to calculate division directly, it would be fine
var result1 = float64(94911151)/94911150
var result2 = float64(x)/float64(y)
fmt.Println(result1, result2)
// If we pass the values directly as parameter into a function and then apply division, it would be fine
getParas(x,y)
// If we pass the values into a stuct, and then retrieve the value from struct, then apply division, the precision would be lost.
getLinearParas(Point{x,y},Point{0,0})
}
func getParas(a int, b int){
diffX := a -0
diffY := b-0
c:= float64(diffX) / float64(diffY)
fmt.Println(c)
}
type Point struct{
X int
Y int
}
func getLinearParas(point1 Point, point2 Point) {
diffX := point1.X - point2.X
diffY := point1.Y - point2.Y
a := float64(diffX) / float64(diffY)
fmt.Printf("diffY: %d; diffX:%d ; a:%f \n", diffY, diffX, a)
}
Like the code, If I put int values into a struct, and later apply division on them. the precision would be lost somehow.
The result of running above code is
1.00000001053617 1.00000001053617
1.00000001053617
diffY: 94911150; diffX:94911151 ; a:1.000000
Or you can try it yourself in playground
https://play.golang.org/p/IDS18rfv9e6
Could anyone explain why this happens? and how to avoid such loss?
Thank you very much.
Change %f in the format string to %v or %g or %.14f. fmt.Println prints things with the equivalent of %v, %v for float64 is treated as %g. %f prints values with 6 significant digits by default, %g uses "the smallest number of digits necessary to identify the value uniquely".

Resources