치춘짱베리굿나이스

[Go] 03 더 많은 타입들 본문

기타공부/Go를 향한 여행

[Go] 03 더 많은 타입들

치춘 2021. 9. 23. 19:31

Pointers

package main

import "fmt"

func main() {
	i, j := 42, 2701

	p := &i         // point to i
	fmt.Println(*p) // read i through the pointer
	*p = 21         // set i through the pointer
	fmt.Println(i)  // see the new value of i

	p = &j         // point to j
	*p = *p / 37   // divide j through the pointer
	fmt.Println(j) // see the new value of j
}

  • 포인터 선언은 int *ptr; 이런 식으로 선언하지 않는다는 점을 제외하고 c와 비슷하다

package main

import "fmt"

type Vertex struct {
	X int
	Y int
}

func main() {
	fmt.Println(Vertex{1, 2})
}

  • 구조체 선언도 typedef struct <구조체명> 이 아닌 type <구조체명> struct라는 점을 제외하면 c와 비슷하다

package main

import "fmt"

type Vertex struct {
	X int
	Y int
}

func main() {
	v := Vertex{1, 2}
	v.X = 4
	fmt.Println(v.X)
}

  • 구조체 내부 변수는 .을 통해 접근할 수 있다 (C와 똑같다.. 어려울 게 없다 와~~~~)

package main

import "fmt"

type Vertex struct {
	X int
	Y int
}

func main() {
	v := Vertex{1, 2}
	p := &v
	p.X = 1e9
	fmt.Println(v)
}

  • 구조체를 포인터를 통해 접근할 때는 C처럼 화살표를 쓰는 것이 아닌 일반 변수 접근하듯 .으로 접근해도 된다
    • 위의 예시에서 p.X나 v.X나 똑같은 값을 접근하게 된다

package main

import "fmt"

type Vertex struct {
	X, Y int
}

var (
	v1 = Vertex{1, 2}  // has type Vertex
	v2 = Vertex{X: 1}  // Y:0 is implicit
	v3 = Vertex{}      // X:0 and Y:0
	p  = &Vertex{1, 2} // has type *Vertex
)

func main() {
	fmt.Println(v1, p, v2, v3)
}

  • v1은 구조체 {1, 2} 를 가지고 있다
  • p는 구조체 {1, 2} 의 포인터를 가지고 있기 때문에 &로 출력된다
  • v2는 x만 1로 설정된 구조체 ({1, 0}) 를 가지고 있다 (y는 묵시적으로 0으로 지정된다)
  • v3은 x, y 둘 다 값을 설정해 주지 않았으므로, 묵시적으로 (자동으로) 0이 들어간다

package main

import "fmt"

func main() {
	var a [2]string
	a[0] = "Hello"
	a[1] = "World"
	fmt.Println(a[0], a[1])
	fmt.Println(a)

	primes := [6]int{2, 3, 5, 7, 11, 13}
	fmt.Println(primes)
}

  • 배열은 c와 다르게 배열의 크기가 자료형의 앞에 온다 ([2]string 이런 식)
    • c랑 차별점을 주려고 일부러 그런 걸까..............
  • 나머지 사용법은 c랑 상당히 비슷하고, 자료형 뒤에 중괄호 ({}) 를 이용해서 값을 바로 초기화해 줄 수도 있다

package main

import "fmt"

func main() {
	primes := [6]int{2, 3, 5, 7, 11, 13}

	var s []int = primes[1:4]
	fmt.Println(s)
}

  • 파이썬 리스트 자르듯 슬라이스를 이용해서 배열의 원하는 부분만 잘라올 수 있다
    • primes[1:4] 는 1번째 원소부터 4번째 원소 전까지 자른다 (커서가 숫자의 왼쪽에 간다고 생각하면 된다)
    • 따라서 출력값이 인덱스 1, 2, 3번이므로 [3, 5, 7] 이 출력된다

package main

import "fmt"

func main() {
	names := [4]string{
		"John",
		"Paul",
		"George",
		"Ringo",
	}
	fmt.Println(names)

	a := names[0:2]
	b := names[1:3]
	fmt.Println(a, b)

	b[0] = "XXX"
	fmt.Println(a, b)
	fmt.Println(names)
}

  • a := names[0:2] -> [John, Paul]
  • b := names[1:3] -> [Paul, George]
    • 따라서 b[0] 은 Paul이 되고, b[0] = "XXX" 로 교체하면 Paul은 XXX가 되므로 names의 원소 Paul이 XXX로 바뀐다

package main

import "fmt"

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},
		{7, true},
		{11, false},
		{13, true},
	}
	fmt.Println(s)
}

  • 길이 지정을 굳이 안 해줘도 리스트와 비슷한 것을 만들 수 있다
    • 배열 리터럴은 [숫자]자료형{값1, 값2, 값3} 이런식
    • 슬라이스 리터럴은 []자료형{값1, 값2, 값3, ...} 이런식

package main

import "fmt"

func main() {
	s := []int{2, 3, 5, 7, 11, 13}

	s = s[1:4]
	fmt.Println(s)

	s = s[:2]
	fmt.Println(s)

	s = s[1:]
	fmt.Println(s)
}

  • 슬라이스 시의 상/하한값 (양 끝값) 은 명시하지 않으면 기본 값이 들어간다
    • 상한값 (더 큰 수) 기본값은 배열의 총 길이
    • 하한값 (더 작은 수) 기본값은 0

package main

import "fmt"

func main() {
	s := []int{2, 3, 5, 7, 11, 13}
	printSlice(s)

	// Slice the slice to give it zero length.
	s = s[:0]
	printSlice(s)

	// Extend its length.
	s = s[:4]
	printSlice(s)

	// Drop its first two values.
	s = s[2:]
	printSlice(s)
}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

  • 슬라이스의 길이와 용량도 얻을 수 있다
    • 길이는 len(슬라이스이름)
    • 용량은 cap(슬라이스이름)
  • 슬라이스의 길이는 슬라이스 내에 포함된 요소의 개수
  • 슬라이스의 용량은 슬라이스의 첫 번째 요소부터 기본 배열 요소의 개수
  • 슬라이스 길이는 슬라이스 용량이 충분할 때 재 슬라이스를 통해 연장할 수 있다

package main

import "fmt"

func main() {
	var s []int
	fmt.Println(s, len(s), cap(s))
	if s == nil {
		fmt.Println("nil!")
	}
}

  • 슬라이스의 길이가 0이라면 기본값으로 nil이 들어간다

package main

import "fmt"

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

  • 내장된 make 함수를 이용해서 슬라이스를 생성할 수도 있다
    • 디폴트 값인 0으로 초기화된 배열을 생성한다
  • 매개변수로 세번째 인자에 용량을 설정할 수도 있다 (두번째 인자는 길이)
    • 세번째 인자를 지정하지 않으면 용량은 길이와 같은 값이 들어간다

 

'기타공부 > Go를 향한 여행' 카테고리의 다른 글

[Go] 02 흐름제어 구문  (0) 2021.09.19
[Go] 01 패키지와 변수 함수  (2) 2021.09.19
[Go] 00 환영합니다  (3) 2021.09.18
Comments