Go에서 struct는 Custom Data Type을 표현하는데 사용되는데, Go의 struct는 필드들의 집합체이며 필드들의 컨테이너이다. Go에서 struct는 필드 데이타만을 가지며, (행위를 표현하는) 메서드를 갖지 않는다.
type Data struct { A int8 // 1Byte B int8 // 1Byte C int // 8Byte } func main() { var d Data fmt.Println(unsafe.Sizeof(d)) } // 시스템의 아키텍쳐가 32Bit라는 가정하에 Data 의 크기는 16Byte 이다.
type Data struct { A int8 C int B int8 } func main() { var d Data fmt.Println(unsafe.Sizeof(d)) } // 위와 동일한 내용이지만 Data의 크기는 24Byte 이다. // 위의 크기와 다른 이유는 각각 A=1,B=1,C=8 크기를 가지고 있는대 // 위의 예시는 첫 8Byte 안에 A,B가 모두 들어가서 1개의 8Byte만 차지하지만 // 밑의 예시는 A와 B가 각각 떨어져 8Byte씩 용령을 차지하고 C 까지 더해져 24Byte가 된다
참조 : struct Padding
https://bumukisbest.tistory.com/18
https://wnsgml972.github.io/c/2019/11/21/c_struct_padding/
type Vertex struct { X int Y int } func main() { v := Vertex{1, 2} fmt.Println(v.X) // 1 v.X = 4 fmt.Println(v.X) // 4 }
func main() { v := Vertex{1, 2} p := &v fmt.Println(p) // &{1 2} p.X = 1e9 fmt.Println(v) // {1000000000 2} }
var ( V1 = Vertex{1, 2} // has type Vertex {1 2} V2 = Vertex{X: 1} // Y:0 is implicit &{1 2} V3 = Vertex{} // X:0 and Y:0 {1 0} p = &Vertex{1, 2} // has type *Vertex {0 0} ) func main() { fmt.Println(V1, p, V2, V3) }
func main() { primes := [6]int8{2, 3, 5, 7, 11, 13} fmt.Println(primes) // [2 3 5 7 11 13] fmt.Println("\n", &primes) // &[2 3 5 7 11 13] fmt.Println("\n", &primes[0]) // 0xc000014088 fmt.Println("\n", &primes[1]) // 0xc000014089 fmt.Println("\n", &primes[2]) // 0xc00001408a fmt.Println("\n", &primes[3]) // 0xc00001408b fmt.Println("\n", &primes[4]) // 0xc00001408c fmt.Println("\n", &primes[5]) // 0xc00001408d }
func main() { primes := [6]int8{2, 3, 5, 7, 11, 13} fmt.Println(primes) pp := uintptr(unsafe.Sizeof(&primes)) for i := uintptr(0); i < 6; i++ { fmt.Println(*(*int8)(unsafe.Pointer(pp + i))) } } // [2 3 5 7 11 13] // 2 // 3 // 5 // 7 // 11 // 13
func main() { primes := [4]int8{2, 3, 5, 7} a := primes[0:2] b := primes[1:3] fmt.Println(a, b) b[0] = 11 fmt.Println(a, b) fmt.Println(primes) fmt.Println(&primes[0] == &a[0]) fmt.Println(&primes[1] == &a[1]) fmt.Println(&primes[1] == &a[0]) fmt.Println(&primes[2] == &a[1]) } // [2 3] [3 5] // [2 11] [11 5] // [2 11 5 7] // true // true // false // false
func main() { q := []int{2, 3, 5, 7, 11, 13} fmt.Println(q) r := []bool{true, false, true, true, false, true} fmt.Println(r) s := []struct { i int b bool }{ {2, true}, {3, false}, {5, true}, {i: 7}, {11, false}, {}, } fmt.Println(s) } // [2 3 5 7 11 13] // [true false true true false true] // [{2 true} {3 false} {5 true} {7 false} {11 false} {0 false}]
func main() { s := []int{2, 3, 5, 7, 11, 13} fmt.Println(s) // len=6 cap=6 [2 3 5 7 11 13] // Slice the slice to give it zero length s = s[:0] printSlice(s) // len=0 cap=6 [] // Extend its length s = s[:4] printSlice(s) // len=4 cap=6 [2 3 5 7] // Drop its first two values s = s[2:] printSlice(s) // len=2 cap=4 [5 7] } func printSlice(s []int) { fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) }
참조 : slice 사용법 및 구조 https://go.dev/blog/slices-intro
func main() { var s []int fmt.Println(s, len(s), cap(s)) // [] 0 0 if s == nil { fmt.Println("nil") // nil } }
func main() { a := make([]int, 5) printSlice("a", a) b := make([]int, 0, 5) printSlice("b", b) c := b[:2] printSlice("c", c) d := c[2:5] printSlice("d", d) } func printSlice(s string, x []int) { fmt.Printf("%s len=%d cap=%d %v\n", s, len(x), cap(x), x) } // a len=5 cap=5 [0 0 0 0 0] // b len=0 cap=5 [] // c len=2 cap=5 [0 0] // d len=3 cap=3 [0 0 0]
func main() { var s []int printSlice(s) // append works on nil slices s = append(s, 0) printSlice(s) // The slices grows as needed s = append(s, 1) printSlice(s) // We can add more than one element at a time. s = append(s, 2, 3, 4) printSlice(s) } // ptr=0x0 &[0]=0x0 len=0 cap=0 [] // ptr=0xc00009a018 &[0]=0xc00009a018 len=1 cap=1 [0] // ptr=0xc00009a050 &[0]=0xc00009a050 len=2 cap=2 [0 1] // ptr=0xc000096060 &[0]=0xc000096060 len=5 cap=6 [0 1 2 3 4]
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} func main() { for i := 0; i < len(pow); i++ { fmt.Printf("2**%d = %d\n", i, pow[i]) } }
============================================================
>var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
>
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}
>
// 2**0 = 1
// 2**1 = 2
// 2**2 = 4
// 2**3 = 8
// 2**4 = 16
// 2**5 = 32
// 2**6 = 64
// 2**7 = 128
// 주의 func main() { var s = []int{1} fmt.Printf("%p / %v\n", s, s) foo(s) fmt.Printf("%p / %v\n", s, s) } func foo(sli []int) { fmt.Printf("foo : %p / %v\n", sli, sli) sli = append(sli, 1) fmt.Printf("foo : %p / %v\n", sli, sli) } // 0xc00009a010 / [1] // foo : 0xc00009a010 / [1] // foo : 0xc00009a040 / [1 1] // 0xc00009a010 / [1]
// 해결방법 -1 func main() { var s = []int{1} fmt.Printf("%p / %v\n", s, s) foo(&s) fmt.Printf("%p / %v\n", s, s) } func foo(sli *[]int) { fmt.Printf("foo : %p / %v\n", sli, sli) *sli = append(*sli, 1) fmt.Printf("foo : %p / %v\n", sli, sli) } =============================================================================== // 해결방법 -2 func main() { var s = []int{1} fmt.Printf("%p / %v\n", s, s) foo(s) fmt.Printf("%p / %v\n", s, s) } func foo(sli []int) []int { fmt.Printf("foo : %p / %v\n", sli, sli) sli = append(sli, 1) fmt.Printf("foo : %p / %v\n", sli, sli) return sli }
func main() { rand.Seed(time.Now().UnixNano()) for { fmt.Println(time.Now()) time.Sleep(time.Millisecond * 100) if rand.Int()%3 == 0 { break } } } // 2022-05-17 01:04:03.3051727 +0900 KST m=+0.000105401 // 2022-05-17 01:04:03.405766 +0900 KST m=+0.100698801 // 2022-05-17 01:04:03.5060199 +0900 KST m=+0.200952701 // 2022-05-17 01:04:03.6062666 +0900 KST m=+0.301199301
func main() { rand.Seed(time.Now().UnixNano()) LOOP: for { for i := 0; i < 10; i++ { fmt.Println(i) if rand.Int()%3 == 0 { break LOOP } fmt.Println("inner loop!") } fmt.Println("loop!") } } // 0 // inner loop! // 1 // inner loop! // 2 // inner loop! // 3 // inner loop! // 4 // inner loop! // 5 `Loop?` 위의 Loop 라벨이라 칭하며 다른 언어들의 GOTO와 같다
func main() { rand.Seed(time.Now().UnixNano()) for i := 0; i < 10 ; i ++ { if i%2 == 0 { continue } fmt.Println(i) } } // 1 // 3 // 5 // 7 // 9
func main() { rand.Seed(time.Now().UnixNano()) LOOP: for { fmt.Println("start loop") time.Sleep(time.Millisecond * 10) for i := 0; i < 10; i++ { fmt.Println(i) if rand.Int()%3 == 0 { continue LOOP } fmt.Println("inner loop!") } fmt.Println("loop!") } } // inner loop! // 3 // inner loop! // 4 // start loop // 0 // inner loop! // 1 // inner loop! // 2 // inner loop! // 3
func main() { rand.Seed(time.Now().UnixNano()) switch n := rand.Int(); n % 2 { case 0: fmt.Println(n, "짝수") fallthrough case 1: fmt.Println(n, "홀수") default: fmt.Println("이것은 숫자여!") } } // 8766305652735485300 짝수 // 8766305652735485300 홀수
func main() { rand.Seed(time.Now().UnixNano()) RESET: fmt.Println("와 시작!") for i := 0; i < 2; i++ { if rand.Int()%3 == 0 { fmt.Println("당신은 운이 없군요!") goto RESET } if rand.Int()%4 == 0 { fmt.Println("바로통과 !!") goto PASS } } fmt.Println(" 축하한다! 시련을 통과했다!") return PASS: fmt.Println("바로 통과해버리다니!!") } // 와 시작! // 바로통과 !! // 바로 통화개버리다니!!