Published: 07 Oct 2018 › Updated: 07 Oct 2018![[The Go Programming Language] 2장 프로그램 구조 - 2.7 범위](https://i.ecency.com/p/HNWT6DgoBc18GVREvvsnAjfLwLF5qHHFduNHKinq2s659FD5RBdc1NzHR5ipPfZkVmpViuMe2Kd1XiLUrqyHZMEMDhCu4832hHtzqdCuTeZD13h4g1CGrtaL9ae?format=match&mode=fit&height=377)
[The Go Programming Language] 2장 프로그램 구조 - 2.7 범위
안녕하세요. 개발자 모도리입니다.
The Go Programming Language 라는 책으로 Go를 공부하고 있으며, 해당 책의 내용을 요약 정리해서 올리려고 합니다. 저는 번역본을 구매해서 공부하고 있습니다.
게시물에 예제코드 라고 나오는 것들은 https://github.com/modolee/tgpl.git 에서 다운 받으실 수 있습니다.
지난 게시물
- [Go] Mac에서 Atom으로 Go 개발 환경 구축하기
- [The Go Programming Language] 1장 튜토리얼 - 1.1 Hello, World
- [The Go Programming Language] 2장 프로그램 구조 - 2.1 이름
- [The Go Programming Language] 2장 프로그램 구조 - 2.2 선언
- [The Go Programming Language] 2장 프로그램 구조 - 2.3 변수
- [The Go Programming Language] 2장 프로그램 구조 - 2.4 할당
- [The Go Programming Language] 2장 프로그램 구조 - 2.5 타입 선언
- [The Go Programming Language] 2장 프로그램 구조 - 2.6 패키지와 파일
2장 프로그램 구조
2.7 범위
선언과 수명
- 선언의 범위는 소스코드 안에서 선언된 이름으로 해당 선언을 참조할 수 있는 구역입니다.
- 선언의 범위는 프로그램 텍스트의 영역이며, 컴파일 시의 속성입니다.
- 수명은 실행 중에 변수가 프로그램의 다른 구역에서 참조할 수 있는 시간의 범위입니다.
- 변수의 수명은 실행 시의 속성입니다.
예제
내부 선언이 외부 선언을 가리는 경우
func f() {}
var g = "g"
func main() {
f := "f"
fmt.Println(f) // "f"; 지역 변수 f가 패키지 수준 함수 f를 가린다.
fmt.Println(g) // "g"; 패키지 수준 변수
fmt.Println(h) // 컴파일 오류; 선언되지 않음: h
}
각기 다른 어휘 블록에 동일한 이름의 변수가 선언되어 있는 경우
func main() {
x := "hello!"
for i := 0; i < len(x); i++ {
x := x[i]
if x != '!' {
x := x + 'A' - 'a'
fmt.Printf("%c", x) // "HELLO" (반복마다 글자 1개)
}
}
}
- 서로 다른
x가 세 개 사용되고 있습니다. x[i],x + 'A' - 'a'는 각각 다른 외부 x 선언을 참조합니다.
묵시적인 블록 생성
if x := f(); x == 0 {
fmt.Println(x)
} else if y := g(x); x == y {
fmt.Println(x, y)
} else {
fmt.Println(x, y)
}
fmt.Println(x,y) // 컴파일 오류: 여기서는 x, y를 볼 수 없습니다.
- 두번 째 if문은 첫 번째 if문과 중첩돼 있으므로 첫 번째 문장의 초기화 과정에서 선언된 변수는 두 번째 문장에서도 볼 수 있습니다.
if 블록에서 오류 처리 시
if f, err := os.Open(fname); err != nil { // 컴파일 오류: 사용되지 않음: f
return err
}
f.Stat() // 컴파일 오류: 정의되지 않은 f
f.Close() // 컴파일 오류: 정의되지 않은 f
- f의 범위는 if문에 한정되므로 이후 문장에서는 f에 접근할 수 없어서 컴파일 오류가 발생합니다.
- 컴파일러에 따라 지역 변수 f가 사용되지 않았다는 추가 오류 보고를 받을 수도 있습니다.
// f를 조건문 전에 선언해서 이후에 이용할 수 있게 합니다.
f, err := os.Open(fname)
if err != nil {
return err
}
f.Stat()
f.Close()
// Stat와 Close 함수 호출을 else 블록 안으로 옮겨서 f와 err를 외부 블록에 선언하지 않습니다.
if f, err := os.Open(fname); err != nil {
return err
} else {
// f와 err는 여기서도 볼 수 있습니다.
f.Stat()
f.Close()
}
짧은 변수 선언에서의 범위
- init 함수에서 현재 디렉토리를 가져와서 패키지 수준의 변수를 업데이트 하는 프로그램을 작성하려고 합니다.
var cwd string
func init() {
cwd, err := os.Getwd() // 컴파일 오류: 사용되지 않음: cwd
if err != nil {
log.Fatalf("os.Getwd failed: %v", err)
}
}
init함수의 블록에서는 사전에 선언된cwd와err가 없으므로:=구문이 둘 다 지역 변수로 선언합니다.cwd의 내부 선언이 외부 선언으로의 접근을 막기 때문에 이 문장은 의도대로 패키지 수준의cwd변수를 갱신하지 않습니다.
var cwd string
func init() {
cwd, err := os.Getwd() // NOTE: 오류!
if err != nil {
log.Fatalf("os.Getwd failed: %v" err)
}
log.Printf("Working directory = %s", cwd)
}
- 첫번째 코드에서
cwd를 사용하지 않기 때문에 컴파일 오류가 발생했는데, 두번째 코드 처럼cwd변수를 사용하는 코드가 포함되어 있다면 어디에서 문제가 발생하는지 찾기 어려울 수 있습니다.
var cwd string
func init() {
var err error
cwd, err = os.Getwd()
if err != nil {
log.Fatalf("os.Getwd failed: %v", err)
}
}
- 이런 잠재적인 문제를 해결하는 방법은 여러가지가 있는데, 가장 직접적인 방법은 세번째 코드와 같이
err를 별도의var선언으로 분리하고:=를 사용하지 않는 것입니다.
이어보기
Leave [The Go Programming Language] 2장 프로그램 구조 - 2.7 범위 to:
Read more #kr-dev posts
Best Posts From 모도리
We have not curated any of modolee's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From 모도리
- ELK Stack을 이용한 로그 관제 시스템 만들기
- 이더리움 콘스탄티노플 하드포크 내용 정리 (Ethereum Constantinople Hardfork)
- [Mastering Ethereum] Oracle
- 겨울철 대비 (이더리움) 가스 절약 방법
- Puppeth를 이용해 AWS에 Private Ethereum Network 구성하기 (PoA)
- [Mastering Ethereum] 4장 지갑(Wallet)
- [Mastering Ethereum] 3장 키와 주소
- [The Go Programming Language] 3장 기본 데이터 타입 - 3.1 정수
- [Ethereum - White Paper] 이더리움 백서 기준 개념 정리
- [The Go Programming Language] 2장 프로그램 구조 - 2.7 범위
- [The Go Programming Language] 2장 프로그램 구조 - 2.6 패키지와 파일
- [The Go Programming Language] 2장 프로그램 구조 - 2.5 타입 선언
- [The Go Programming Language] 2장 프로그램 구조 - 2.4 할당
- [The Go Programming Language] 2장 프로그램 구조 - 2.3 변수
- [The Go Programming Language] 2장 프로그램 구조 - 2.2 선언
- [The Go Programming Language] 2장 프로그램 구조 - 2.1 이름
- [The Go Programming Language] 1장 튜토리얼 - 1.8 미진한 부분
- [The Go Programming Language] 1장 튜토리얼 - 1.7 웹 서버
- [The Go Programming Language] 1장 튜토리얼 - 1.5, 1.6 URL 반입(Fetching)
- [The Go Programming Language] 1장 튜토리얼 - 1.4 애니메이션 GIF