참고
니코쌤의 go 강의
go에서 변수와 상수를 선언하는 방법에 대해 알아보자.
package main
import "fmt"
func main() {
var value string = "변수"
fmt.Println(value)
}
우선 변수를 선언 하는 방식은 다음과 같다. type을 선언하지 않고 축약해서도 사용할 수 있는데
package main
import "fmt"
func main() {
value := "변수"
fmt.Println(value)
}
다음과 같이 작성하면 type을 선언해주지 않고 축약해서 사용할 수 있다.
하지만 축약형의 경우 func 내에서만 사용할 수 있는데 예를 들어
package main
import "fmt"
var value string = "변수1"
func main() {
fmt.Println(value)
}
다음과 같이 func 밖에서는 변수 선언이 가능하지만
package main
import "fmt"
value := "변수1"
func main() {
fmt.Println(value)
}
다음과 같이 func 외부에서 축약형으로 작성시 에러가 발생한다.
또한 변수는 가장 마지막에 선언된 값으로 적용된다.
package main
import "fmt"
var value string = "변수1"
func main() {
value := "변수2"
fmt.Println(value)
}
의 결과는
다음과 같다.
package main
import "fmt"
const value string = "변수1"
func main() {
value = "변수2"
fmt.Println(value)
}
상수의 경우 다음과 같이 const
를 통해 작성할 수 있고 상수 값을 변경하려고 하면
당연히 에러가 난다.
그런데 여기서 주의해야할 점은
package main
import "fmt"
const value string = "변수1"
func main() {
value := "변수2"
fmt.Println(value)
}
다음과 같이 코드를 작성했을 때 value
는 2개의 value로 나눠지는데 하나는 상수인 value와 다른 하나는 변수인 value이다. 해당 코드를 실행하면
에러는 발생하지 않고 다음과 같이 가장 최근에 선언된 value값이 들어오는 것을 확인할 수 있다.
package main
import "fmt"
func main() {
const value string = "변수1"
fmt.Println(value)
}
func 내에서도 동일하게 사용하면 되며 축양형이 따로 없다!
package main
import "fmt"
func main() {
fmt.Println(multiply(3, 4))
}
func multiply(a int, b int) int {
return a * b
}
곱셈 연산을 대신해주는 func는 다음과 같이 작성할 수 있다.
package main
import (
"fmt"
"strings"
)
func main() {
length, upper := lenAndUpper("juno")
fmt.Println("length =", length)
fmt.Println("upper =", upper)
}
func lenAndUpper(name string) (int, string) {
return len(name), strings.ToUpper(name)
}
다음과 같이 name string 값을 받아서 문자열의 길이와 Upper를 하여 반환하는 함수를 선언해두면 위 코드와 같이 작성하여 결과를 확인해볼 수 있다.
만약 위 코드에서 길이 값만 필요하다면
package main
import (
"fmt"
"strings"
)
func main() {
length, _ := lenAndUpper("juno")
fmt.Println("length =", length)
// fmt.Println("upper =", upper)
}
func lenAndUpper(name string) (int, string) {
return len(name), strings.ToUpper(name)
}
다음과 같이 작성해주면 return하는 값을 컴파일러에서 무시하고 진행된다.
package main
import (
"fmt"
)
func main() {
array("가", "나", "다", "라", "마")
}
func array(name ...string) {
fmt.Println(name)
}
다음과 같이 ...string
으로 매개변수를 선언해주면 무한으로 받을 수 있고 동일한 변수를 array로 자동으로 변경해준다.
결과도 다음과 같이 배열로 나오는 것을 확인할 수 있다.
naked return은 return할 변수들을 미리 지정하여 따로 return 에 적어주지 않아도 자동으로 return하도록 하게 할 수 있는 기능이다. 말로 이해가 안된다면 코드로 봐보자!
package main
import (
"fmt"
"strings"
)
func main() {
length, upper := lenAndUpper("juno")
fmt.Println("length =", length)
fmt.Println("upper =", upper)
}
func lenAndUpper(name string) (length int, upper string) {
length = len(name)
upper = strings.ToUpper(name)
return
}
위에서 작성했던 코드랑 동일한 코드인데 lenAndUpper
부분의 코드를 보면 return 값이 없이 매개변수에 return 변수들을 미리 지정해두었다. 그럼 함수가 끝날 때 자동으로 반환하도록 설정할 수 있는 것이다.
되게 좋은 기능이긴 하지만 코드를 읽는 개발자 입장에서는 만약 함수의 길이가 길어진다면 return 되는 값을 까먹을 수도 있고 이건 팀 단위에서 꼭 약속을 정하고 동일하게 작성하는 것이 더 좋을거 같긴 하다!
결과도 위 결과와 동일한 것을 확인할 수 있다.
func가 return한 뒤 실행되는 코드를 미리 지정해둘 수 있다. 이것도 코드로 빨리 봐보자!
package main
import (
"fmt"
"strings"
)
func main() {
length, upper := lenAndUpper("juno")
fmt.Println("length =", length)
fmt.Println("upper =", upper)
}
func lenAndUpper(name string) (length int, upper string) {
defer fmt.Println("lenAndUpper end !")
fmt.Println("lenAndUpper start !")
length = len(name)
upper = strings.ToUpper(name)
return
}
다음과 같이 코드를 작성하면 defer
라는 예약어를 통해 함수가 종료되었을 때 end 를 출력하도록 했다. 분명 가장 위에 있는 코드인데 함수가 종료되고 실행될 것이다.
결과를 보면 start가 먼저 실행되었고 함수가 종료되었을 때 end가 호출되었다. 함수가 종료되고 나서의 행동들을 명확하게 지정해둘 수 있으니 코드를 읽을 때 더 읽기 편해질거 같다.