웹사이트 검색

Go에서 주석을 작성하는 방법


소개

거의 모든 프로그래밍 언어에는 코드에 주석을 추가하는 구문이 있으며 Go도 예외는 아닙니다. 주석은 코드가 어떻게 작동하는지 또는 왜 그렇게 작성되었는지 인간의 언어로 설명하는 프로그램의 줄입니다. 컴파일러는 무시하지만 신중한 프로그래머는 무시하지 않습니다. 주석은 공동 작업자와 미래의 자신이 함정을 피하고 보다 유지 관리 가능한 코드를 작성하는 데 도움이 되는 귀중한 컨텍스트를 추가합니다.

모든 패키지 내의 일반적인 주석은 해당 코드가 수행하는 작업을 수행하는 이유를 설명합니다. 패키지 개발자를 위한 참고 및 경고입니다. 문서 주석은 패키지의 각 구성 요소가 수행하는 작업과 작동 방식을 요약하여 예제 코드와 명령 사용법도 제공합니다. 사용자를 위한 공식 패키지 문서입니다.

이 기사에서는 Go에서 주석이 어떻게 보이는지 뿐만 아니라 전달해야 하는 내용을 설명하기 위해 몇 가지 Go 패키지의 실제 주석을 살펴보겠습니다.

일반 댓글

Go의 주석은 두 개의 슬래시(//)로 시작하고 공백 하나(필수는 아니지만 관용적임)와 주석이 이어집니다. 해당 코드 바로 위 또는 오른쪽에 나타날 수 있습니다. 위의 경우 코드에 맞게 들여쓰기됩니다.

이 Hello World 프로그램에는 자체 라인에 대한 단일 주석이 포함되어 있습니다.

package main

import "fmt"

func main() {
	// Say hi via the console
	fmt.Println("Hello, World!")
}

참고: 코드와 일치하지 않는 주석을 추가하는 경우 Gopher(Go 매니아라고 함)는 Go 코드를 작성하면서 지속적으로 형식을 지정해야 합니다. 확실히 버전 제어에 커밋하기 전에 말입니다. gofmt를 수동으로 실행할 수 있지만(gofmt -w hello.go) 파일을 저장할 때마다 실행하도록 텍스트 편집기 또는 IDE를 구성하는 것이 더 편리합니다.

이 주석은 너무 짧기 때문에 대신 코드 바로 오른쪽에 인라인 주석으로 나타날 수 있습니다.

. . .
	fmt.Println("Hello, World!") // Say hi via the console
. . .

대부분의 주석은 이와 같이 매우 간단하지 않는 한 한 줄에 표시됩니다.

긴 주석은 여러 줄에 걸쳐 있습니다. Go는 /**/ 태그를 사용하여 매우 긴 주석을 열고 닫는 C 스타일 주석 차단을 지원하지만 이들은 특별한 경우에만 사용됩니다. 사례. (나중에 자세히 설명합니다.) 일반적인 여러 줄 주석은 블록 주석 태그를 사용하지 않고 // 로 모든 줄을 시작합니다.

다음은 각 주석이 적절하게 들여쓰기된 많은 주석이 있는 코드입니다. 하나의 여러 줄 주석이 강조 표시됩니다.

package main

import "fmt"

const favColor string = "blue" // Could have chosen any color

func main() {
	var guess string
	// Create an input loop
	for {
		// Ask the user to guess my favorite color
		fmt.Println("Guess my favorite color:")

                // Try to read a line of input from the user.
                // Print out an error and exit, if there is one.
		if _, err := fmt.Scanln(&guess); err != nil {
			fmt.Printf("%s\n", err)
			return
		}

		// Did they guess the correct color?
		if favColor == guess {
			// They guessed it!
			fmt.Printf("%q is my favorite color!\n", favColor)
			return
		}
		// Wrong! Have them guess again.
		fmt.Printf("Sorry, %q is not my favorite color. Guess again.\n", guess)
	}
}

이러한 댓글의 대부분은 실제로 어수선합니다. 이렇게 작고 간단한 프로그램에는 이렇게 많은 주석이 포함되어서는 안 되며 대부분의 주석은 코드 자체가 명백하게 나타내는 내용을 말합니다. Go 구문, 제어 흐름, 데이터 유형 등의 기본 사항을 이해하는 다른 Go 프로그래머를 신뢰할 수 있습니다. 코드가 슬라이스를 반복하거나 두 개의 부동 소수점을 곱한다고 알리는 주석을 작성할 필요가 없습니다.

그러나 이러한 설명 중 하나는 유용합니다.

좋은 댓글은 이유를 설명합니다.

모든 프로그램에서 가장 유용한 주석은 코드가 무엇을 하는지 또는 어떻게 하는지가 아니라 왜 그렇게 하는지를 설명하는 주석입니다. 때로는 이유가 없고 이 인라인 주석이 하는 것처럼 지적하는 것이 유용할 수도 있습니다.

const favColor string = "blue" // Could have chosen any color

이 주석은 코드가 할 수 없는 것을 말합니다. "blue” 값은 프로그래머가 임의로 선택한 것입니다. 즉, // 이것을 자유롭게 변경하십시오.

그러나 대부분의 코드에는 이유가 있습니다. 다음은 정말 유용한 두 가지 주석이 포함된 Go 표준 라이브러리의 net/http 패키지에 있는 함수입니다.

. . .
// refererForURL returns a referer without any authentication info or
// an empty string if lastReq scheme is https and newReq scheme is http.
func refererForURL(lastReq, newReq *url.URL) string {
	// https://tools.ietf.org/html/rfc7231#section-5.5.2
	//   "Clients SHOULD NOT include a Referer header field in a
	//    (non-secure) HTTP request if the referring page was
	//    transferred with a secure protocol."
	if lastReq.Scheme == "https" && newReq.Scheme == "http" {
		return ""
	}
	referer := lastReq.String()
	if lastReq.User != nil {
		// This is not very efficient, but is the best we can
		// do without:
		// - introducing a new method on URL
		// - creating a race condition
		// - copying the URL struct manually, which would cause
		//   maintenance problems down the line
		auth := lastReq.User.String() + "@"
		referer = strings.Replace(referer, auth, "", 1)
	}
	return referer
}
. . .

강조 표시된 첫 번째 주석은 아래 코드가 HTTP 프로토콜의 RFC(공식 사양)를 준수하도록 의도적으로 작성되었기 때문에 관리자에게 아래 코드를 변경하지 말라고 경고합니다. 강조 표시된 두 번째 주석은 아래 코드가 이상적이지 않음을 인정하고 관리자가 코드를 개선할 수 있는 방법을 암시하며 그렇게 하는 것의 위험에 대해 경고합니다.

이런 댓글은 필수입니다. 관리자가 실수로 버그 및 기타 문제를 도입하는 것을 방지하지만 주의를 기울여 새로운 아이디어를 구현하도록 초대할 수도 있습니다.

func 선언 위의 주석도 유용하지만 방식이 다릅니다. 다음에는 그런 종류의 의견을 살펴보겠습니다.

문서 댓글

package, func, const, var와 같은 최상위(들여쓰기가 아닌) 선언 바로 위에 나타나는 주석 , 유형문서 주석이라고 합니다. 패키지의 공식 문서 및 내보낸 모든 이름을 나타내기 때문에 이름이 붙여졌습니다.

참고: Go에서 내보낸은 일부 언어에서 공개가 의미하는 것과 동일한 의미입니다. 내보낸 구성 요소는 다른 패키지가 패키지를 가져올 때 사용할 수 있는 구성 요소입니다. 패키지의 최상위 이름을 내보내려면 대문자만 사용하면 됩니다.

문서 주석은 무엇을 어떻게 설명합니까?

방금 본 일반 주석과 달리 문서 주석은 일반적으로 코드가 수행하는 작업 또는 수행 방법을 설명합니다. 이는 패키지 관리자를 위한 것이 아니라 일반적으로 코드를 읽거나 기여하기를 원하지 않는 사용자를 위한 것이기 때문입니다.

사용자는 일반적으로 다음 세 위치 중 하나에서 문서 주석을 읽습니다.

  1. 로컬 터미널에서 개별 소스 파일 또는 디렉토리에 대해 go doc를 실행합니다.
  2. pkg.go.dev에서 모든 공용 Go 패키지에 대한 문서의 공식 허브입니다.
  3. 비공개로 실행되는 웹 서버에서 godoc 도구를 사용하여 팀에서 호스팅합니다. 이 도구를 사용하면 팀에서 비공개 Go 패키지를 위한 자체 참조 포털을 만들 수 있습니다.

Go 패키지를 개발할 때 내보낸 모든 이름에 대해 문서 주석을 작성해야 합니다. (그리고 DigitalOcean API용 Go 클라이언트 라이브러리인 godo:

// Client manages communication with DigitalOcean V2 API.
type Client struct {

이와 같은 간단한 문서 주석은 불필요해 보일 수 있지만 패키지의 사용 가능한 모든 구성 요소를 포괄적으로 문서화하기 위해 다른 모든 문서 주석과 함께 표시된다는 점을 기억하십시오.

다음은 패키지의 더 긴 문서 주석입니다.

// Do sends an API request and returns the API response. The API response is JSON decoded and stored in the value
// pointed to by v, or returned as an error if an API error has occurred. If v implements the io.Writer interface,
// the raw response will be written to v, without attempting to decode it.
func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Response, error) {
. . .
}

함수에 대한 문서 주석은 매개변수에 대해 예상되는 형식(명확하지 않은 경우)과 함수가 반환하는 데이터의 형식을 명확하게 지정해야 합니다. 또한 기능이 작동하는 방식을 요약할 수도 있습니다.

Do 함수에 대한 문서 주석을 함수 내의 이 주석과 비교하십시오.

	// Ensure the response body is fully read and closed
	// before we reconnect, so that we reuse the same TCPConnection.
	// Close the previous response's body. But read at least some of
	// the body so if it's small the underlying TCP connection will be
	// re-used. No need to check for errors: if it fails, the Transport
	// won't reuse it anyway.

이것은 net/http 패키지에서 본 주석과 같습니다. 이 주석 아래의 코드를 읽는 관리자는 "이것은 왜 오류를 확인하지 않습니까?\라고 궁금해하고 오류 확인을 추가할 수 있습니다. 그러나 주석은 왜 그렇게 할 필요가 없는지 설명합니다. 수준 무엇 또는 어떻게, 문서 주석입니다.

가장 높은 수준의 문서 주석은 패키지 주석입니다. 모든 패키지에는 코드 및/또는 명령 예제를 포함하여 패키지가 무엇이고 패키지를 사용하는 방법에 대한 높은 수준의 개요를 제공하는 하나의 패키지 주석만 포함되어야 합니다. 패키지 주석은 package 선언 위의 모든 소스 파일과 해당 파일에만 나타날 수 있습니다. 종종 패키지 주석은 doc.go라는 자체 파일에 나타납니다.

우리가 살펴본 다른 모든 주석과 달리 패키지 주석은 너무 길 수 있기 때문에 종종 /**/를 사용합니다. 다음은 gofmt에 대한 패키지 주석의 시작 부분입니다.

/*
Gofmt formats Go programs.
It uses tabs for indentation and blanks for alignment.
Alignment assumes that an editor is using a fixed-width font.

Without an explicit path, it processes the standard input. Given a file,
it operates on that file; given a directory, it operates on all .go files in
that directory, recursively. (Files starting with a period are ignored.)
By default, gofmt prints the reformatted sources to standard output.

Usage:

gofmt [flags] [path ...]

The flags are:

-d
Do not print reformatted sources to standard output.
If a file's formatting is different than gofmt's, print diffs
to standard output.
. . .
*/
package main

그렇다면 문서 주석의 형식은 어떻습니까? 그들은 어떤 종류의 구조를 가질 수 있습니까?

문서 주석에는 형식이 있습니다

Go 제작자의 오래된 블로그 게시물에 따르면 다음과 같습니다.

Godoc은 개념적으로 Python의 Docsstring 및 Java의 Javadoc과 관련이 있지만 디자인이 더 간단합니다. godoc이 읽는 주석은 언어 구조(Docstring과 마찬가지로)가 아니며 기계가 읽을 수 있는 자체 구문(Javadoc과 같이)도 없어야 합니다. Godoc 댓글은 좋은 댓글일 뿐이며, godoc이 존재하지 않더라도 읽고 싶은 종류입니다.

문서 주석에는 필수 형식이 없지만 선택적으로 Go 문서에 자세히 설명된 "마크다운의 단순화된 하위 집합\ 형식을 사용할 수 있습니다. 문서 주석에서 단락과 목록으로 작성하고 예제 코드 또는 명령을 다음 형식으로 표시합니다. 들여쓰기 블록, 참조에 대한 링크 제공 등 문서 주석이 이 형식에 따라 잘 구성되면 멋진 웹 페이지로 렌더링될 수 있습니다.

다음은 How To Write Your First Program in Go에서 확장된 Hello World 프로그램 greeting.go에 추가된 몇 가지 설명입니다.

// This is a doc comment for greeting.go.
//  - prompt user for name.
//   - wait for name
//    - print name.
// This is the second paragraph of this doc comment.
// `gofmt` (and `go doc`) will insert a blank line before it.
package main

import (
	"fmt"
	"strings"
)

func main() {
	// This is not a doc comment. Gofmt will NOT format it.
	//  - prompt user for name
	//   - wait for name
	//    - print name
	// This is not a "second paragraph" because this is not a doc comment.
	// It's just more lines to this non-doc comment.
	fmt.Println("Please enter your name.")
	var name string
	fmt.Scanln(&name)
	name = strings.TrimSpace(name)
	fmt.Printf("Hi, %s! I'm Go!", name)
}

package main 위의 주석은 문서 주석입니다. 문서 주석 형식의 단락 및 목록 개념을 사용하려고 시도하고 있지만 옳지 않습니다. gofmt 도구는 이를 형식으로 성형합니다. gofmt greeting.go를 실행하면 다음이 인쇄됩니다.

// This is a doc comment for greeting.go.
//   - prompt user for name.
//   - wait for name.
//   - print name.
//
// This is the second paragraph of this doc comment.
// `gofmt` (and `go doc`) will insert a blank line before it.
package main

import (
	"fmt"
	"strings"
)

func main() {
	// This is not a doc comment. `gofmt` will NOT format it.
	//  - prompt user for name
	//   - wait for name
	//    - print name
	// This is not a "second paragraph" because this is not a doc comment.
	// It's just more lines to this non-doc comment.
	fmt.Println("Please enter your name.")
	var name string
	fmt.Scanln(&name)
	name = strings.TrimSpace(name)
	fmt.Printf("Hi, %s! I'm Go!", name)
}

그것을주의해라:

  1. 이제 문서 주석의 첫 단락에 나열된 항목이 정렬됩니다.
  2. 이제 첫 번째 단락과 두 번째 단락 사이에 빈 줄이 있습니다.
  3. main() 내의 주석은 gofmt가 문서 주석이 아님을 인식했기 때문에 형식이 지정되지 않았습니다. (하지만 앞서 언급한 것처럼 gofmt는 모든 주석을 코드와 동일한 들여쓰기로 정렬합니다.)

go doc greeting.go를 실행하면 문서 주석의 서식을 지정하고 인쇄하지만 main() 내의 주석은 인쇄하지 않습니다.

This is a doc comment for greeting.go.
  - prompt user for name.
  - wait for name.
  - print name.

This is the second paragraph of this doc comment. `gofmt` (and `go doc`) will
insert a blank line before it.

이 문서 주석 형식을 일관되고 적절하게 사용하면 패키지 사용자는 읽기 쉬운 문서에 감사할 것입니다.

문서 주석에 대한 공식 참조 페이지를 읽고 주석을 잘 작성하는 방법에 대한 모든 것을 배우십시오.

코드를 빠르게 비활성화

새로운 코드를 작성하여 애플리케이션 속도를 저하시키거나 더 나쁘게는 모든 것을 망가뜨린 적이 있습니까? 이것은 C 스타일 /**/ 태그를 사용할 때 외에 다른 것입니다. 문제가 있는 코드 앞에 /* 하나를, 뒤에 */ 하나를 배치하여 문제가 있는 코드를 빠르게 비활성화할 수 있습니다. 문제가 있는 코드 주위에 이러한 태그를 감싸서 주석 차단으로 전환합니다. 그런 다음 원인이 된 문제를 해결했으면 두 태그를 제거하여 코드를 다시 활성화할 수 있습니다.

. . .
func main() {
    x := initializeStuff()
    /* This code is causing problems, so we're going to comment it out for now
    someProblematicCode(x)
    */
    fmt.Println("This code is still running!")
}

더 긴 코드 청크의 경우 이러한 태그를 사용하는 것이 문제가 있는 코드의 모든 줄 시작 부분에 //를 추가하는 것보다 훨씬 편리합니다. 관례적으로 일반 주석과 코드에 영구적으로 남아 있는 문서 주석에는 //를 사용하십시오. /**/ 태그는 테스트 중(또는 앞에서 언급한 패키지 주석의 경우)에만 일시적으로만 사용하십시오. 프로그램에 주석 처리된 코드 조각을 오랫동안 두지 마십시오.

결론

모든 Go 프로그램에서 표현적인 주석을 작성하면 다음과 같습니다.

  1. 공동 작업자가 무언가를 깨는 것을 방지합니다.
  2. 코드가 왜 원래 이렇게 쓰여졌는지 가끔 잊어버리는 미래의 자신을 돕는 것.
  3. 패키지 사용자에게 코드를 자세히 살펴보지 않고도 읽을 수 있는 참조를 제공합니다.