go-learning/2moretypes/slices.go

180 lines
5.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}