Go Exercises and Questions
OTHER License
ℹ️ This repo contains questions and exercises to learn and practice Golang
📊 There are currently 98 exercises and questions
Name | Exercise | Solution | Comments |
---|---|---|---|
Hello World! | Exercise | Solution | |
Variables & Constants | Exercise | Solution | |
Arithmetic Operators | Exercise | Solution | |
Data Types | Exercise | Solution | |
User Input | Exercise | Solution | |
Packages | Exercise | Solution | |
Logical Operators | Exercise | Solution | |
Conditionals | Exercise | Solution | |
Switch | Exercise | Solution |
Name | Exercise | Solution | Comments |
---|---|---|---|
Split Strings | Exercise | Solution |
Name | Exercise | Solution | Comments |
---|---|---|---|
Arrays 101 | Exercise | Solution | |
Slices 101 | Exercise | Solution |
Name | Exercise | Solution | Comments |
---|---|---|---|
Maps 101 | Exercise | Solution |
Name | Exercise | Solution | Comments |
---|---|---|---|
Loops 101 | Exercise | Solution | |
Loops 102 | Exercise | Solution | |
Continue | Exercise | Solution |
Name | Exercise | Solution | Comments |
---|---|---|---|
Functions 101 | Exercise | Solution | |
Named Return Values | Exercise | Solution |
Name | Exercise | Solution | Comments |
---|---|---|---|
Generics 101 | Exercise | Solution |
True
Any exported variable, function, ... begins with a capital letter. In fact when using a package, you can use only the things the package exports for you and others to use.
package main
import "fmt"
func main() {
x := 2
var y int = 2
fmt.Printf("x: %v. y: %v", x, y)
}
package main
import "fmt"
func main() {
var userName
userName = "user"
fmt.Println(userName)
}
Error. The type userName is not defined. It has to be declared or the value assignment should happen at declaration.
So both var userName = user
and var userName string
are valid.
The result is the same, a variable with the value 2.
With var x int = 2 we are setting the variable type to integer, while with x := 2 we are letting Go figure out by itself the type. The result is the same, both styles can't be used in every situation. For example, short declaration can't be used outside of a function.
package main
import "fmt"
x := 2
func main() {
x = 3
fmt.Println(x)
}
It will fail with expected declaration, found x
as outside of a function, every statement should start with a keyword (and short variable declarations won't work).
package main
import "fmt"
var (
x bool = false
y int = 0
z string = "false"
)
func main() {
fmt.Printf("The type of x: %T. The value of x: %v\n", x, x)
fmt.Printf("The type of y: %T. The value of y: %v\n", y, y)
fmt.Printf("The type of z: %T. The value of z: %v\n", y, y)
}
Package level variables are variables that defined at the package level instead of a specific function (like main for example).
If you have multiple functions in your package that use the same variables, it might make these variables available to the functions by defining them at the package level. This can be in the same file or any file under the same package. For example:
package main
var packageLevelVar int = 0
func main() {
nonPackageLevelVar := 0
}
func main() {
var x float32 = 13.5
var y int
y = x
}
package main
import "fmt"
func main() {
var x int = 2
fmt.Println(x)
var y float32 = float32(x)
fmt.Println(y)
}
package main
import "fmt"
func main() {
var x int = 101
var y string
y = string(x)
fmt.Println(y)
}
It looks what unicode value is set at 101 and uses it for converting the integer to a string. If you want to get "101" you should use the package "strconv" and replace y = string(x) with y = strconv.Itoa(x)
package main
import "fmt"
func main() {
var x uint
x = -3
// comment!
fmt.Println(x)
}
Error. When x
is declared as uint
it means you can't put any negative values. But because we did put a negative value (-3
) it will fail to compile it.
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("A random integer:", rand.Intn(10))
}
// Single constant
const x int = 2732
// Multiple constants in one block
const (
y = 2017
z = 2022
)
package main
func main() {
var x int = 2
var y int = 3
const someConst = x + y
}
package main
import "fmt"
func main() {
const X := 2
fmt.Print(X)
}
It won't run. Constants cannot be declared using :=
.
package main
import "fmt"
const (
Const1 = 1
Const2 = 1 < 2
Const3 = 1 << 10
)
func main() {
fmt.Println(Const1)
fmt.Println(Const2)
fmt.Println(Const3)
}
1 true 1024
The 1024 result is because we shifted a 1 bit left 10 places.
package main
import "fmt"
func main() {
x := 2017
fmt.Println(x > 2022 && x < 3000)
fmt.Println(x > 2000 && x < 3000)
fmt.Println(x > 2000 && x&2 == 0)
}
false
true
false
package main
import "fmt"
func main() {
x := 2017
fmt.Println(x > 2022 || x < 3000)
fmt.Println(x > 2000 || x < 3000)
fmt.Println(x > 2000 || x&2 == 0)
}
true
true
true
package main
import "fmt"
func main() {
x := true
fmt.Println(x)
fmt.Println(!x)
fmt.Println(!x && x)
fmt.Println(!x || x)
}
true
false
false
true
var some_string := "Hello, World"
Hello,
World
var some_string := "Hello,\nWorld"
package main
import "fmt"
func main() {
some_string := `Hello,\nWorld`
fmt.Println(some_string)
}
package main
import "fmt"
func main() {
some_string := "There"
fmt.Println("Hello", some_string)
}
Hello There
package main
import "fmt"
func main() {
str := "Hello, world!"
fmt.Println(len(str))
}
var str string = "cowabunga"
fmt.Println(str[3])
97 Because it prints the ascii code of 'a' which is 97.
fmt.Println(str[3:5])
'ab'
x := 5
if x > 0 {
fmt.Print("It's bigger than 0!")
}
rand.Seed(time.Now().UnixNano())
var x int = rand.Intn(100)
if x > 10 {
fmt.Print("yay!")
} else {
fmt.Print("nay!")
}
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
if randNum := rand.Intn(100); randNum%2 == 0 {
fmt.Print("Bingo!")
} else {
fmt.Print(randNum)
}
}
Defines a variable with random value between 0 and 100. If the random value is even, prints "Bingo!" otherwise, prints the random value itself.
package main
import (
"fmt"
"time"
)
func main() {
today := time.Now().Weekday().String()
switch today {
case "Sunday":
fmt.Println("Here we go")
case "Monday":
fmt.Println("We have just started")
default:
fmt.Println(today)
}
}
var name string
fmt.Scan(name)
fmt.Println(name)
var name string
fmt.Scan(&name)
fmt.Println(name)
Because we want to reference the memory address of the variable, this is where the user input will be stored.
var age int = 3
fmt.Println(age)
fmt.Println(&age)
The value of age
variable and then the memory location of age
variable
var x [4]int
var rgb = [3]string{"red", "green", "blue"}
[0 0 0 0 0 0 0 0 0 0]
var arr = [10]int{5, 9: 100}
var arr = [...]int{1, 2, 3, 4}
var anotherArr = [4]int{1, 2, 3, 4}
fmt.Println(arr == anotherArr)
The result of comparison is true.
fmt.Println(len(arr))
False. Go treats the array size as being part of the type itself. So [1]int type != [2]int type.
False. It's not possible to use variable to define an array of certain size. As the size of an array is part of its type and types must be resolved at compile time, not runtime.
var slice []int
var slice = []int{1, 2}
b = append(b, 7)
[2 0 1 7 2 0 2 2]
package main
import (
"fmt"
"reflect"
)
func main() {
x := []int {2, 0, 1, 7}
y := []int {2, 0, 2, 2}
fmt.Println(reflect.DeepEqual(x, y))
}
Because in Go when you pass a something to a function, it copies it. So when we append something to a slice it appends it to a copy of it. So in order to change the original slice, we need to assign the returned copy back into the original slice.
slice := make([]int, 20)
slice := make([]int, 3, 20)
It's more efficent to set the size once for a slice rather than increase its capacity every times new items added to it.
slice := make([]int, 3)
slice = append(slice, 41)
[0 0 0 41]
True. Otherwise it will cause compile-time error or run-time error, depends on how you defined it.
slice[:]
slice[2:]
slice[:1]
slice[2:4]
[1 2 3 4 5]
[3 4 5]
[1]
[3 4]
slice := []int{1, 2, 3}
anotherSlice := slice[1:]
slice[1] = 999
anotherslice[1] = 5
fmt.Println("slice:", slice)
fmt.Println("slice:", anotherSlice)
[10 999 3]
[999 5]
The expalantion is that slicing a slice isn't creating a copy of the data but rather creates another variable that shares the very same memory.
When creating a slice of a slice, it will create variable that shares the same memory. To create a slice that is indepdant of the original slice, you can use the built-in function copy
slice := []int{1, 2, 3}
destSlice = make([]int, 3)
numOfElements := copy(slice, destSlice)
i
initialized to 0i
should be added to a variable called sum
(initialize the variable before the loop with value of 0)sum := 0
for i := 0; i < 50; i++ {
sum += i
}
for {
fmt.Print("forever!")
}
for {
fmt.Print("forever!")
}
for true {
fmt.Print("forever!")
}
From result perspective, there is no difference. Both are infinite loops.
var someMap = map[string]string
anotherMap := map[string]int{}
nonEmptyMap := map[string][]int{
"someKey": []int{1, 2, 3},
"anotherKey": []int{4, 5, 6},
}
someMap := make(map[int][]string, 100)
True. This is also true for the all the values in a single map.
len(someMap)
False.
someMap := map[string]int{}
someMap["x"] = 41
fmt.Println(someMap["y"])
0
someMap := map[string]int{
"x": 41,
}
value, exists := someMap["x"]
fmt.Println(value, exists)
value, exists = someMap["y"]
fmt.Println(value, exists)
41 true 0 false
someMap := map[string]int{
"x": 41,
"y": 303,
"z": 56,
}
delete(someMap, "y")
func PrintHelloWorld() {
fmt.Println("Hello World")
}
func add(x int, y int) int {
return x + y
}
add is a function that takes two parameters (two integers) and returns their sum.
func add(x int, y int) int {
return x + y
}
func add(x, y int) int {
return x + y
}
Both. If two or more parameters share the same type, you can specify it only once.
False. A fucntion in Go can return multiple values
func swap(x, y string) (string, string) {
return y, x
}
x, y = swap("and roll", "rock")
fmt.Println(a, b)
func process(num int) (x int) {
x = num + 10
var z = num - x
x = z + x
return
}
func main() {
fmt.Println(process(10))
}
10
package main
import "fmt"
func main() {
defer fmt.Println("1")
fmt.Println("2")
}
2
1
2 is printed before 1 due to the defer statement. The defer
statement defers the execution of the function (fmt.Println("1")
) until the surrounding fucntion (which is main()
) returns.
True.
package main
import "fmt"
func main() {
fmt.Println("100")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("200")
}
100
200
9
8
7
6
5
4
3
2
1
0
Deferred functions are executed in a last-in-first-out order, this is why it prints it from 9 to 0 instead of from 0 to 9.
Capitalize the first letter of what you would like to export.
By creating an interface.
package main
type C interface {
int | int32 | string
}
package main
import "fmt"
type C interface {
int | int32 | string
}
func show[T C](input T) {
fmt.Println(input)
}
Because we created show function as a generic function. Therefore it can get types that we have in C.
package main
import "log"
func do_log(input string) {
log.Print(input)
}
Use any keyword.
package main
import "log"
func do_log(input any) {
log.Print(input)
}
Name | Description | Solution | Comments |
---|---|---|---|
Simple Web Server | Description | Solution |
Go Gopher was designed by Renee French. The specific Go Gophers designs used in this project created by Arie Bregman