go-learning/2moretypes/slices.go

181 lines
5.5 KiB
Go
Raw Permalink Normal View History

2023-07-12 15:34:30 +03:00
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)
}