균형잡힌_세상_4949번

[Python, Go] 백준 4949번 풀이

균형잡힌 세상

  • 괄호문제 의 연장이다.

  • 소괄호뿐만 아니라 대괄호까지 포함해 문장에서 괄호가 올바르게 되어져있는지 확인해야한다.

  • 괄호안에 있는 괄호의 짝도 맞아야 yes를 출력할 수 있다. 예를들어 ( [ ) ] 와 같은 경우 하나의 괄호 안에 올바른 짝의 괄호가 들어가지 못했으므로 no 를 출력해야 한다.

  • 정규표현식을 사용해 따라가야될 괄호들을 뺀 문자들은 pass 시켜주는 방법을 사용했다.

  • 이외에는 괄호문제와같이 스텍에 ( 와 [ 를 담아서 사용했다.

    • 단 ) 와 ] 를 만났을 때, 스텍의 마지막 요소가 짝이되는 괄호인지를 판별해줘야 한다.
  • Python 풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def vps(line):
stack = []
if line[0] == ")" or line[0] == "]":
# print("1")
return "no"
else: pass
for s in line:
if bool(com.match(s)) == True:
pass
elif s == " " or s == ".":
pass
elif s == "(" or s == "[":
stack.append(s)
# print(stack)
elif s == ")" and stack != []:
if stack[-1] == "(":
stack.pop()
else:
# print("2")
return "no"
elif s == "]" and stack != []:
if stack[-1] == "[":
stack.pop()
else:
# print("3")
return "no"
else:
# print("4")
return "no"
if stack == []:
return "yes"
else:
# print("5")
return "no"
  • Go 풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
func vps(x string) string {
var stack []string

// fmt.Println(string(x[0]))
// return x
if string(x[0]) == ")" || string(x[0]) == "]" {
return "no"
}
for _, ch := range x {
s := string(ch)
match, _ := regexp.MatchString("[a-zA-Z]", s)
if match == true {
} else if s == " " || s == "." {
} else if s == "(" || s == "[" {
stack = append(stack, s)
} else if s == ")" && stack != nil {
if stack[len(stack)-1] == "(" {
if len(stack) == 1 {
stack = nil
} else {
stack = stack[:len(stack)-1]
}
} else {
return "no"
}
} else if s == "]" && stack != nil {
if stack[len(stack)-1] == "[" {
if len(stack) == 1 {
stack = nil
} else {
stack = stack[:len(stack)-1]
}
} else {
return "no"
}
} else {
return "no"
}
}
if stack == nil {
return "yes"
} else {
return "no"
}
}
  • Go로 풀이할때, 조건이 많을때는 switch가 더 좋기때문에 switch를 사용했다면 더 좋았을것같다.

Full Code

Full Code - Python

Full Code - Go

괄호_9012번

[Python, Go] 백준 9012번 풀이

괄호

  • 괄호의 쌍이 맞게 이루어져있는지 찾아내는 문제이다.

  • “(“괄호와 “)” 괄호의 개수를 세는것에서 끝나면 안된다.

  • 스택에 “(“ 가 들어왔을때 저장하고 “)” 와 만나면 스택에서 하나를 제거하는 방법으로 쌍을 맞춰주었다.

  • 가장 먼저 들어오는 문자열이 “)” 이라면 쌍이 맞을 수 없으므로 NO 를 리턴하며, 문자열 모두를 파악한 후 stack이 비어있다면 YES 그렇지 않다면 NO 이다

  • Python 풀이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import sys

n = int(sys.stdin.readline())


def vps(li):
stack = []

if li[0] == ")":
return "NO"
else:
for s in li:
if s == "(":
stack.append(s)
elif s == ")" and stack != []:
stack.pop()
else:
return "NO"

if stack == []:
return "YES"
else: return "NO"

for i in range(n):
order = list(sys.stdin.readline().rstrip())
print(vps(order))
  • Go 풀이

    • Go 를 사용할때는 파이썬의 pop과같은 내장함수가 없으므로 “)”를 만났을때 슬라이스의 길이가 1인 경우와 그렇지 않은 경우를 나눠서 판단했다.
func vps(x string) string {
    var stack []string

    for idx, ch := range x {
        s := string(ch)
        if idx == 0 && s == ")" {
            return "NO"
        } else {
            if s == "(" {
                stack = append(stack, s)
            } else if s == ")" && stack != nil {
                length := len(stack)
                if length == 1 {
                    stack = nil
                } else {
                    stack = stack[:length-1]
                }
            } else {
                return "NO"
            }
        }
    }
    if stack == nil {
        return "YES"
    } else {
        return "NO"
    }
}

Full Code

Full Code - Python

Full Code - Go

영화감독_숌_1436번

[Python, Go] 백준 1436번 풀이

영화감독 숌

  • 숫자 6이 연속해서 3번 나타나는 수를 구하는 문제이다.

  • 666, 1666, … , 5666, 의 다음은 6660, 6661, … 이다

  • 666 부터 시작해서 수를 1씩 늘려가면서 모두 확인한다.

  • 해당 수를 string으로 바꾸고 for문을 통해 6이 나왔을때 그 다음의 수도 6인지 그리고 그 다음 숫자도 6인지 확인하는 check 변수를 사용했다.

  • 만약 check가 3이되면 해당 숫자는 6이 연속해서 3번 들어갔으므로 count를 1 증가시키고 주어진 목표만큼 count가 증가하면 종료, 출력했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
n = int(input())

name = 666
count = 0

while True:
if count == n:
print(name-1)
break
else:
check = 0
for i in str(name):
if i == "6":
check += 1
if check == 3:
count += 1
continue
else: pass
else:
check = 0
name += 1
  • Go도 같은 방식의 풀이지만, string을 for문에 돌릴때 반환되는 값은 포인터 값이므로 string(x) 로 바꿔주는것만 주의 참조

  • string을 int로 바꿀때 strconv.ParseInt 를 사용했으나 strconv.Atoi를 사용해도됨

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import (
"fmt"
"strconv"
)

func main() {
var n int
count := 0
name := 666
fmt.Scanf("%d", &n)

for {
if count == n {
fmt.Printf("%d", name-1)
break
} else {
check := 0
for _, k := range strconv.Itoa(name) {
v, _ := strconv.ParseInt(string(k), 10, 8)
if v == 6 {
check += 1
switch check {
case 3:
count += 1
}
} else {
check = 0
}
}
}
name += 1
}
}
  • check 값이 3인지 확인할때 if문을 사용해도 괜찮지만 switch문을 사용해보았다.

Full Code

Full Code - Python

Full Code - Go

for문에서_string_사용하기

[Go] string(문자열)을 for문으로 출력, 이용하기

  • Go로 문제를 풀 때, 문자열을 for문으로 돌려야 하는 경우가 자주 발생했다.

  • 파이썬같은 경우, 문자열을 다음과 같이 입력하면 문자열 그대로 출력된다.

1
2
for i in "CAT":
print(i) #print : C A T
  • Go도 문자열을 for문에 사용할 수는 있지만, 파이썬과 달리 Go는 인덱스와 포인터 값을 반환한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"

func main() {
str := "CAT"
for _, r := range str {
c := string(r)
fmt.Println(c)
}
fmt.Println()
for i, r := range str {
fmt.Println(i, r, string(r))
}
}
  • 위의 코드를 실행시켜보면, 다음과 같이 출력된다.
    C
    A
    T

0 67 C
1 65 A
2 84 T

  • 위와같이, Go에서는 for문에서 문자열이 아닌 포인터값(int)을 반환한다.

  • 따라서 문자열을 이용하고 싶을 경우, 새로운 변수를 만들고 이에 string()함수를 통해 초기화 시켜주어야 한다.

    • 위의 예처럼, 반환받은 r값을 새로운 변수 c := string(r) 로 초기화 시켜서 사용.

스택_10828번

[Python, Go] 백준 10828번 풀이

스택

  • 주어지는 명령에 따라 스택을 처리하는 문제이다. 파이썬은 큐나 스택을 지원하는 라이브러리가 있지만 사용하지 않고 리스트를 통해 구현했으며, Go는 슬라이스를 통해 구현했다.
  • 스택을 초기화할 필요가 있는 문제가 아니었으므로 하나의 파이썬의 경우 하나의 for문안에서 처리하고 Go는 각각의 명령에 따른 함수를 만들어 사용했다.

  • Python 풀이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import sys

n = int(sys.stdin.readline())

stack = []

# n = int(input())

for i in range(n):

order = sys.stdin.readline().rstrip()
# print(order)
if len(order.split()) == 2:
stack.insert(0,int(order.split()[1]))

else:
if order == "pop":
if stack == []:
print(-1)
else:
print(stack[0])
stack.pop(0)
elif order == "size":
print(len(stack))
elif order == "empty":
if stack == []:
print(1)
else:
print(0)
# top
else:
if not stack == []:
print(stack[0])
else:
print(-1)
  • Go를 통해 슬라이스를 다룰때 파이썬의 pop과 같은 내장함수가 없다.

    • 따라서, 슬라이스에서 하나를 제거할 때 슬라이스의 길이가 1인경우와 1이 아닌경우를 나눠서 생각했다.

    • 슬라이스의 길이가 1인경우, 남아있는 하나를 제거하고 empty slice를 만들기 위해 nil 처리

    • 슬라이스의 길이가 1이 아닌 경우, 슬라이스의 가장 끝의 하나를 제거하면 되므로 슬라이스의 길이 L 을 구하고 L-1 까지의 슬라이스만을 가져간다.

  • Go 풀이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package main

import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)

var s []int

func s_push(x int) {
s = append(s, x)
}

func s_pop() {

if s == nil {
fmt.Printf("%d\n", -1)
} else if len(s) == 1 {
top := s[0]
fmt.Printf("%d\n", top)
s = nil
} else {
l := len(s)
top := s[l-1]
fmt.Printf("%d\n", top)
s = s[:l-1]
}
}

func s_size() {
l := len(s)
fmt.Printf("%d\n", l)
}

func s_empty() {
if s == nil {
fmt.Printf("%d\n", 1)
} else {
fmt.Printf("%d\n", 0)
}
}

func s_top() {
if s == nil {
fmt.Printf("%d\n", -1)
} else {
l := len(s)
top := s[l-1]
fmt.Printf("%d\n", top)
}
}

func main() {
var n int
inputReader := bufio.NewReader(os.Stdin)
fmt.Scanf("%d", &n)

for i := 0; i < n+1; i++ {
input, _ := inputReader.ReadString('\n')

order := strings.Split(input, " ")

action := strings.TrimSpace(order[0])

if len(order) == 2 {
n := strings.TrimSpace(order[1])
num, _ := strconv.Atoi(n)
s_push(num)
} else {
switch action {
case "pop":
s_pop()
case "size":
s_size()
case "empty":
s_empty()
case "top":
s_top()
}
}
}
}

Full Code

Full Code - Python

Full Code - Go

Golang_정리하기_4

[Go tutorial] Go 정리하기 - 4

Go-tour 참조

구름edu 참조

  • 스위치 (switch)

    • case의 라벨과 일치하는경우를 찾아 실행

    • 어느것에도 맞지않다면 default문으로 실행 가능

    • break를 따로 입력하지 않아도 해당되는 case문만 실행된다.

    • 스위치의 각 조건은 위에서 아래로 평가한다. 참인 case를 찾으면 평가를 마침.

    • switch 전달 인자

      • 태그

      • 표현식

      • 전달되는 인자 없이 case에 표현식 사용 가능

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        func main() {
        var a, b int

        fmt.Print("정수 a와 b를 입력하시오:")
        fmt.Scanln(&a, &b)

        switch {
        case a > b:
        fmt.Println("a가 b보다 큽니다.")
        case a < b:
        fmt.Println("a가 b보다 작습니다.")
        case a == b:
        fmt.Println("a와 b가 같습니다.")
        default:
        fmt.Println("모르겠어요.")
        }
        }
  • 메소드와 인터페이스

    • 메소드란 특정 속성들(구조체)을 이용해 기능을 수행하기 위해 만들어진 함수이다.

    • 선언

      • “func (매개변수이름 구조체이름) 메소드이름() 반환형 {}” 형식으로 선언
    • 매개변수 이름은 메소드 내에서 매개변수처럼 사용

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      type Vertex struct {
      X, Y float64
      }

      func (v *Vertex) Abs() float64 {
      return math.Sqrt(v.X*v.X + v.Y*v.Y)
      }

      func main() {
      v := &Vertex{3, 4}
      fmt.Println(v.Abs()) ### print : 5
      }
    • 위의 예에서는 메소드에 구조체를 붙였다.

    • 뿐만 아니라 메소드에는 아무 타입이나 붙일 수 있다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      type MyFloats float64

      func (f MyFloats) Abs() float64 {
      if f < 0 {
      return float64(-f)
      }
      return float64(f)
      }

      func main() {
      k := MyFloats(-math.Sqrt2)
      fmt.Println(k.Abs()) ### print : 1.4142135623730951
      }
    • 위의 예에서는 float타입을 메소드에 붙였다.

  • 인터페이스

    • 구조체가 변수를 묶어놓은 것이라면, 인터페이스는 메소드를 모아놓은 것이다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      package main

      import (
      "fmt"
      "math"
      )

      type geometry interface {
      area() float64
      perimeter() float64
      }

      type Rect struct {
      width, height float64
      }

      type Circle struct {
      radius float64
      }

      func (r Rect) area() float64 {
      return r.width * r.height
      }

      func (c Circle) area() float64 {
      return math.Pi * c.radius * c.radius
      }

      func (r Rect) perimeter() float64 {
      return 2 * (r.width + r.height)
      }

      func (c Circle) perimeter() float64 { .Pi * c.radius
      }

      func main() {
      r1 := Rect{10, 20}
      c1 := Circle{10}
      r2 := Rect{12, 14}
      c2 := Circle{5}

      printMeasure(r1, c1, r2, c2)
      }

      func printMeasure(m ...geometry) {
      for _, val := range m {
      fmt.Println(val)
      fmt.Println(val.area())
      fmt.Println(val.perimeter())
      }
      }
    • 위의 예를 보면 인터페이스 안에 메소드가 들어가있다. 또한, 같은 이름의 메소드가 두개씩 있다.

    • 이름이 동일하게 선언되어도 메소드가 전달받는 구조체가 다르기 때문에 괜찮은것이다.

    • 메인함수에서 구조체를 초기화하고 for문을 통해 각 구조체를 전달받은 메소드에 대해 결과값을 출력하고 있다.

    • 빈 인터페이스

      • 인터페이스는 어떠한 타입도 담을 수 있는 dynamic type 이다.

      • 인터페이스는 매개변수로 사용할 수 있다.

      • 인터페이스는 내용을 따로 선언하지 않아도 형으로 사용할 수 있다.

      • 하나의 변수를 형이 다른 형태로 저장해 출력한다고 생각한다면, 매개변수형에 따른 2개 이상의 함수를 만들어야한다.

      • 하지만 빈 인터페이스를 사용한다면, 어떤 형도 담을 수 있기 때문에 편하게 사용이 가능하게된다.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        package main

        import "fmt"

        func printVal(i interface{}) {
        fmt.Println(i)
        }

        func main() {
        var x interface{} //빈 인터페이스 선언

        x = 1
        printVal(x)

        x = "test"
        printVal(x)
        }
      • 위의 예에서 x의 값에따라 다르게 형을 선언하지 않고 출력하는것을 확인할 수 있다.

분해합_2231번

[Python, Go] 백준 2231번 풀이

분해합

  • 자연수 N의 생성자를 찾기 위해 1부터 N이전까지의 수를 모두 탐색한다.

    • N이 1일때는 생성자가 존재하지 않으므로 0을 출력한다.

    • i 를 키워나가면서 가장 작은 생성자를 찾으면 멈추고, N-1까지 탐색했을 때 결과값이 존재하지 않다면 0을 출력한다.

    • i 의 각 자리수를 sum에 더해줄때, 각 자리수를 for문으로 돌려서 더해주었음. —> 10으로 나누고 나머지를 사용하는 방법도있다.

  • Python 풀이

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    n = int(input())

    if n==1:
    print(0)

    for i in range(1,n):
    sum = i
    for j in str(i):
    sum += int(j)
    if sum == n:
    print(i)
    break
    elif i == n-1 :
    print(0)
  • Go 풀이

    • Python과 같은 방법을 사용했는데 Go에서는 int를 스트링으로 바꿔주기 위해 “strconv”를 사용하였다.

    • strconv.Itoa를 통해 int를 string으로 변환

    • strconv.ParseInt를 통해 string을 int로 바꿔주었다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      package main

      import (
      "fmt"
      "strconv"
      )

      func main() {
      var n int
      fmt.Scanf("%d", &n)

      if n == 1 {
      fmt.Printf("%d", 0)
      }

      for i := 1; i < n; i++ {
      sum := i
      for _, j := range strconv.Itoa(sum) {
      k, _ := strconv.ParseInt(string(j), 10, 8)
      sum += int(k)
      }
      if sum == n {
      fmt.Printf("%d", i)
      break
      } else if i == n-1 {
      fmt.Printf("%d", 0)
      }
      }
      }

Full Code

Full Code - Python

Full Code - Go

Golang_정리하기_3

[Go tutorial] Go 정리하기 - 3

Go-tour 참조

구름edu 참조

  • 맵(map)

    • 키와 value의 조합을 나타내기 위한것으로 파이썬의 딕셔너리를 생각하자.

    • var 맵이름 map[key자료형]value자료형 으로 선언

      • var a map[int]string :: key가 int이고 value가 string인 맵 a
    • 선언만 하고 초기화하지 않는다면 Nil map 이다.

    • 데이터 추가 or 갱신 :: 맵이름[key] = value 를 이용

    • 데이터 삭제 :: delete(맵이름,key) 를 이용

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      func main() {
      //지역번호와 지역 저장
      var m = make(map[string]string)

      m["02"] = "서울특별시"
      m["031"] = "경기도"
      m["032"] = "충청남도"
      m["053"] = "대구광역시"

      fmt.Println(m)

      //동일한 key값으로 value값을 저장하면 갱신이 된다
      m["032"] = "인천"

      fmt.Println(m)

      //m에 있는 "031"key의 value와 함께 삭제
      delete(m, "031")

      fmt.Println(m)
      }
    • key체크, value 확인

      • “맵이름[key]” 는 value와 키가 존재하는지 여부를 반환한다.

      • 존재하지 않는 키값이라면 자료형에따라 0 혹은 “” 를 반환

      • 해당 키가 존재하는지 여부에 따라 true/false 반환

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        func main() {
        m := make(map[string]int)

        m["Answer"] = 42
        fmt.Println("The value:", m["Answer"])
        ## print : The value: 42
        m["Answer"] = 48
        fmt.Println("The value:", m["Answer"])
        ## print : The value: 48
        delete(m, "Answer")
        fmt.Println("The value:", m["Answer"])
        ## print : The value: 0
        v, ok := m["Answer"]
        fmt.Println("The value:", v, "Present?", ok)
        ## print : The value: 0 Present? false
        }
  • 연습 : 맵 - 문제

  • 함수 클로져

    • 클로져는 함수 안에서 익명 함수를 정의해 바깥쪽 함수에서 선언한 변수에도 접근할 수 있는 함수를 뜻한다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      func adder() func(int) int {
      sum := 0
      return func(x int) int {
      sum += x
      return sum
      }
      }

      func main() {
      pos, neg := adder(), adder()
      for i := 0; i < 10; i++ {
      fmt.Println(
      pos(i),
      neg(-2*i),
      )
      }
      }
    • 위의 예에서 adder() 함수는 지역 변수 sum 을 초기화하고 입력받는 x를 더해주는 익명 함수를 반환합니다.

    • for문에서 함수가 실행될때마다 지역 변수가 초기화되지않고 더해주는 익명함수만을 통해 값이 지속적으로 증가/감소 하는것을 확인할 수 있습니다.

  • 연습 : 피보나치 클로져 - 문제

Golang_정리하기_2

[Go tutorial] Go 정리하기 - 2

Go-tour 참조

구름edu 참조

  • 구조체(Structs)

    • structs는 데이터들의 조합

    • type선언으로 이름을 지정할 수 있음

    • “객체이름 := 구조체이름{저장할값}”으로 입력해 선언과 동시에 초기화할 수 있다.

    • 구조체에 속한 필드(데이터)는 dot(.)으로 접근

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      type person struct {
      name string
      age int
      contact string
      }

      func main() {
      var p1 = person{}
      fmt.Println(p1)

      p1.name = "kim"
      p1.age = 25
      p1.contact = "01000000000"
      fmt.Println(p1)

      p2 := person{"nam", 31, "01022220000"} // 필드 이름을 생력할 시 순서대로 저장함
      fmt.Println(p2)

      p3 := person{contact: "01011110000", name: "park", age: 23} // 필드 이름을 명시할 시 순서와 상관 없이 저장할 수 있음
      fmt.Println(p3)

      p3.name = "ryu" //필드에 저장된 값을 수정할 수 있음
      fmt.Println(p3)

      fmt.Println(p3.contact) //필드 값의 개별 접근도 가능함
      }
  • 포인터

    • 포인터 연산은 불가능

    • 포인터를 이용한 간접 접근은 실제 구조체에도 영향을 끼침

    • “&” 을 매개변수 앞에 붙여 pass by reference 를 통해 값이 저장된 주소에 직접 접근할 수 있음.

    • 구조체 포인터를 생성하는 방법은 두 가지가 있다.

      • ‘new(구조체이름)’ 을 사용하여 객체를 생성

      • 구조체 이름 앞에 & 붙이기

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        type Person struct {
        Name string
        }

        func main() {
        c := new(Person) // returns pointer
        c.Name = "Catherine"
        fmt.Println(c.Name) // prints: Catherine

        d := *c
        d.Name = "Daniel"
        fmt.Println(d.Name) // prints: Daniel

        i := &d
        i.Name = "Ines"
        fmt.Println(c.Name) // prints: Catherine
        fmt.Println(d.Name) // prints: Ines
        fmt.Println(i.Name) // prints: Ines
        }
  • 슬라이스(slice)

    • 슬라이스는 참조 타입이다. 따라서, 슬라이스를 복사한다는 것은 같은 주소를 참조한다는 것이다. 복사한 슬라이스의 값을 바꾸면 참조하는 슬라이스의 해당 값도 바뀌게 된다.

    • 슬라이스 선언

      • var a []int = []int{1,2,3,4} 와 같이 선언과 함께 초기화

      • make() 함수를 이용.

      • make(슬라이스 타입, 슬라이스 길이, 슬라이스 용량)

      • ex) s:=make([]int,3,3)

    • append() 함수를 통해 슬라이스에 데이터를 추가할 수 있다.

    • 슬라이스에 슬라이스를 추가하기 위해서는 슬라이스 뒤에 “…”을 입력

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      func main() {
      sliceA := []int{1, 2, 3}
      sliceB := []int{4, 5, 6}

      sliceA = append(sliceA, sliceB...)
      //sliceA = append(sliceA, 4, 5, 6)

      fmt.Println(sliceA)
      fmt.Println(sliceB)
      }
    • copy(붙여넣을 슬라이스, 복사할 슬라이스) 를 통해 한 슬라이스를 다른 슬라이스로 복사할 수 있다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      func main() {
      c := make([]int, 0, 3) //용량이 3이고 길이가0인 정수형 슬라이스 선언
      c = append(c, 1, 2, 3, 4, 5, 6, 7)
      fmt.Println(len(c), cap(c))

      l := c[1:3] //인덱스 1요소부터 2요소까지 복사
      fmt.Println(l)

      l = c[2:] //인덱스 2요소부터 끝까지 복사
      fmt.Println(l)

      l[0] = 6

      fmt.Println(c) //슬라이스 l의 값을 바꿨는데 c의 값도 바뀜
      //값을 복사해온 것이 아니라 기존 슬라이스 주솟값을 참조
      }
    • 위의 예제를 실행해보면 slice c의 값도 l 에 의해 바뀌는것을 확인할 수 있다. 왜냐하면, 슬라이스는 배열과 다르게 슬라이스 자체가 참조하고 있는 주소값을 같이 참조하기 때문이다.

    • 슬라이스 순회(iterates)

      • 슬라이스는 for 반복문에서 range를 통해 순회할 수 있다.

      • 이때, index와 value를 순회하며 필요치 않은 값은 “_” 를 이용해 무시할 수 있다.

Golang_정리하기-1

[Go tutorial] Go 정리하기 - 1

Go-tour 참조

  • 익스포트

    • Go 에서는 첫 문자가 대문자로 시작하면 특정 패키지를 사용하는 곳에서 접근할 수 있는 exported name이 됨
  • 함수

    • Go 는 코드를 왼쪽부터 자연스럽게 읽기 위해 매개변수 타입은 변수명 뒤에 명시.

    • 두 개 이상의 매개변수가 같은 타입일 때, 같은 타입을 취하는 마지막 매개변수에만 타입을 지정할 수 있음.

      1
      2
      3
      4
      5
      x int, y int

      #를 아래와 같이도 사용 가능

      x, y int
    • 하나의 함수는 여러 개의 결과를 반환할 수 있음.

      1
      2
      3
      func swap(x, y string) (string, string) {
      return y, x
      }
  • 변수

    • var 을 통해 변수를 선언.

    • 변수 선언과 함꼐 초기화 가능, 초기화를 하는 경우 타입 생략 가능. 이 경우, 초기화하고자 하는 값에 따라 타입이 결정됨.

      1
      var a, b, c int = 1, 2, 3
    • 함수 내에서 := 을 사용하면 var와 명시적인 타입을 생략할 수 있음.

  • 상수

    • const 키워드와 함께 변수처럼 선언.

    • 상수는 문자, 문자열, boolean, 숫자 타입 중의 하나가 될 수 있음

    • 숫자형 상수는 정밀한 값을 표현할 수 있음. Go-tour 사이트에서 제공하는 예제를 이해하기 위해서는 Go의 << 와 >> 연산자의 이해가 필요하다.

    • <<, >> 연산자에 대해

      • << 와 >> 연산자는 비트 이동 연산자로 Left shift, Right shift 라고 함.
      • Left shift 는 현재 값의 비트를 주어진 값만큼 왼쪽으로 Right shift는 현재 값의 비트를 주어진 값만큼 오른쪽으로 옮깁니다.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        const (
        a = 1
        b = a << 1
        )

        func main() {
        fmt.Println(a) ### 1 출력
        fmt.Printf("%08b\n", a) ### 00000001 출력
        fmt.Println(b) ### 2 출력
        fmt.Printf("%08b", b) ### 00000010 출력
        }
  • 반복문 for

    • Go 에는 반복문으로 for 하나만 존재.

    • 조건문만 표현해서 루프를 표현 가능.

      1
      2
      3
      4
      5
      6
      7
      func main() {
      sum := 1
      for sum < 1000 {
      sum += sum
      }
      fmt.Println(sum)
      }
    • 위와 같이 표현하면 while을 사용하듯 for을 사용할 수 있다.

    • 조건문을 생략하는것으로 무한 루프를 만들 수 있다.

      1
      2
      3
      4
      func main() {
      for {
      }
      }
  • 조건문 if

    • 반복문과 마찬가지로 실행문을 위한 { } 만 필요.

    • for 처럼 조건문 앞에 문장을 실행할 수 있음.

      1
      2
      3
      4
      5
      6
      func pow(x, n, lim float64) float64 {
      if v := math.Pow(x, n); v < lim {
      return v
      }
      return lim
      }
    • 위의 예를 보면, v < lim 을 통한 조건문 앞에 v := math.Pow(x,n) 을 실행했다.

    • 이렇게 선언된 변수(위에서는 v)는 if 안쪽 범위에서만(else 블럭 안에서도 가능) 사용할 수 있다.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×