diff --git a/2moretypes/function.go b/2moretypes/function.go new file mode 100644 index 0000000..04f4aa0 --- /dev/null +++ b/2moretypes/function.go @@ -0,0 +1,105 @@ +package main + +import ( + "fmt" + "math" + "reflect" +) + +func compute(fn func(float64, float64) float64) float64 { + return fn(2, 7) +} + +func incrementer() func() int { // returns a function -that requires and returns an int value- + curVal := 0 + return func() int { + curVal += 1 + return curVal + } +} + +func incrementWithNum() func(int) int { // returns a function -that requires and returns an int value- + curVal := 0 + return func(i int) int { + curVal += i + return curVal + } +} + +func adder(a int) func(int) int { // gets first value with adder(int), returns a function -that requires and returns an int value- + return func(b int) int { + return a + b + } +} + +func main() { + fmt.Println("Includes function values, closures and other function related subject, if you want to see functions basics, go to 0basics/basics.go > Section \"Functions\"") + + fmt.Println("Functions are values too, They can be passed around just like other values") + + sum := func(x, y float64) float64 { + return float64(x + y) + } + fmt.Println(sum(2, 3)) + fmt.Println(sum) + fmt.Println(&sum) + fmt.Println(reflect.TypeOf(sum)) + fmt.Println(reflect.TypeOf(sum).Kind()) + + fmt.Printf("\n\n") + fmt.Println("Function values may be used as function arguments and return values") + fmt.Println(compute(sum)) + fmt.Println(compute(math.Pow)) + fmt.Printf("%p\n", compute) + fmt.Println(reflect.TypeOf(compute)) + fmt.Println(reflect.TypeOf(compute).Kind()) + + fmt.Printf("\ncompute a function that gets a function as an argument (that gets two float64 values and returns float64) and returns float64\n\n\n") + + fmt.Println("Go functions may be closures") + fmt.Println("With this feature inner functions can read outer functions values, use them. Also with assigning it to a variable we can use same function from scratch") + fmt.Println("A bit confusing but just see the examples:") + + // SECTION incrementer() + newInc1 := incrementer() + fmt.Println(newInc1()) + fmt.Println(newInc1()) + fmt.Println(newInc1()) + + fmt.Printf("\n") + + newInc1 = incrementer() // you can initialize again + fmt.Println(newInc1()) + + newInc2 := incrementer() + newInc2() + newInc2() + newInc2() + newInc2() + newInc2() + fmt.Println(newInc2()) + + fmt.Println(newInc1()) + + fmt.Printf("\n\n") + // !SECTION + // SECTION incrementWithNum() + numInc1 := incrementWithNum() + // fmt.Println(numInc1()) // ERROR, not enough arguments in call to numInc1 + fmt.Println(numInc1(4)) // Increments curVal by 4 and print out + fmt.Println(numInc1(3)) // Increments curVal by 3 and print out + fmt.Println(numInc1(2)) // "" 2 "" + fmt.Println(numInc1(1)) // "" 1 "" + + fmt.Printf("\n\n") + // !SECTION + // SECTION adder() + + myAdder1 := adder(5) + fmt.Println(myAdder1(1)) // 5+1=6 + fmt.Println(myAdder1(8)) // 5+8=13 + + myAdder2 := adder(8) + fmt.Println(myAdder2(myAdder1(3))) // 8 + (5+3) + +} diff --git a/exercises/fibonacci.go b/exercises/fibonacci.go new file mode 100644 index 0000000..89b10a9 --- /dev/null +++ b/exercises/fibonacci.go @@ -0,0 +1,24 @@ +package main + +// exercise link: https://go.dev/tour/moretypes/26 + +import "fmt" + +// fibonacci is a function that returns +// a function that returns an int. +func fibonacci() func() int { + first := 0 + second := 1 + return func() int { + second += first + first = second - first + return first + } +} + +func main() { + f := fibonacci() + for i := 0; i < 10; i++ { + fmt.Println(f()) + } +}