본문 바로가기
프로그래밍/Golang

[GOLANG] 공부 (3)

by 채연2 2020. 10. 29.

- import 패키지 > 패키지 이름은 디렉토리 경로의 마지막 이름을 사용.
- import (pkg1, pkg2, ...) || import "pkg1" import "pkg2"
- 첫 문자가 대문자로 시작 > 패키지를 사용하는 곳에서 접근 가능한 exported name
math.pi : cannot refer to unexported name math.pi
mathPi : 3.141592653589793

*함수
- 매개변수 타입은 변수명 뒤에 명시
- x int, y int > x, y int
- 하나의 함수는 여러 개의 결과 반환 가능
- 반환 값에 이름을 부여하면 변수처럼 사용 가능, 반환 값을 지정하지 않고 return해도 알아서 반환
package main
import "fmt"
func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}
func main() {
    fmt.Println(split(17)) // 함수도 값처럼 사용 가능
}

------------------------------------------> return> 7 19

- 함수는 클로져(Closure)를 반환 가능
func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

 

● 피모나치 클로져
func fibonacci() func() int {
a, b := 0, 1
return func() int {
c := a
a, b = b, c+b

return c
}
}

*변수
- var 변수명 type
- 변수 선언과 함께 변수 각각 초기화 가능 > 이 경우, 변수 타입 생략 가능
var c, python, java = 1, false, "no!"
- := 사용 시, var과 명시적인 타입 생략 가능 (함수 내에서만 사용 가능)
c, python, java := 1, false, "no!"
- const 상수 > 문자(character), 문자열(string), 부울(boolean), 숫자 타입 중 하나
- 타입을 지정하지 않은 상수는 문맥에 따라 타입 가짐

 

*반복문
- 반복문은 for 뿐임. 소괄호가 필요 없음
for i := 0; i < 10; i++ {
...
}
- 전,후 처리를 제외하고 조건문만 표현 가능 > C언어에서의 while을 사용하듯이 사용 가능
sum := 1
for sum < 1000 {
sum += sum
}
- 조건문 생략하면 무한 루프
for {
}

*조건문
- 조건 표현 소괄호는 사용 안함. 실행문을 위한 중괄호는 사용.
if x < 0 {
...
}
- for문처럼 if에서도 조건문 앞에 짧은 문장 실행 가능 > 짧은 실행문을 통해 선언된 변수는 if 내에서만 사용 가능  > else 내에서도 사용 가능
if v := math.Pow(x, n); v < lim {
return v
}

 

*자료형
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte (uint8)
rune (int32) > 유니코드 코드 포인트 값 표현
float32 float64
complex64 complex128

*구조체
- struct는 필드들의 조합. type 선언으로 struct의 이름 지정 가능
type Vertex struct {
    X int
    Y int
}
func main() {
    fmt.Println(Vertex{1, 2})
}
- 구조체에 속한 필드는 dot(.)으로 접근
v := Vertex{1, 2}
v.X = 4
- 포인터 연산은 불가. 구조체 변수는 구조체 포인터를 이용해서 접근 가능 > 실제 구조체에도 영향을 미침
type Vertex struct {
    X int
    Y int
}
func main() {
    p := Vertex{1, 2}
    q := &p
    q.X = 1e9
}
- 구조체 리터럴 : 필드와 값을 나열해서 구조체를 새ㅗㄹ 할당하는 방법 `{Name: value}`
p = Vertex{1, 2}  // has type Vertex
q = &Vertex{1, 2} // has type *Vertex
r = Vertex{X: 1}  // Y:0 is implicit
s = Vertex{}      // X:0 and Y:0
- new함수 : new(Vertex)는 모든 필드가 0이 할당된 Vertex 구조체 타입의 포인터를 반환 (숫자에서는 0, 참조 타입에서는 nil)
v := new(Vertex) > &{0 0}
var v *Vertex = new(Vertex)

 

*슬라이스(Slices)
- 동적 배열의 개념. 가변배열, 동적배열.
- 배열과 슬라이스의 차이 > 원소에 값을 지정하지 않는다는 점.
배열  : var arr1 = [5]int{1, 2, 3, 4, 5}
슬라이스 : var arr1 = []int{1, 2, 3, 4, 5}
- 배열의 값을 가리킴(point), 배열의 길이를 가지고 있음 > []T 는 타입 T 를 가지는 요소의 슬라이스
p := []int{2, 3, 5, 7, 11, 13} , 길이 len(p) , 용량 cap(p)
- 재분할 할 수도 있고, 같은 배열을 가리키는 새로운 슬라이스 생성 가능.
p := []int{2, 3, 5, 7, 11, 13}
p [2 3 5 7 11 13]
p[0:5] [2 3 5 7 11]
p[:3] [2 3 5]
p[4:] [11 13]
p[1:1] []
p[:] [2 3 5 7 11 13]
- make 함수로 슬라이스 생성. 생성된 슬라이스는 0을 할당한 배열을 생성하고 참조. make 함수의 세번째 매개변수로 용량(capacity) 제한 가능
a := make([]int, 5) //a len=5 cap=5 [0 0 0 0 0]
b := make([]int, 0, 5) //b len=0 cap=5 []
c := b[:2] //c len=2 cap=5 [0 0]
d := c[2:5] //d len=3 cap=3 [0 0 0]
※길이 len() 와 용량 cap() 의 차이
s := make([]int, 0, 3)
for i := 0; i < 10; i++ {
s = append(s, i)

fmt.Printf("cap %v, len %v, %p\n", cap(s), len(s), s)
}
cap 3, len 1, 0x40e020
cap 3, len 2, 0x40e020
cap 3, len 3, 0x40e020
cap 8, len 4, 0x456020
cap 8, len 5, 0x456020
cap 8, len 6, 0x456020
cap 8, len 7, 0x456020
cap 8, len 8, 0x456020
cap 16, len 9, 0x430080
cap 16, len 10, 0x430080
- 슬라이스의 zero value는 nil. nil 슬라이스는 길이와 최대크기가 0. if문으로 nil과 비교 가능
var z []int [] 0 0
if z == nil {
fmt.Println("nil!")
}

*레인지 (Range, 범위)
- for 반복문에서 range를 사용하면 슬라이스나 맵을 순휘(iterates) 가능
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
- _를 이용하여 index나 값 무시 가능. 인덱스만 사용 가능
pow := make([]int, 10)
for i := range pow {
pow[i] = 1 << uint(i)
}
for _, value := range pow {
fmtPrintf("%d\n", value)
}

 

*맵 (Maps)
- 값에 키를 지정. 반드시 사용하기 전에 make를 명시해야함 > make를 수행하지 않은 nil에는 값 할당 불가
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
var m2 map[string]Vertex
func main() {
    m = make(map[string]Vertex)
    m["Bell Labs"] = Vertex{40.68433, -74.39967}
    fmt.Println(m["Bell Labs"]) //{40.68433 -74.39967}
    fmt.Println(m["Bell Labs"].Lat) //40.68433
    fmt.Println(m2) //map[]
m2["TEST"] = Vertex{40.68433, -74.39967} //panic: assignment to entry in nil map
}
- 맵 리터럴은 구조체 리터럴과 비슷하지만 key를 반드시 지정해야 함.
var m = map[string]Vertex{
    "Bell Labs": Vertex{
        40.68433, -74.39967,
    },
    "Google": Vertex{
        37.42202, -122.08408,
    },
}

- 가장 상위의 타입이 타입명이라면 리터럴에서 타입명 생략 가능
"Bell Labs": Vertex{40.68433, -74.39967} > "Bell Labs": {40.68433, -74.39967}
- 맵 다루기
맵 m의 요소 삽입 및 수정  : n[key] = elem
요서 값 가져오기 : elem = m[key]
요소 지우기 : delete(m, key)
키의 존재 여부 확인하기 : elem, ok = m[key] //존재하지 않는 key의 반환 값은 타입에 맞는 zero value.
m["Answer"] = 42 //42
m["Answer"] = 48 //48
delete(m, "Answer") //0
v, ok := m["Answer"] //v:0, ok:false

 

320x100

'프로그래밍 > Golang' 카테고리의 다른 글

[GOLANG] 공부 (4)  (0) 2020.10.29
[GOLANG] 공부 (2)  (0) 2020.10.29
[GOLANG] 공부 (1)  (0) 2020.10.29

댓글