Исходники и презентации
This commit is contained in:
26
lessons/functions/composition/main.go
Normal file
26
lessons/functions/composition/main.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func sqr(number int) int {
|
||||
return number * number
|
||||
}
|
||||
|
||||
func neg(number int) int {
|
||||
return -number
|
||||
}
|
||||
|
||||
func compose(fn ...func(int) int) func(int) int {
|
||||
return func(value int) int {
|
||||
for _, v := range fn {
|
||||
value = v(value)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fn := compose(sqr, neg, sqr)
|
||||
fmt.Println(fn(4))
|
||||
}
|
||||
30
lessons/functions/continuation/main.go
Normal file
30
lessons/functions/continuation/main.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Divide1(lhs, rhs int) int {
|
||||
if rhs == 0 {
|
||||
panic("incorrect argument") // Why???
|
||||
} else {
|
||||
return lhs / rhs
|
||||
}
|
||||
}
|
||||
|
||||
func Divide2(lhs, rhs int, successFn func(int), errorFn func()) {
|
||||
if rhs == 0 {
|
||||
errorFn()
|
||||
} else {
|
||||
successFn(lhs / rhs)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
Divide2(100, 10,
|
||||
func(number int) {
|
||||
fmt.Println(number)
|
||||
},
|
||||
func() {
|
||||
fmt.Println("incorrect argument")
|
||||
},
|
||||
)
|
||||
}
|
||||
42
lessons/functions/conveyor/main.go
Normal file
42
lessons/functions/conveyor/main.go
Normal file
@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func sqr(number int) int {
|
||||
return number * number
|
||||
}
|
||||
|
||||
func neg(number int) int {
|
||||
return -number
|
||||
}
|
||||
|
||||
func inc(number int) int {
|
||||
return number + 1
|
||||
}
|
||||
|
||||
func pipe(value int, fn ...func(int) int) int {
|
||||
for _, v := range fn {
|
||||
value = v(value)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reverse(fn ...func(int) int) []func(int) int {
|
||||
for idx := 0; idx < len(fn)/2; idx++ {
|
||||
fn[idx], fn[len(fn)-idx-1] = fn[len(fn)-idx-1], fn[idx]
|
||||
}
|
||||
|
||||
return fn
|
||||
}
|
||||
|
||||
func main() {
|
||||
// decorator way
|
||||
decorationResult := inc(neg(sqr(5)))
|
||||
fmt.Println(decorationResult)
|
||||
|
||||
// composition way
|
||||
compositionResult1 := pipe(5, sqr, neg, inc)
|
||||
compositionResult2 := pipe(5, reverse(inc, neg, sqr)...)
|
||||
fmt.Println(compositionResult1, compositionResult2)
|
||||
}
|
||||
20
lessons/functions/currying/main.go
Normal file
20
lessons/functions/currying/main.go
Normal file
@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func multiply(x int) func(y int) int {
|
||||
return func(y int) int {
|
||||
return x * y
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(multiply(10)(15))
|
||||
|
||||
// частичное применение
|
||||
var mult10 = multiply(10)
|
||||
var mult15 = multiply(15)
|
||||
|
||||
fmt.Println(mult10(5))
|
||||
fmt.Println(mult15(15))
|
||||
}
|
||||
28
lessons/functions/decorator/main.go
Normal file
28
lessons/functions/decorator/main.go
Normal file
@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Add(x, y int) int {
|
||||
return x + y
|
||||
}
|
||||
|
||||
func Mul(x, y int) int {
|
||||
return x * y
|
||||
}
|
||||
|
||||
func Calculate(x, y int, fn func(int, int) int) int {
|
||||
fmt.Printf("x=%d y=%d\n", x, y)
|
||||
return fn(x, y)
|
||||
}
|
||||
|
||||
func CalculateAdd(x, y int) int {
|
||||
fmt.Printf("x=%d y=%d\n", x, y)
|
||||
return Add(x, y)
|
||||
}
|
||||
|
||||
func main() {
|
||||
Calculate(10, 10, Add)
|
||||
Calculate(10, 10, Mul)
|
||||
|
||||
CalculateAdd(10, 10)
|
||||
}
|
||||
28
lessons/functions/defer_calculating/main.go
Normal file
28
lessons/functions/defer_calculating/main.go
Normal file
@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Need to show solution
|
||||
|
||||
const (
|
||||
StatusOk = "ok"
|
||||
StatusError = "error"
|
||||
)
|
||||
|
||||
func notify(status string) {
|
||||
fmt.Println(status)
|
||||
}
|
||||
|
||||
func process() {
|
||||
var status string
|
||||
defer func(s string) {
|
||||
notify(s)
|
||||
}(status)
|
||||
|
||||
// processing..
|
||||
status = StatusError
|
||||
}
|
||||
|
||||
func main() {
|
||||
process()
|
||||
}
|
||||
12
lessons/functions/defer_evaluation_moment/main.go
Normal file
12
lessons/functions/defer_evaluation_moment/main.go
Normal file
@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
var f func()
|
||||
defer f()
|
||||
|
||||
f = func() {
|
||||
fmt.Println(true)
|
||||
}
|
||||
}
|
||||
13
lessons/functions/defer_inactive/main.go
Normal file
13
lessons/functions/defer_inactive/main.go
Normal file
@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
defer fmt.Println("code")
|
||||
if false {
|
||||
defer fmt.Println("unreacheable code")
|
||||
}
|
||||
|
||||
return
|
||||
defer fmt.Println("unreacheable code")
|
||||
}
|
||||
21
lessons/functions/defer_inside_loop/main.go
Normal file
21
lessons/functions/defer_inside_loop/main.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import "os"
|
||||
|
||||
func readFiles(paths []string) error {
|
||||
for _, path := range paths {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// reading file...
|
||||
defer file.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
_ = readFiles([]string{"text1.txt", "text2.txt", "text3.txt"})
|
||||
}
|
||||
15
lessons/functions/defer_modification_1/main.go
Normal file
15
lessons/functions/defer_modification_1/main.go
Normal file
@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Modify(value int) (result int) {
|
||||
defer func() {
|
||||
result += value
|
||||
}()
|
||||
|
||||
return value + value
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(Modify(5))
|
||||
}
|
||||
16
lessons/functions/defer_modification_2/main.go
Normal file
16
lessons/functions/defer_modification_2/main.go
Normal file
@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Modify(value int) int {
|
||||
var result int
|
||||
defer func() {
|
||||
result += value
|
||||
}()
|
||||
|
||||
return value + value
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(Modify(5))
|
||||
}
|
||||
11
lessons/functions/defer_nil/main.go
Normal file
11
lessons/functions/defer_nil/main.go
Normal file
@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
defer fmt.Println("reachable 1")
|
||||
var f func()
|
||||
defer f()
|
||||
|
||||
fmt.Println("reachable 2")
|
||||
}
|
||||
25
lessons/functions/defer_order/main.go
Normal file
25
lessons/functions/defer_order/main.go
Normal file
@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func process1() {
|
||||
defer fmt.Println(3)
|
||||
defer fmt.Println(2)
|
||||
defer fmt.Println(1)
|
||||
}
|
||||
|
||||
func process2() {
|
||||
defer func() {
|
||||
defer fmt.Println(4)
|
||||
defer fmt.Println(3)
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
defer fmt.Println(2)
|
||||
defer fmt.Println(1)
|
||||
}()
|
||||
}
|
||||
|
||||
func main() {
|
||||
process1()
|
||||
}
|
||||
31
lessons/functions/defer_performance/comparison_test.go
Normal file
31
lessons/functions/defer_performance/comparison_test.go
Normal file
@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
// go test -bench=. comparison_test.go
|
||||
|
||||
//go:noinline
|
||||
func withDefer(a, b int) {
|
||||
defer func() {
|
||||
Result = a + b
|
||||
}()
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func withoutDefer(a, b int) {
|
||||
Result = a + b
|
||||
}
|
||||
|
||||
var Result int
|
||||
|
||||
func BenchmarkWithDefer(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
withDefer(-1, i)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkWithoutDefer(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
withoutDefer(-1, i)
|
||||
}
|
||||
}
|
||||
19
lessons/functions/defer_union/main.go
Normal file
19
lessons/functions/defer_union/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func process1() {
|
||||
defer fmt.Println("test1")
|
||||
defer fmt.Println("test2")
|
||||
|
||||
// implementation...
|
||||
}
|
||||
|
||||
func process2() {
|
||||
defer func() {
|
||||
fmt.Println("test2")
|
||||
fmt.Println("test1")
|
||||
}()
|
||||
|
||||
// implementation...
|
||||
}
|
||||
21
lessons/functions/defer_with_function/main.go
Normal file
21
lessons/functions/defer_with_function/main.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func get() string {
|
||||
fmt.Println("1")
|
||||
return ""
|
||||
}
|
||||
|
||||
func handle(string) {
|
||||
fmt.Println("3")
|
||||
}
|
||||
|
||||
func process() {
|
||||
defer handle(get())
|
||||
fmt.Println("2")
|
||||
}
|
||||
|
||||
func main() {
|
||||
process()
|
||||
}
|
||||
37
lessons/functions/filename_like_argument/main.go
Normal file
37
lessons/functions/filename_like_argument/main.go
Normal file
@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func ProccessDataInFile(filename string) (string, error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var data string
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
// processing...
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func ProccessData(reader io.Reader) (string, error) {
|
||||
if reader == nil {
|
||||
return "", errors.New("incorrect reader")
|
||||
}
|
||||
|
||||
var data string
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
// processing...
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
38
lessons/functions/functions_inlining/comparison_test.go
Normal file
38
lessons/functions/functions_inlining/comparison_test.go
Normal file
@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
// go test -bench=. comparison_test.go
|
||||
|
||||
//go:noinline
|
||||
func maxWithoutInline(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func maxWithInline(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
var Result int
|
||||
|
||||
func BenchmarkMaxWithoutInline(b *testing.B) {
|
||||
var r int
|
||||
for i := 0; i < b.N; i++ {
|
||||
r = maxWithoutInline(-1, i)
|
||||
}
|
||||
_ = r
|
||||
}
|
||||
|
||||
func BenchmarkMaxWithInline(b *testing.B) {
|
||||
var r int
|
||||
for i := 0; i < b.N; i++ {
|
||||
r = maxWithInline(-1, i)
|
||||
}
|
||||
_ = r
|
||||
}
|
||||
18
lessons/functions/generator/main.go
Normal file
18
lessons/functions/generator/main.go
Normal file
@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Generator(number int) func() int {
|
||||
return func() int {
|
||||
r := number
|
||||
number++
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
generator := Generator(100)
|
||||
for i := 0; i <= 200; i++ {
|
||||
fmt.Println(generator())
|
||||
}
|
||||
}
|
||||
22
lessons/functions/high_order_function/main.go
Normal file
22
lessons/functions/high_order_function/main.go
Normal file
@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func forEach(data []int, fn func(int) int) []int {
|
||||
newData := make([]int, 0, len(data))
|
||||
for _, value := range data {
|
||||
newData = append(newData, fn(value))
|
||||
}
|
||||
|
||||
return newData
|
||||
}
|
||||
|
||||
func main() {
|
||||
var data = []int{1, 2, 3, 4}
|
||||
var newData = forEach(data, func(value int) int {
|
||||
return (value * value)
|
||||
})
|
||||
|
||||
fmt.Println(data)
|
||||
fmt.Println(newData)
|
||||
}
|
||||
19
lessons/functions/imperative_declarative/main.go
Normal file
19
lessons/functions/imperative_declarative/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
func filterEvenNumbers(numbers []int) []int {
|
||||
return nil // implemented
|
||||
}
|
||||
|
||||
func main() {
|
||||
// imperative way
|
||||
var imperative []int
|
||||
for _, number := range []int{1, 2, 3, 4, 5} {
|
||||
if number%2 != 0 {
|
||||
imperative = append(imperative, number)
|
||||
}
|
||||
}
|
||||
|
||||
// declarative way
|
||||
declarative := filterEvenNumbers([]int{1, 2, 3, 4, 5})
|
||||
_ = declarative
|
||||
}
|
||||
31
lessons/functions/lazy_evaluation/main.go
Normal file
31
lessons/functions/lazy_evaluation/main.go
Normal file
@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type LazyMap func() map[string]string
|
||||
|
||||
func Make(ctr func() map[string]string) LazyMap {
|
||||
var initialized bool
|
||||
var data map[string]string
|
||||
return func() map[string]string {
|
||||
if !initialized {
|
||||
data = ctr()
|
||||
initialized = true
|
||||
ctr = nil // for GC
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := Make(func() map[string]string {
|
||||
return make(map[string]string)
|
||||
})
|
||||
|
||||
fmt.Println(data())
|
||||
data()["key"] = "value"
|
||||
fmt.Println(data())
|
||||
}
|
||||
29
lessons/functions/memoization/main.go
Normal file
29
lessons/functions/memoization/main.go
Normal file
@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
func Fibonacci(number int) int {
|
||||
if number <= 2 {
|
||||
return 1
|
||||
}
|
||||
|
||||
return Fibonacci(number-1) + Fibonacci(number-2)
|
||||
}
|
||||
|
||||
func FibonacciWithMemoization(number int) int {
|
||||
cache := make([]int, number+1)
|
||||
var impl func(number int) int
|
||||
impl = func(n int) int {
|
||||
if cache[n] != 0 {
|
||||
return cache[n]
|
||||
}
|
||||
|
||||
if number <= 2 {
|
||||
return 1
|
||||
} else {
|
||||
cache[n] = impl(n-1) + impl(n-2)
|
||||
}
|
||||
|
||||
return cache[n]
|
||||
}
|
||||
|
||||
return impl(number)
|
||||
}
|
||||
20
lessons/functions/named_return_values/main.go
Normal file
20
lessons/functions/named_return_values/main.go
Normal file
@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type mobileNavigator struct{}
|
||||
|
||||
func (n mobileNavigator) GetLocation(ctx context.Context, address string) (lat, lon float32, err error) {
|
||||
if address == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// calculating coordinates...
|
||||
return lat, lon, err
|
||||
}
|
||||
29
lessons/functions/predicate/main.go
Normal file
29
lessons/functions/predicate/main.go
Normal file
@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Less(lhs, rhs int) bool {
|
||||
return lhs < rhs
|
||||
}
|
||||
|
||||
func Greater(lhs, rhs int) bool {
|
||||
return lhs > rhs
|
||||
}
|
||||
|
||||
func Sort(numbers []int, predicate func(int, int) bool) {
|
||||
for i := 0; i < len(numbers); i++ {
|
||||
for j := i; j > 0 && predicate(numbers[j-1], numbers[j]); j-- {
|
||||
numbers[j-1], numbers[j] = numbers[j], numbers[j-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
numbers := []int{1, 2, 5, 4, 3}
|
||||
|
||||
Sort(numbers, Less)
|
||||
fmt.Println(numbers)
|
||||
|
||||
Sort(numbers, Greater)
|
||||
fmt.Println(numbers)
|
||||
}
|
||||
43
lessons/functions/pure_function/main.go
Normal file
43
lessons/functions/pure_function/main.go
Normal file
@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
)
|
||||
|
||||
var cache = map[int]struct{}{}
|
||||
|
||||
func dirtySum(x, y *int) int {
|
||||
result := *x + *y
|
||||
|
||||
// mutations of data (1)
|
||||
*x = 0
|
||||
*y = 0
|
||||
|
||||
// logging or files/network (2)
|
||||
fmt.Println(result)
|
||||
|
||||
// global variables (3)
|
||||
cache[result] = struct{}{}
|
||||
|
||||
// dependencies on parameters (4)
|
||||
os.Getenv("parameter")
|
||||
|
||||
// unpredictable result (5)
|
||||
result += rand.Intn(100)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func pureSum(x, y int) int {
|
||||
return x + y
|
||||
}
|
||||
|
||||
func main() {
|
||||
x := 13
|
||||
y := 12
|
||||
fmt.Println(dirtySum(&x, &y))
|
||||
|
||||
fmt.Println(pureSum(13, 12))
|
||||
}
|
||||
26
lessons/functions/random_generator/main.go
Normal file
26
lessons/functions/random_generator/main.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func produce(source int, permutation func(int) int) func() int {
|
||||
return func() int {
|
||||
source = permutation(source)
|
||||
return source
|
||||
}
|
||||
}
|
||||
|
||||
func mutate(number int) int {
|
||||
return (1664525*number + 1013904223) % 2147483647
|
||||
}
|
||||
|
||||
func main() {
|
||||
next := produce(1, mutate)
|
||||
|
||||
fmt.Println(next())
|
||||
fmt.Println(next())
|
||||
fmt.Println(next())
|
||||
fmt.Println(next())
|
||||
fmt.Println(next())
|
||||
}
|
||||
35
lessons/functions/recursion/recursion_test.go
Normal file
35
lessons/functions/recursion/recursion_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func SlowFactorial(number int) int {
|
||||
if number == 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
return number * SlowFactorial(number-1)
|
||||
}
|
||||
|
||||
func FastFactorial(number int) int {
|
||||
return factorial(number, 1)
|
||||
}
|
||||
|
||||
func factorial(number, accumulator int) int {
|
||||
if number == 1 {
|
||||
return accumulator
|
||||
}
|
||||
|
||||
return factorial(number-1, number*accumulator)
|
||||
}
|
||||
|
||||
func BenchmarkSlowRecursion(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = SlowFactorial(10)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFastRecursion(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = FastFactorial(10)
|
||||
}
|
||||
}
|
||||
20
lessons/functions/stack_overflow/main.go
Normal file
20
lessons/functions/stack_overflow/main.go
Normal file
@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func recursion() {
|
||||
var data = [10 * 1024 * 1024]int8{}
|
||||
_ = data
|
||||
|
||||
recursion()
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println("Recovered in main:", r)
|
||||
}
|
||||
}()
|
||||
|
||||
recursion()
|
||||
}
|
||||
12
lessons/functions/variadic_parameters/main.go
Normal file
12
lessons/functions/variadic_parameters/main.go
Normal file
@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func process(values ...*int) {
|
||||
fmt.Println(len(values))
|
||||
}
|
||||
|
||||
func main() {
|
||||
process(nil)
|
||||
process(nil...)
|
||||
}
|
||||
Reference in New Issue
Block a user