diff --git a/2moretypes/slices.go b/2moretypes/slices.go new file mode 100644 index 0000000..e0d7070 --- /dev/null +++ b/2moretypes/slices.go @@ -0,0 +1,180 @@ +package main + +import ( + "fmt" + "reflect" + "strings" +) + +func main() { + fmt.Println("Slices are dynamically-sized, flexible view into the elements of an arrary") + fmt.Println("Generally more common than arrays") + fmt.Println("Just dont use size in square brackets, thats the difference .d") + + fmt.Println("You can slice arrays like this:") + + primes := [6]int{2, 3, 5, 7, 11, 13} + var s []int = primes[1:4] // from index 1 to 4 (exclude 4) (1-2-3) + fmt.Println(s) + + // s[10] = 1 // runtime ERROR (panic: runtime error: index out of range [10] with length 3) + + fmt.Println("Changing the slice of an array also changes array index, see below:") + s[2] = 10 + fmt.Println(s) + fmt.Println(primes) + + fmt.Println("This because slices are like references to arrays") + fmt.Println("Also same thing with multiple slices:") + + names := [5]string{"Gary", "Earl", "Billy", "Felix", "Mary"} + fmt.Println(names) + + a := names[0:3] + b := names[1:5] + c := names[2:5] + d := names[3:5] + e := names[4:5] + + fmt.Println(a, b) + + b[1] = "DELETED" + + fmt.Println(a, b) + fmt.Println(names) + + fmt.Printf("\nN: %p: %p, %p, %p, %p, %p\n", &names, &names[0], &names[1], &names[2], &names[3], &names[4]) + fmt.Printf("A: %p: %p, %p, %p, %p\n", &a, a, &a[0], &a[1], &a[2]) + fmt.Printf("B: %p: %p, %p, %p, %p, %p\n", &b, b, &b[0], &b[1], &b[2], &b[3]) + fmt.Printf("C: %p: %p, %p, %p, %p\n", &c, c, &c[0], &c[1], &c[2]) + fmt.Printf("D: %p: %p, %p, %p\n", &d, d, &d[0], &d[1]) + fmt.Printf("E: %p: %p, %p\n", &e, e, &e[0]) + + // TODO names içindeki stringler nerede depolanıyor, stringleri ne kadar uzatsam da sadece 10 bit yer kaplıyor. Bu nasıl oluyor. + + fmt.Printf("\n\n") + fmt.Println("Slice literals are like array literals without the length") + + arr := [3]bool{true, false, false} // THIS CREATES ARRAY + sli := []bool{true, false, false} + fmt.Println("This creates the same array as above, then builds a slice that references it") + + fmt.Printf("%T: %v\n", arr, arr) + fmt.Printf("%T: %v\n", sli, sli) + + fmt.Printf("%p, %p, %p, %p, %p\n", &arr, arr, &arr[0], &arr[1], &arr[2]) + fmt.Printf("%p, %p, %p, %p, %p\n", &sli, sli, &sli[0], &sli[1], &sli[2]) + fmt.Printf("%s, %s\n", reflect.TypeOf(&sli), reflect.TypeOf(&arr)) + + // TODO slice başka bir yerde tanımlanan bir pointer aslında, ve herhangi bir yerde (bir değişkene atılmamış) depolanan array'i işaret ediyor, doğru muyum? Yani ben sli[2] dediğim zaman, sli->gösterdiği yer(gerçek array'in başı)->+2 yapıp arraydeki yeri mi gösteriyor? Ya da tam tersi her index için ayrı bir pointer mı tutuluyor (sanmıyorum) + + fmt.Printf("\n\n") + fmt.Println("You can also use slices with struct:") + + myvar := []struct { + i int + b string + }{ + {2, "apple"}, + {5, "strawberry"}, + {3, "watermelon"}, + } + + fmt.Println(myvar, myvar[0], myvar[0].i) + fmt.Printf("%p, %p\n", myvar, &myvar) + fmt.Printf("%p, %p, %p\n", &myvar[0], &myvar[0].i, &myvar[0].b) + fmt.Printf("%p, %p, %p\n", &myvar[1], &myvar[1].i, &myvar[1].b) // TODO 2 fark neden var !!!?? + fmt.Printf("%p, %p, %p\n", &myvar[2], &myvar[2].i, &myvar[2].b) + + fmt.Printf("\n\n") + fmt.Println("The default is zero for the low bound and the length of the slice for the high bound") + + myvar2 := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + fmt.Println("These are same:") + fmt.Println(myvar2[0:10]) + fmt.Println(myvar2[:10]) + fmt.Println(myvar2[0:]) + fmt.Println(myvar2[:]) + + fmt.Printf("\n\n") + fmt.Println("Slice has both len (Length) and cap (Capacity)") + fmt.Println("Capacity is the number of elements in the underlying array, counting from the first element in the slice") + + // 0 1 2 3 4 5 6 + myslice1 := []int{1, 2, 3, 4, 5, 6, 7} + printSlice(myslice1) + // 0 1 2 3 4 + myslice1 = myslice1[2:4] // [3 4 -5- -6- -7-] + printSlice(myslice1) + + myslice1 = myslice1[:5] + printSlice(myslice1) + + fmt.Printf("\n\n") + fmt.Println("The zero value for a slice is `nil`") + var myslice2 []int + printSlice(myslice2) + if myslice2 == nil { + fmt.Println("Slice is nil!") + } + + fmt.Printf("\n\n") + fmt.Println("Slices can be created with built-in `make` function") + fmt.Println("`make` allocates zeroed array and returns a slice that refers to that array") + + // make(TYPE, LEN, CAP) + + myslice3 := make([]int, 5) + printSlice(myslice3) + + myslice4 := make([]int, 5, 10) + printSlice(myslice4) + + fmt.Printf("\n\n") + fmt.Println("Slices can contain any type, including other slices") + board := [][]string{ + []string{"_", "_", "_"}, + []string{"_", "_", "_"}, + []string{"_", "_", "_"}, + } + + printSlice2(board) + + board[2][0] = "X" + board[0][2] = "X" + board[1][1] = "O" + + for i := 0; i < len(board); i++ { + fmt.Printf("%s\n", strings.Join(board[i], " ")) + } + + fmt.Printf("\n\n") + fmt.Println("Go also provides built-in append function") + + var myslice5 []int + printSlice(myslice5) + + fmt.Printf("%p, %p\n", myslice5, &myslice5) + + myslice5 = append(myslice5, 1, 2, 3) + printSlice(myslice5) + fmt.Printf("%p, %p\n", myslice5, &myslice5) + + myslice5 = myslice5[:1] // + // TODO Bunu yorum satırına alınca ilk pointer değeri değişiyor. Açınca ise değişmiyor. Büyük ihtimal farklı bir yere işaretçi tanımlıyor ama bu işaretçi neyin. Array'in mi Slice'ın mı??? + + myslice5 = append(myslice5, 4) + printSlice(myslice5) + fmt.Printf("%p, %p\n", myslice5, &myslice5) + + fmt.Printf("\n%v, %v\n", reflect.ValueOf(myslice5).Kind(), reflect.ValueOf(&myslice5).Kind()) + fmt.Printf("%v, %v\n", reflect.ValueOf(myslice5[1]).Kind(), reflect.ValueOf(&myslice5[1]).Kind()) +} + +func printSlice(s []int) { + fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) +} + +func printSlice2(s [][]string) { + fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) +}