함수

1. 함수 생성 방법

package main

func main(){
  a := 1
    say(a)
}

func say(a int) {
    println(a)
}

func키워드를 이용해서 함수를 선언할 수 있고 가장 기본적으로 만드는 main도 함수 이다.



2. 매개변수(인자)

1) 전달 방식

Java처럼 primitive자료형은 pass by value, reference자료형은 pass by refernece가 아닌 go는 C처럼 *을 이용해서 value인지 reference인지 정해서 넘겨줄 수 있다.

func main(){
	a := 1
	increase1(a)
	println(a)		  //1
	increase2(&a)
	println(a)		  // 2
}

func increase1(a int) {
	a+=1
}

func increase2(a *int) {
	*a+=1
}

포인터를 이용해서 변수의 주소를 넘겨주면 pass by reference로 함수에서도 해당 함수를 호출한 곳의 변수의 값을 변경할 수 있다.


2) 중복된 자료형 생략

package main

import "fmt"

func main() {
	variousVariables(1,2,true, 1.2)
}

func variousVariables( a, b int, c bool, d float32){
	fmt.Println(a,b,c,d)    //1 2 true 1.2
}

위처럼 매개변수가 같은 자료형을 갖는다면 변수선언 방식과 비슷하게 자료형을 생략해서 마지막에만 작성을 해주어도 된다.


3) 가변 인자 함수

매개변수의 개수가 정해지지 않고 여러개를 전달할때 사용할 수 있는 함수 기법으로 을 이용하여 표현할 수 있다.

func main() {
    say(1,2,3,4)
    say(10)
}

func say(nums ...int) {
    for _, num := range nums {
        println(num)
    }
}



3. 리턴 값

go는 다른 언어들과는 다르게 리턴값을 void나 하나가 아닌 여러개를 가질 수 있다.

func main() {
    total1 := sum1(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    println(total1)         //55

    count, total2 := sum2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    println(count, total2)  //10 55
}

func sum1(nums ...int) int {
    sum := 0
    for _, num := range nums {
        sum += num
    }
    return sum
}


func sum2(nums ...int) (int, int) {
  s := 0
  count := 0
	for _, n := range nums {
		s += n
		count++
	}
	return count, s
}

return값이 여러개일 경우에는 () 로 묶어 표시해야 하고 return문을 , 을 이용해서 여러개의 값을 return하도록 작성해주면 된다.


1) Named Return Parameter

return값에 이름을 지정하는 Named Return Parameter도 제공한다.

func main() {
    count, total2 := sum2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    println(count, total2)  //10 55
}
func sum2(nums ...int) ( count int, s int) {
	for _, n := range nums {
		s += n
		count++
	}
	return
}

위처럼 return값에 자료형만 작성하는 것이 아니라 변수명을 작성해 줄 수 있는데 이는 매개변수처럼 하나의 변수로써 생성이 되기 때문에 zero value로 처음에 선언이 되고 함수내부에서 변수처럼 사용이 가능하다. 또한 return문을 작성할때 필요로하는 return값들을 모두 작성해줄 필요없이 return만 작성해도 변수에 할당된 값을 그대로 반환해주기 때문에 쉽게 작성이 가능하다.



4. 익명 함수

JS의 익명함수 처럼 함수의 이름이 없는 함수로써 그자리에서 한번만 바로 실행하는 함수를 작성하거나 변수에 할당하기 위한 방식의 함수 이다.

func main() {
    sum := func(n ...int) int {
        s := 0
        for _, i := range n {
            s += i
        }
        return s
    }

    result := sum(1, 2, 3, 4, 5) //익명함수 호출
    println(result)
}

함수의 선언 방식은 거의 똑같지만 func키워드 뒤에 함수명이 오지 않고 이렇게 선언한 함수를 바로 변수에 할당하는 것을 볼 수 있다.

변수에 할당하게 되면 그 변수이름으로 함수를 똑같이 사용이 가능하다.



5. 일급 함수

go에서 함수는 하나의 데이터 타입으로 취급되기 때문에 다른 함수의 파라미터로 전달하거나 리턴값으로 사용할 수 있다.

package main

func main() {
    add := func(a int, b int) int {
        return a + b
    }

    result1 := calc(add, 10, 20)
    println(result1)

    result2 := calc(func(a int, b int) int { return a + b }, 10, 20)
    println(result2)

}

func calc(f func(int, int) int, a int, b int) int {
    result := f(a, b)
    return result
}

calc() 의 매개변수로 func키워드를 이용해 함수를 매개변수로 받을 수 있으며, 이때 매개변수타입과 reutrn타입을 작성해주어야 한다. 이렇게 함수를 매개변수로 받으면 해당 함수 내에서 인자로받은 함수를 사용할 수 있다.

함수의 매개변수로 함수를 넘겨줄때는 result1처럼 익명함수를 통해 선언된 함수타입 변수를 넘겨주거나 result2처럼 바로 익명함수를 작성해서 넘겨주는 방식도 가능하다.

1) 함수 type 정의

함수의 매개변수로 함수타입을 받을 때 매개변수의 타입과 return타입을 매번 작성해주는 것이 번거로울 수 있는데, C/C++의 typedef처럼 go도 type을 이용해 함수 원형을 정의 하여 반복코드를 줄일 수 있다.

package main

type funcII func(int,int) int

func main() {
	add := func(a int, b int) int {
		return a + b
	}
	result1 := calc(add, 10, 20)
	println(result1)
}

func calc(f funcII, a int, b int) int {
	result := f(a, b)
	return result
}

이렇게 함수원형을 정의하고 함수를 다른 함수에 전달하고 리턴받는 기능을 Delegate라고 부른다.





Reference

『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트

Tags :

Related Posts

Home Server 만들기

Home Server 만들기

집 서버를 만들게 된 배경 집 컴퓨터를 교체하고 지인의 컴퓨터를 교체해주면서 부품들이 여럿 남게 되는 상황이 생겼는데, 그냥 버리기 아까워 컴퓨터를 한대 더 조립을 하게 되었다. 사양은 Intel(R) Celeron(R) CPU G3930 에 4G, 250Gb 이다. 컴퓨터를 조립 후 막상 사용할 곳이 없어 고민하던 중에 aws 프리티어도 끝났겠다 싶어 개발이나 테스트용으로 서버를 사용하면 좋을 것 같아 서버로 만들어보...

Read More
JVM과 자바 실행

JVM과 자바 실행

  • Java
  • 2021년 1월 22일

백기선님의 유튜브 로 진행하시는 스터디를 진행하며 올리는 정리 블로그입니다. 1. JVM Java Virtual Machine의 약자로 Java와 OS사이에서 중개자 역할을 하여 메모리 관리, GC(garbage collection)을 수행하는 스택기반의 가상머신으로 C++,C와 같은 언어들과 다르게 OS에 상관없이 동작이 가능하다. Java는 C나 C++과 같이 바로 컴파일...

Read More
[WSL2] 포트포워딩과 window에서 workbench로 접속하기

[WSL2] 포트포워딩과 window에서 workbench로 접속하기

WSL2를 이용하여 개발을 진행서 외부에서 접근하고 싶거나, 배포를 위해 접근하고 싶을 수가 있는데, 문제가 되는 것이 WSL2는 VM과 같은 환경이라 별도의 IP를 갖는다는 점이다. 그러면 포트포워딩을 하면 되지 않느냐라고 할 수 있는데 맞다 포트포워딩을 하면된다 하지만 재부팅을 할때마다 변경되는 IP에 매번 포트 포워딩을 할 수 없는 노릇이기에 Powershell...

Read More