// 방법 1.
var a *int
// 방법 2.
var b *int = new(int)
p := 7
fmt.Println(p) // p값
fmt.Println(&p) // p의 주소
a := &p
var b *int
b=&p
fmt.Println(a,b) // p의 주소
fmt.Println(&a,&b) // a와 b의 주소
fmt.Println(*a,*b) // p의 값 : 역참조
*a++ // a가 역참조한 (*a) 값을 증가 시킴. 7 출력
func rptc(n *int) {
*n = 77
}
var a int = 10
fmt.Println(a) // 10 출력
rptc(&a)
fmt.Println(a) // 77 출력
func 함수이름 (입력파라미터)(리턴파라미터)
func multiply(x int, y int) (int, int) { //(x,y int 가능)
return x * 5, y * 5
}
func arrayMultiply(a, b, c, d, e int) (int, int, int, int, int) {
return a * 1, b * 2, c * 3, d * 4, e * 5 // 리턴 5개
}
// 리턴 파라미터를 받을 변수를 리터럴로 선언. 불필요한 값은 밑줄(_)로 생략
a, b := multiply(1, 2)
c, _ := multiply(5, 2)
_, d := multiply(1, 10)
x1, x2, x3, x4, x5 := arrayMultiply(1, 1, 1, 1, 1)
x6, _, x7, _, x10 := arrayMultiply(1, 1, 1, 1, 1)
func sum(n ...int) int {
tot := 0
for _, value := range n {
tot += value
}
return tot
}
func prtWord(msg ...string) {
for _, value := range msg {
fmt.Println(value)
}
}
y := sum(1, 2, 3, 4, 5, 6, 7)
prtWord("a", "apple", "gogogo")
// 슬라이스 넘기기
a := []int{5, 6, 6, 7, 8, 9, 10}
m := sum(a...)
//함수를 배열에 할당
func sum(n ...int) int {
tot := 0
for _, value := range n {
tot += value
}
return tot
}
func multiply(x, y int) (r int) {
r = x * y
return r
}
f := []func(int, int) int{multiply, sum}
a := f[0](10, 10)
b := f[1](10, 10)
// 함수를 변수에 할당
var f1 func(int, int) int = multiply
f2 := sum
a := f1(10, 10)
b := f2(10, 10)
// 함수를 맵에 할당
m := map[string]func(int, int) int{
"mul_func": multiply,
"sum_func": sum,
}
fmt.Println(m["mul_func"](10, 10))
func main() {
func() {
fmt.Println("즉시 실행")
}()
}
msg := "helelo golang"
func(m string) {
fmt.Println(m) // msg 문자열 값 즉시 실행
}(msg)
// 즉시 실행하여 변수에 할당
r := func(x, y int) int {
return x * y
}(10, 100)
}
예시1) 외부 변수를 참조하여 실행
m, n := 5, 10
sum := func(c int) int { // 익명함수 변수 할당
return m + n + c // m과 n은 소멸되지 않음
}
r2 := sum(10)
예시 2) 함수 내 함수 리턴
func main() {
cnt := increaseCnt()
fmt.Println(cnt())
fmt.Println(cnt())
}
func increaseCnt() func() int {
n := 0
return func() int {
n += 1 // 리턴되는 함수에서 n이 사용되므로 리턴된 함수에 대한 참조가 사라질때 까지 n은 메모리에서 반환 대상이 안됨
return n
}
}
전역변수를 쓰지 않고 클로저를 사용하는 이유?
=> 전역변수는 다른 함수, 모듈에서도 참조 가능하므로 개발자의 실수로 값이 잘못되는 상황이 발생할 수 있지만 클로저는 해당 함수 내에서만 기억하는 것이므로 외부에서는 참조하지 못하게 하면서 값을 기억할수 있는 것이 장점
클로저는 함수 외부 변수에 대한 참조를 유지 하기 때문에 무분별한 클로저 남발은 메모리 누수로 이어질 수 있음
var closurFunc func(int) int
func outerFunc() {
m, n := 5, 10
closurFunc = func(c int) int { // 익명함수 변수 할당
return m + n + c
// outerFunc가 종료되어 메모리가 반환되어도 m, n 지역변수는 참조가 살아있어 GC에서 메모리 해제가 되지 않음
}
r2 := closurFunc(10)
fmt.Println("here ", r2)
}
func main(){
outerFunc()
// outerFunc의 지역 변수인 m,n에 대한 메모리가 해제되지 않으므로 outerFunc이 반환되어도 closurFunc 사용 가능.
// 이런식의 코딩이 많아져 지역변수들중 전역변수화 되어 메모리 해제가 되지 않는게 많아지면 GC에서 정리되지 않아 메모리 부족 현상이 발생할수있음
r2 := closurFunc(20)
fmt.Println("here ", r2)
}
함수 실행 지연 예약어
func ex_f1() {
fmt.Println("f1 : start! ") // 출력 순서 1
defer ex_f2() // 출력 순서 4
fmt.Println("f1 : end") // 출력 순서 2
defer func(){
fmt.Println("third") // 출력 순서 3
}()
}
func ex_f2() {
fmt.Println("f2 : called")
}
func main() {
ex_f1()
}
중첩 함수에 defer 사용한 경우, 실행순서 유의
func start(t string) string {
fmt.Println(" start: ", t) // 실행 1
return t
}
func end(t string) {
fmt.Println(" end : ", t) // 실행 3
}
func a() {
defer end(start("b")) //중첩함수 주의. start 함수는 먼저 실행됨.
fmt.Println("in a") // 실행 2
}
func main() {
a()
}
[학습 자료] 인프런 - 쉽고 빠르게 끝내는 GO언어 프로그래밍 핵심 기초 입문 과정
[공식사이트] https://golang.org/tutorial