>  기사  >  백엔드 개발  >  이것이 제가 2주 동안 Go에 대해 배운 전부입니다!

이것이 제가 2주 동안 Go에 대해 배운 전부입니다!

Barbara Streisand
Barbara Streisand원래의
2024-10-31 04:27:02690검색

This is all what I

새로운 것을 배워야 할 때 어떻게 접근하시나요? 아주 구체적인 것이 있어서 Golang을 배우면서 다시한번 테스트해봤습니다!

말할 내용이 너무 많지만, 제가 유익하다고 생각하고 특히 시간을 내어 올바르게 배운 내용을 나열하는 것이 목표입니다.

목차

  • 1. 프롤로그
  • 2. CLI를 만나보세요
    • 2.1 CLI: 모드로 이동
    • 2.2 CLI: 실행
  • 3. 다른 구문 비교
    • 3.1 구문: 클래스/구조체 및 API 캡슐화
    • 3.2 구문: 인터페이스 구현은 FUC만큼 이상합니다*
  • 4. Stdlib: 정말 멋진 툴킷입니다.
    • 4.1 패키지: 기본 유형
    • 4.2 패키지: 유용한 정보
  • 5. Go의 테스트는 매우 간단합니다.
    • 5.1 테스트: 기본 테스트
    • 5.2 테스트: Jetbrains 상용구
    • 5.3 테스트: 테스트 실행
  • 6. 순환 수입에 주의하세요
  • 7. 이거 미루고 저거 미루고... 그런데 미루는게 뭐죠?
  • 8. 멍청한 놈들을 위한 오류 관리
  • 9. 결론: 저지연 코딩 챌린지

1. 프롤로그

지난 2주 동안 저는 Golang을 사용하여 작은 애플리케이션을 배우고 구축해 왔습니다. 현재 많은 라이브 스트림을 통해 거의 50시간에 달하는 코드가 작성되었으며 이전에 언어와 관련하여 몇 가지 작은 문제가 있었던 내용을 배울 수 있어서 매우 기뻤습니다.

이 2주간의 여정에서 제가 만든 것은 다음과 같습니다.

  • 작고 정말 단순한 쉘
  • Redis 기본 구현
  • HTTP 1.1 프로토콜 구현
  • DNS 서버 구현
  • 그리고 정말 멋진 회사에 대한 취업 시험(이 기사 마지막 부분에서 확인 가능).

그리고 이 모든 것은 제 상사가 ScyllaDB PoC 및 데모 작업을 위한 새로운 기술을 배우라고 다시 한 번 요청했기 때문입니다... 저는 그 결정에 별로 만족하지 않았지만, 음, 그건 내 일이야.

작년에 저는 Rust를 공부했는데 아직은 너무 복잡할 수도 있지만 Go로 전환하게 된 정말 멋진 개념을 배웠습니다!

이 기사에서는 학습 속도를 높이는 데 도움이 되는 몇 가지 팁과 조언을 제공합니다.

2. CLI를 만나보세요

저는 PHP 개발자이고 지금까지 만들어진 최고의 CLI(예, Artisan입니다)에 익숙합니다. 그러나 개발자로서의 여정을 통해 저는 멋진 프로젝트를 많이 겪었습니다..:

  • 화물(러스트)
  • NPM(JS)
  • 작곡가(PHP)
  • 등...

Go 환경에 들어가보니 진짜 문제가 생기기 시작했습니다. 적어도 나에게는 도구와 문서 측면에서 Golang의 개발자 경험이 훨씬 더 좋을 수 있습니다. 이런 생각을 하다가 처음에 꼭 배워야 할 명령 3개를 먼저 진행하기로 했습니다.

기억하세요: 이것은 사물에 대해 저만의 설명을 포함하는 연습일 뿐입니다. 자세한 정보를 원하시면 문서를 열어보세요 :)
또한: go docs 짜증나는데 누군가 구문 강조 표시를 거기에 넣어주세요

2.1 CLI: 모드로 이동

애플리케이션을 모듈화하려는지 아니면 체계적인 환경을 원하는지에 따라 처음에는 이 명령이 가장 유용한 명령이 될 것입니다.

go mod 명령은 프로젝트 내의 모든 종속성을 관리하고 더 이상 사용되지 않는 항목을 자동으로 제거합니다.

먼저 비어 있는 새 폴더 내에서 go mod init를 사용하여 프로젝트 내의 새 모듈을 초기화해 보겠습니다.

mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

이렇게 하면 프로젝트 루트에 go.mod라는 새 파일이 생성됩니다. 이는 기본적으로 현재 내용입니다.

  • 모듈 이름
  • Go 버전

직접 확인하고 싶다면 파일은 다음과 같습니다.

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

그 후 제가 정말 마음에 들었던 것은 기본적으로 누락된 종속성을 추가하고 사용하지 않는 종속성을 제거하는 go mod tidy였습니다.

go mod tidy

두 번째는 이것이 존재하며 정말 유용하다는 점을 명심하기 위한 것입니다! 아마도 귀하의 환경에서는 항상 이를 실행하고 수입품이 사라지는 것을 보게 될 것입니다 :p

2.2 CLI: 실행

프로젝트를 실행해야 하기 때문에 아마도 가장 일반적으로 사용하게 될 명령일 것입니다. 작동 방식은 다음과 같습니다.

  • main() 함수가 포함된 파일을 가리켜야 합니다.
  • 이 파일이 폴더의 루트에 있을 필요는 없습니다.

이 명령에 대해 기억해야 할 가장 중요한 점은 go run 명령을 실행할 때 현재 디렉터리에서 go.mod 파일을 찾아 전체 프로젝트(가져오기, 패키지) 매핑의 기초로 사용한다는 것입니다. , 등). 다음은 몇 가지 예입니다.

# go run <your-main-file>

# Environment 1
# .
# ├── go.mod
# └── main.go
go run app.go

# Environment 2
# .
# ├── go.mod
# └── src
#     └── main.go
go run src/app.go

app.go 콘텐츠는 다음과 같습니다.

package main

import(
    "fmt"
)

func main () {
    fmt.Println("whats up! don't forget to like this article <3")
}

이제 프로젝트 실행에 대한 기본 사항을 알았습니다! 말 그대로 안녕하세요!

3. 다른 구문 비교:

Go에 대한 내 문제는 항상 작성된 방식이었지만 몇 시간 동안 코딩한 후에 생각보다 간단하다는 것을 깨달았습니다. 짐작하셨겠지만 저는 PHP에 대한 배경 지식이 풍부하고 Rust에 대한 경험도 있습니다.

2023년에 제가 Rust를 배우기 시작했을 때, 다행스럽게도 제가 열렬한 팬인 Nuno Maduro(Laravel)가 "PHP for Rust Developers"라는 강연을 했는데, 이를 통해 기본적인 소개가 되었습니다. 구문을 사용하여 제가 완전히 Rust에 압도당했습니다.

어쨌든 당시에는 나에게 도움이 되었는데, 한번 비교해 보시는 건 어떨까요?

3.1 구문: 클래스/구조체 및 API 캡슐화

OOP에는 코드를 작은 조각으로 추상화하는 정말 멋진 방법인 클래스가 있으며 "그런" 것이 있습니다. Golang은 환경을 원하는 대로 바꾸는 획기적인 개발이 될 수 있기 때문에 오디세이로 볼 수 있습니다.

Golang은 "낮은 수준" 구현으로 쉽게 작업할 수 있는 "시스템 수준" 구문을 제공하는 "고수준 언어"라는 점을 기억하세요.

Go 구문에서 다음을 수행할 수 있습니다.

  • [구조체] 유형 접두사를 붙이고 "클래스/구조체" 이름을 추가한 다음 구조체 접미사를 추가하여 구조체를 정의합니다.
  • [캡슐화] UpperCase 또는 LowerCase 이름으로 시작하여 클래스/구조체 관련 요소의 노출을 정의합니다.
    • [표시 여부: "public"]: 항목 이름을 대문자로 설정합니다.
    • [가시성: "비공개/보호됨"]: 항목 이름을 소문자로 설정합니다.

구조체, 구조체 필드, 구조체 메서드에 사용할 수 있습니다. 자세히 살펴보세요:

mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

Rust에서는 다음과 같은 보다 명확한 접근 방식(언어와 유사)이 있습니다.

  • [Struct] 접두사 struct를 사용하여 구조체를 정의하고 "클래스/구조체" 이름을 추가하면 끝입니다.
  • [캡슐화] 무언가를 다른 "크레이트"에 공개하려면 노출하려는 코드 부분에 pub 접두어를 추가해야 합니다.
# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

PHP, Java 등을 명시적으로 작성하고 싶지만, 생각해보면 LESS CODE 작성해야 하지만 가독성에도 영향을 줍니다.

3.2 구문: 인터페이스 구현은 FUC만큼 이상합니다*

솔직히 저는 Go 환경에 LARAVEL을 넣으려고 하는 편인데, Goravel에서는 이미 그렇게 되어 있었습니다. 어쨌든 저는 "인터페이스/계약 중심 개발"을 사용하여 작업한다는 아이디어가 정말 마음에 들었고 처음으로 언어에서 막혔습니다.

Go에서 인터페이스는 구조/클래스에서 "구현"되지 않으며 저와 같은 OOP 사용자에게는 그러한 디자인 결정이 내 머릿속에 들어맞는다는 것이 정말 미친 일입니다. 예상되는 내용을 살펴보세요.

mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

이제, 구조 내부에 "인터페이스"를 명시적으로 구현하지 않은 경우, 흠... 이상한가요? 대신, Go가 컴파일 타임에 확인하는 인터페이스의 필수 메소드를 구현하기만 하면 됩니다. 이것이 컴파일된 언어이고 결코 문제가 되지 않는다는 것을 아는 것이 공평하지만, 저는 Developer Experience!
에서 제 관점에 대해 이야기하고 있습니다.

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

어쨌든 언어로 코딩하는 데 시간이 좀 걸리면 익숙해질 것입니다. 이제 아무것도 다운로드하지 않고도 기본 환경이 제공하는 기능에 대해 이야기해 보겠습니다!

4. Stdlib: 정말 멋진 툴킷입니다.

이제 타사 패키지를 다운로드하지 않고도 Go가 표준 라이브러리를 통해 제공하는 모든 것에 대해 이야기하고 있습니다. 다음은 연대순 타임라인입니다.

  • 첫째 날: 뭐? 해당 유형이 모든 메소드를 지원한다는 점에서 JS/Java를 좋아하지 않는 이유는 무엇입니까? (그리고 둘 다 싫어요)
  • 첫 번째 주: 잠깐, 어쩌면 그게 좋은지도 (기본 유형에 대한 패키지를 이해한 후)
  • 둘째 주: 뭐? 왜 다른 언어에는 기본적으로 이렇게 좋은 라이브러리가 없나요?

농담이 아닙니다. 매일 탐색하면서 표준 라이브러리 아래에 멋진 라이브러리를 발견했습니다. 그럼 이제 원시 유형에 대해 이야기해 보겠습니다.

4.1 패키지: 기본 유형

PHP와 마찬가지로 다른 많은 언어(Rust, Java, JS 등)와 Golang은 대부분의 관련 유형 작업을 수행하기 위해 "helper" 함수가 필요합니다. . "유용성"이 붙어 있지 않기 때문에 "빈혈" 유형으로 생각할 수 있습니다.

go mod tidy

따라서 "문자열" 유형으로 작업하는 경우 strconv나 문자열과 같은 다른 패키지를 사용하여 이를 조작할 수 있습니다! 하지만 어떤 패키지를 살펴봐야 하는지 절대 잊지 말아야 하는 황금률이 ​​있습니다. 유형이 문자열인 경우 복수형 이름을 가진 동일한 패키지를 찾으세요!

간단히 말하면 []유형 및 유형:

과 관련된 기능을 제공합니다.
  • 문자열 유형 -> 다음과 같은 작업에 대한 가져오기("문자열"): Contains(), Upper(), Split() ...
  • 바이트 유형 -> Include(), Compare(), Split() ...
  • 과 같은 작업의 경우 가져오기("바이트")
  • 등등!

코드를 살펴보고 직접 확인할 수 있습니다.

# go run <your-main-file>

# Environment 1
# .
# ├── go.mod
# └── main.go
go run app.go

# Environment 2
# .
# ├── go.mod
# └── src
#     └── main.go
go run src/app.go

간단해야 하는데 머리에 쏙쏙 들어올 때까지 한동안 고민했어요. 아마도 Laravel과 그 도우미 기능을 너무 오랫동안 사용하다 보니 프레임워크 없이 코딩하는 것이 얼마나 힘든지 잊어버렸을 것입니다. :D

4.2 패키지: 유용한 것들

도구와 프로젝트를 탐색하는 동안 많은 프로젝트에 대해 정말 좋은 소개를 얻었고 각 프로젝트와 내가 사용한 라이브러리를 나열하고 싶습니다.

  • 나만의 쉘 챌린지 만들기:
    • 패키지:
      • fmt: I/O 라이브러리(화면에서 내용 스캔/읽기 및 쓰기)
      • os: 운영 체제와 직접 대화하는 기능 및 도우미
      • strconv: 특정 데이터 유형을 문자열로 변환하거나 문자열을 정의된 유형으로 변환합니다.
  • 나만의 (HTTP|DNS) 서버 구축 챌린지:
    • 패키지:
      • net: HTTP, TCP, UDP 및 Unix 도메인 소켓과 같은 네트워크 I/O 프로토콜을 사용한 통합 레이어
      • [이전 패키지...]
  • 중급숙제?
    • 패키지:
      • 플래그: CLI 인수를 변수로 캡처합니다.
      • log: 애플리케이션에 Log의 채널을 추가합니다
      • crypto/rand: 보안 암호화 무작위 생성기
      • 수학/랜드: 수학 숫자 무작위 생성기
      • 시간: 기간/시간 Lib

다음은 모든 패키지 구현을 확인할 수 있는 스크롤 가능한 보기입니다. 여기에 인용할 수 있는 멋진 표준 패키지가 많이 있습니다.

주의: 코드가 너무 많습니다! :피
(고루틴과 채널 외에) 가장 좋아하는 기능에 대해 댓글을 남기는 것을 잊지 마세요. :p

mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

정말로 정말 놀랍습니다! 그럼 이제 계속해서 테스트를 해보겠습니다.

5. Go의 테스트는 매우 간단합니다.

Go를 사용한 두 번째 프로젝트에서는 요청 및 응답 객체를 생성하면서 테스트를 배울 수 있는 기회를 보았습니다. PHP 환경 내에서는 아마도 PHPUnit 또는 Pest와 같은 타사 라이브러리를 사용하고 있을 것입니다. 오른쪽? Go 환경에서는 쉽습니다! 당신이 해야 할 일은 다음과 같습니다:

  • 패키지 내부에 파일 만들기: person.go에서 테스트하려는 기능을 작성합니다.
  • 패키지에 대한 테스트 파일 만들기 :** person_test.go라는 파일을 만들고 자신만의 테스트 작성을 시작하세요!

패키지 폴더에requests.go와requests_test.go가 있고,requests.go는 다음과 같다고 가정해 보겠습니다.

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

5.1 테스트: 기본 테스트

(t *Testing.T).Errorf()가 테스트 함수 내에서 호출되지 않으면 Go의 테스트는 통과(녹색)로 간주됩니다. 또한 앞서 소개한 것과 동일한 캡슐화 개념을 따릅니다.

  • 테스트 함수 대문자로 시작하는 테스트 실행자가
  • 식별합니다.
  • 테스트 함수 소문자는 무시됩니다(일반적으로 도우미 함수).
mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

자신만의 도우미 기능을 사용하여 테스트할 수 있습니다. 이 테스트에서는 모듈 도메인을 침해하지 않도록 주의하세요!

5.2 테스트: Jetbrains 상용구

저는 Goland를 처음부터 사용해왔기 때문에 대부분의 일이 더 쉬워졌습니다. 그래서 새로운 테스트를 시작할 때마다 기본적으로 병렬(고루틴)로 실행되는 Unity 테스트 구조가 포함된 상용구를 얻습니다.

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

5.3 테스트: 테스트 실행

이제 우리는 Go에서 테스트를 작성하는 것이 얼마나 쉬운 것을 알았습니다. 그렇다면 실행하는 것은 어떨까요? 간단한 작업! 패키지 폴더로 이동하여 다음을 실행하기만 하면 됩니다.

go mod tidy

귀하의 작업에 대한 몇 가지 테스트를 적어주세요. 필요한 것만 분리하면 그리 어렵지 않아요 :p

6. 순환 수입을 조심하세요

지난 몇 년간의 개발 기간 동안 저는 항상 "클린 아치" 또는 "도메인 기반 디자인"에 얽매이지 않고 제 필요에 맞는 방식으로 모든 프로젝트를 모듈화하려고 노력했습니다. . 그러나 처음으로 패키지를 분할하려고 시도했을 때 "Cyclic Import" 오류가 발생하여 다음과 같은 생각이 들었습니다. 내가 그런 것을 본 지 얼마나 됐지?

PHP를 사용하는 2년 동안 특정 흐름에서 동일한 파일을 두 번 가져올 수 없는 가져오기 지옥과 같은 문제에 직면했습니다. 이것은 PSR-4(자동 로딩)(내 PHP 시절을 완전히 바꿔 놓았습니다!!)를 만나기 전이었고 지금은 몇 년 전 Go에서 이 문제로 어려움을 겪고 있습니다.

순환 가져오기 시나리오를 고려해 보겠습니다.

# go run <your-main-file>

# Environment 1
# .
# ├── go.mod
# └── main.go
go run app.go

# Environment 2
# .
# ├── go.mod
# └── src
#     └── main.go
go run src/app.go

Go에서 Cyclic Imports 플래그를 지정하는 항목을 컴파일하려고 하면 다음과 같은 오류가 발생합니다.

package main

import(
    "fmt"
)

func main () {
    fmt.Println("whats up! don't forget to like this article <3")
}

이 순간 이를 방지하려면 종속성/패키지를 분해해야 합니다.

TLDR: 여러 번 로드되는 곳에 동일한 패키지를 가져오지 마세요.

7. 이것을 미루세요, 저것을 미루세요... 그런데, 연기란 무엇인가요?

찾아보진 않았지만 프로그래밍 언어에서 예약어 defer를 본 것은 처음이었습니다. 그리고 "일반 예약어"에 포함되지 않아서 일주일 내내 무시했어요!

그때 내 직장 동료인 두산은 내가 몇 시간 동안 언어로 어려움을 겪는 것을 보고 나에게 Go로 기억 관리 수업을 해주었다. (네, 이건 외침입니다 :p)

중요한 것은: 무언가에 대한 버퍼/연결을 열 때마다 그것을 닫아야 한다는 것입니다! 2014년 메이플스토리 서버(Java) 작업을 할 때 개발자들이 DB와의 연결을 끊지 않아서 가장 많이 발생한 문제가 메모리 누수였던 것으로 기억합니다.

잊어도 괜찮습니다! 그런데 코드리뷰에 합격하면 안 돼요 ㅋㅋ

다음은 Java의 예입니다.

mkdir go-fodase
cd go-fodase

# go mod init <module-name>
go mod init github.com/danielhe4rt/go-fodase

Golang을 코딩하는 동안 항목을 연 후 즉시 닫아야 한다는 것을 기억할 수 있도록 이 지연 속성을 제공합니다.

Defer는 코드의 특정 부분 실행이 끝난 후 리소스를 "정리"하는 방법인 "Deference"를 의미합니다.

# folder: ~/go-fodase
cat go.mod

# module github.com/danielhe4rt/gofodase
# 
# go 1.23.2

한 함수 내에서 많은 연기를 가질 수도 있으며 DEFER ORDER가 중요합니다! database2를 연기한 다음 database1을 연기하면 두 프로세스 모두 동일한 순서로 정리됩니다.

go mod tidy

이것은 프로젝트의 메모리 누수를 방지하는 망하지 않는 정말 간단한 방법입니다. 무엇이든 스트리밍할 때마다 꼭 활용해 보세요.

8. 멍청한 놈들을 위한 오류 관리

처음에 오류 처리는 다음과 같습니다. 사용 중인 함수가 오류 유형을 반환하는지 확인하고 매 빌어먹을 시간마다 유효성을 검사하세요! 제가 말하는 내용의 예는 다음과 같습니다.

# go run <your-main-file>

# Environment 1
# .
# ├── go.mod
# └── main.go
go run app.go

# Environment 2
# .
# ├── go.mod
# └── src
#     └── main.go
go run src/app.go

솔직히 말해서 저는 이 구문이 싫습니다. 그러나 이는 언어의 일부이며 코딩하는 동안 접하게 될 것입니다.

오류가 있는 함수는 오류 또는 (T, 오류)를 반환할 수 있으며 다행히 Go에서는 이를 잊지 않도록 해줍니다.

package main

import(
    "fmt"
)

func main () {
    fmt.Println("whats up! don't forget to like this article <3")
}

err != nil로 코드를 스팸하면 괜찮을 것입니다. 약속합니다! :디

9. 결론: 저지연 코딩 챌린지

환경을 이해하려고 노력하며 스트레스와 시간을 보낸 것 외에도 Twitch 시청자들과 함께 새로운 언어를 배우는 것은 멋진 도전이었습니다. 많은 분들이 오랫동안 저에게 확인해 달라고 요청해 왔고 이렇게 되었습니다.

이 모든 점은 언어에 대한 개인적인 발전 경험을 반영하며, 2주 동안 언어를 공부하면서 겪은 일을 공유하는 것이 목표였습니다.

9.1 보너스: 코딩 챌린지

최근에 저는 팀원으로부터 ScyllaDB 챌린지를 완료하라는 도전을 받았으며 이를 통해 병렬성, 풀 및 속도 제한에 대해 많은 것을 배웠습니다. 이는 많은 기업이 제품 성능을 향상시키기 위해 직면하는 과제입니다!

챌린지의 목표는 요청 수를 제한하면서 ScyllaDB에 임의의 데이터를 삽입하는 작은 Go 명령줄 애플리케이션을 만드는 것입니다.

여기에서 저장소 챌린지를 찾을 수 있습니다: github.com/basementdevs/throttling-requests-scylla-test. 우리는 또한 채용 중입니다! 채용 섹션에서 공석을 찾아보세요!

읽어주셔서 감사합니다! 이 기사가 Golang 학습에 대한 귀중한 통찰력을 제공했기를 바랍니다. 여러분의 생각이나 경험을 자유롭게 공유해 주세요.

위 내용은 이것이 제가 2주 동안 Go에 대해 배운 전부입니다!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.