#TIL GO 3회차

송정석·2022년 5월 15일
0
post-thumbnail

struct란?

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

ARRAY

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

Slice

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
}

for-break

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와 같다

for-continue

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

switch-fallthrought

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 홀수

goto

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("바로 통과해버리다니!!")
}
// 와 시작!
// 바로통과 !!
// 바로 통화개버리다니!!
profile
Foot print

0개의 댓글