Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions the_blank_identifier.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
`for range`루프에서 공백 식별자의 사용은 일반적인 상황에서의 특별한 경우(다중 할당)이다.


만약 좌변에 여려개의 값을 할당해야 하는데, 그 중 하나가 사용되지 않을 경우, 좌변에 공백 식별자를 두면 더미 변수를 생성 해야하는 필요가 없어지고 값 버리기를 깔끔하게 처리할 수 있다. 예를 들면, 하나의 값과 에러를 리턴하는 함수를 호출하는데 오직 에러만이 중요하다면, 무관한 값을 버리기 위해 공백 식별자를 사용한다.
만약 좌변에 여러 개의 값을 할당해야 하는데, 그 중 하나가 사용되지 않을 경우, 좌변에 공백 식별자를 두면 더미 변수를 생성 해야하는 필요가 없어지고 값 버리기를 깔끔하게 처리할 수 있다. 예를 들면, 하나의 값과 에러를 리턴하는 함수를 호출하는데 오직 에러만이 중요하다면, 무관한 값을 버리기 위해 공백 식별자를 사용한다.

```go
if _, err := os.Stat(path); os.IsNotExist(err) {
Expand Down Expand Up @@ -87,7 +87,7 @@ func main() {
## 부수효과(side effect)를 위한 임포트


이전 예시에서 `fmt`나 `io`와 같은 미사용 임포트는 결국 사용되야 하거나 그렇지 않을 경우엔 없애야한다. (공백 할당은 아직 작업이 진행중인 코드로 인식해야 한다.) 그러나 때로는 직접 사용하지는 않으면서, 부수효과를 위해 패키지를 임포트하기도 하는데, 이는 유용한 사례이다. 예를 들면,`net/http/pprof`패키지는 패키지의 초기화 함수를 실행하는 동안 디버깅 정보를 제공하는 HTTP 핸들러를 등록한다. 이는 노출된 API를 가지고 있지만 대다수의 클라어언트는 오직 핸들러 등록만이 필요하고 정보에는 웹페이지를 통해 접근한다. 부수효과만을 위해 이 패키지를 임포트하기 위해선 이 패키지 이름을 공백 식별자로 바꾸면 된다:
이전 예시에서 `fmt`나 `io`와 같은 미사용 임포트는 결국 사용되야 하거나 그렇지 않을 경우엔 없애야한다. (공백 할당은 아직 작업이 진행중인 코드로 인식해야 한다.) 그러나 때로는 직접 사용하지는 않으면서, 부수효과를 위해 패키지를 임포트하기도 하는데, 이는 유용한 사례이다. 예를 들면,`net/http/pprof`패키지는 패키지의 초기화 함수를 실행하는 동안 디버깅 정보를 제공하는 HTTP 핸들러를 등록한다. 이는 노출된 API를 가지고 있지만 대다수의 클라이언트는 오직 핸들러 등록만이 필요하고 정보에는 웹페이지를 통해 접근한다. 부수효과만을 위해 이 패키지를 임포트하기 위해선 이 패키지 이름을 공백 식별자로 바꾸면 된다.

```go
import _ "net/http/pprof"
Expand All @@ -98,7 +98,7 @@ import _ "net/http/pprof"
## 인터페이스 검사


위의 인터페이스에 대한 논의에서 봤듯이, 타입은 인터페이스를 구현했음을 명시적으로 선언할 필요가 없다. 대신에, 타입은 인터페이스의 메서드를 구현함으로써 인터페이스를 구현한다. 실제로 ,대다수의 인터페이스 변환은 정적이며 따라서 컴파일 도중에 검사가 이루어진다. 예를 들면, 만약 `*os.File`이 `io.Reader`인터페이스를 구현하고 있지 않는데 이를 `io.Reader`를 기대하는 함수에 인자로 전달하게 되면 컴파일이 되지 않을 것이다.
위의 인터페이스에 대한 논의에서 봤듯이, 타입은 인터페이스를 구현했음을 명시적으로 선언할 필요가 없다. 대신에, 타입은 인터페이스의 메서드를 구현함으로써 인터페이스를 구현한다. 실제로, 대다수의 인터페이스 변환은 정적이며 따라서 컴파일 도중에 검사가 이루어진다. 예를 들면, 만약 `*os.File`이 `io.Reader`인터페이스를 구현하고 있지 않는데 이를 `io.Reader`를 기대하는 함수에 인자로 전달하게 되면 컴파일이 되지 않을 것이다.


하지만 몇 몇 인터페이스 검사는 런타임때 발생한다. 한 가지 예시는 `Marshaler` 인터페이스를 정의하는 `encoding/json`패키지에 있다. JSON 인코더가 저 인터페이스를 구현한 값을 받을 때, 인코더는 JSON으로 변환을 하기 위해 표준 변환을 진행하는 대신 값의 `marshiling` 메서드를 실행한다. 인코더는 런타임때 다음과 같이 타입 단언을 하면서 프로퍼티를 검사한다.
Expand All @@ -108,11 +108,11 @@ m, ok := val.(json.Marshaler)
```


만약 타입이 인터페이스를 구현했는지 안했는지를 실제 인터페이스 자체를 사용하지 않고, 에러 검사의 일부로서 확인할 필요가 있을 때, 타입 단언된 값을 무시하기 위해 공백 식별자를 사용하라:
만약 타입이 인터페이스를 구현했는지 안했는지를 실제 인터페이스 자체를 사용하지 않고, 에러 검사의 일부로서 확인할 필요가 있을 때, 타입 단언된 값을 무시하기 위해 공백 식별자를 사용하라.

```go
if _, ok := val.(json.Marshaler); ok {
fmt.Printf("value %v of type %T implements json.Marshaler\n", val, val)
fmt.Printf("value %v of type %T implements json.Marshaler\n", val, val)
}
```

Expand Down