>  기사  >  백엔드 개발  >  Go와 함께하는 첫걸음

Go와 함께하는 첫걸음

WBOY
WBOY원래의
2024-08-05 19:28:13398검색

Baby steps with Go

저는 내 경력과 관심 분야에 도움이 될 새로운 언어를 배우기 위해 Go를 시도해 보기로 결정했습니다. 이번에는 Go를 가봤습니다. 첫인상은 꽤 좋은 것 같아요.

이 투어는 가이드 투어가 아니며 개인적인 참고 사항으로 저 이외의 다른 사람을 위해 작성된 것이 아닙니다.

저는 Os-Release-Q라는 작은 프로젝트를 진행했습니다. 내 의도는 내가 관리하는 모든 시스템에 바이너리를 두어 구문 분석이나 시선을 끌 필요 없이 필요한 정보를 정확히 인쇄할 수 있도록 하는 것이었습니다.

첫 번째 장애물: 수입

웹 검색에서는 다른 사람의 패키지를 가져오는 것에 대해 많이 이야기하지만 자신의 코드를 구성하는 것에 대해서는 거의 이야기하지 않습니다. 문서조차도 관심사를 분리하는 것보다 go get에 중점을 둡니다.

각 언어마다 해결 방법과 각 언어가 갖고 있거나 부과하는 제한 사항에 대한 고유한 철학이 있기 때문에 모든 언어에서 이 장애물에 상당히 많이 직면합니다.

기본을 배우기 위해 수행한 모든 활동 중에서 주로 Python을 사용하면서 코드를 여러 파일로 분할하는 것이 답변을 얻는 데 가장 오랜 시간이 걸렸습니다. 정리해보면 다음과 같은 내용을 발견했습니다.

  • 최상위 수준에는 module-name 모듈을 선언하는 go.mod가 필요합니다.
  • 그런 다음 최상위 레벨에 src/ 디렉토리를 설정하고, 상단에 패키지 메인 선언을 사용하여 메인 함수를 배치할 src/main.go를 설정할 수 있습니다
  • 다른 파일에 코드를 넣는 것은 패키지 메인 선언으로 src/others.go 같은 파일을 생성하면 간단합니다.
  • 모든 함수와 변수는 main 패키지의 다른 파일에서 직접 사용할 수 있지만 go build FILES 호출 시 해당 파일을 명시적으로 지정해야 합니다

로컬 하위 모듈의 경우 하위 모듈이 폴더에 있어야 합니다. 패키지 하위 모듈 이름을 선언할 수 있습니다.

src/submod/에 있고 src/submod/submod.go에 주요 구현자가 있다고 가정해 보겠습니다. main.go에서는 "module-name/src/submod"(go.mod에서 모듈 이름을 가져옴)를 가져옵니다. 그런 다음 submod.SomeFunction()을 호출할 수 있습니다.

하위 모듈 기능은 이름이 대문자로 시작하는 경우에만 수입업체가 사용할 수 있습니다. 따라서 submod.myFunction()을 수행하지 마세요. submod.MyFunction()이어야 합니다.

하위 모듈 및 가져오기와 관련하여 고려해야 할 다른 사항이 분명히 있지만 코드를 체계적으로 정리하고 분리하는 한 이것이 핵심입니다.

정상적인 상태를 유지하기 위해 패키지 메인을 선언하는 파일 하나만 갖고 나머지는 하위 모듈로 분리하려고 했습니다. 이러한 파일은 Go Build FILES 파일 목록에서 선언할 필요 없이 자동으로 가져옵니다.

기본 작업 수행

이러한 Go의 특수성을 해결한 후 나머지는 아주 쉽게 자리를 잡았습니다. 모든 기본 작업에는 물론 StackOverflow 항목이나 GoByExample.com 페이지가 있었고 더 기본적으로는 Go 언어 참조가 있었습니다.

  • 문자열 처리는 strings 패키지를 통해 수행됩니다
  • 배열 처리에는 base_array = 추가(base_array, item1, item2) 패턴을 포함한 여러 기본 함수가 있습니다. 또한 추가(base, other_array...)를 통해 다른 값으로 배열을 확장하는 데에도 작동합니다.
  • 오류 처리는 일반적으로 오류 개체를 전달하여 수행되지만 반드시 그런 것은 아닙니다.
  • 미리 구성된 편리한 no-faffing 로그를 위한 "로그" lib가 존재합니다. 여기에는 오류를 기록하고 즉시 종료하는 log.Fatal(message) 호출이 포함되어 있습니다.
  • exec.Command(base, args...) 패턴을 사용하여 "os/exec" 라이브러리를 통해 하위 프로세스를 쉽게 호출할 수 있습니다

특히 일반적인 두 가지 작업에는 별도의 단락이 필요합니다.

오류 처리

기본적인 오류 처리는 문자 그대로 제어 흐름 중에 오류를 처리해야 하기 때문에 번거롭다고 평가되는 경우가 많습니다. 이는 try/catch 워크플로에서 오는 프로그래머에게는 혐오스러울 수 있지만 문제가 발생할 수 있는 지점에서 문제를 처리하는 것은 그리 나쁘지 않습니다.

// explicit return item `err` forces us to be aware of it
// but having the ability to check it in the same breath is not so bad
if result, err := someCall(); err != nil {
    log.Fatal("Sorry.")
}

// Equally valid is
/*
result, err := someCall()
if err != nil {
    log.Fatal("Sorry")
}
*/

fmt.Println(result)

try/catch 방식 비교

try:
    result = someCall()
    print(result)
except:
    print("Sorry") # a little divorced from potential origin of error
    sys.exit(1)

인수 구문 분석

플래그 라이브러리 구현이 다소 설익었다는 느낌을 지울 수 없습니다. 현재 형태로 생존한다는 점을 고려하면 사람들은 이에 익숙하고 괜찮다는 것이 분명합니다.

프로그램 -flag arg1 arg2를 호출하면 플래그가 수행되도록 설정된 토글이 제공되고 positionals := flags.Args()는 ["arg1", "arg2"] 배열을 반환합니다.

그러나 arg1 arg2 -flag 호출 프로그램은 -flags가 수행해야 하는 모든 작업을 전환하지 않고 대신 위치를 ["arg1", "arg2", "-flag"]로 제공합니다. 구문 분석되지 않았습니다.

이는 ls -l이 문자 그대로 전달되는 프로그램 colorize ls -l과 같은 하위 호출을 전달하는 데 유용할 수 있으므로 사용 사례를 볼 수 있습니다.

단지 대부분의 프로그램은 위치 항목 주변 어디에서나 플래그 인수를 허용합니다. ls dir1/ -l dir2/는 ls -l dir1/dir2/와 동일하며 이는 대부분의 Unix 및 Linux 명령에 적용되는 규칙입니다.

이것은 익숙해져야 할 부분이고 언급할 가치가 있는 부분일 수도 있습니다.

Go의 목적과 활용 사례

파일 가져오기 패러다임을 제외하면 기본 애플리케이션을 구현하는 것이 꽤 쉽다는 것을 알았습니다. 내가 잘못한 것은 무엇이든 상당히 명백했고 오류는 의미가 있었습니다. 정말 '일을 끝내는 것'에만 집중할 수 있는 것 같아요.

지금까지의 사용량이 매우 적고 특정 요구 사항을 고려하여 알 수 있습니다.

  • 시작하기 쉬움
  • 컴파일된 바이너리, 런타임 종속성 없음
  • 유형이 있는 간단한 언어는 쉘 스크립팅보다 한 단계 더 발전한 언어입니다
  • 간편한 다중 처리 지원

객체와 상속 대신 희소 유형을 갖는 것이 방해가 될 것이라고 생각했지만 지금까지는 그럭저럭 괜찮습니다. 다른 언어에서는 그것들 없이도 지내기 때문에 인터페이스와 유형을 정의하게 되면 Lua와 bash보다 한 단계 더 발전된 것처럼 느껴질 것입니다. 바랍니다.

내가 네이티브 언어로 컴파일된 언어를 탐구하고 싶었던 이유 중 하나는 존재하는 런타임의 특정 버전에 의존할 필요 없이 쉽게 우회할 수 있는 바이너리를 생성할 수 있기 위해서였습니다.

최근 한 동료가 Debian 10을 기반으로 한 이전 Node 기본 이미지에 Java 17을 적용하는 문제를 해결하려고 실망한 채 내 책상으로 다가왔습니다. 새로운 기본 이미지를 얻기 위해 Node 버전을 업그레이드해야 하거나, 새로운 Debian 기본 이미지를 사용하고 Node를 수동으로 설치 및 구성하거나, 인터넷에서 goodness-knows-who가 호스팅하는 사용자 정의 저장소를 검색해야 합니다. -해킹된 경우 Debian 10에서 실행되는 Java 17.

배포된 소프트웨어에 런타임 종속성 충돌이 없다면 얼마나 쉬울까요...

운영 관점에서 제가 느낄 수 있는 큰 이점 중 하나는 쉽게 코드를 작성하고 ELF 바이너리를 구축하여 "임의 시스템 X"에 배포할 수 있다는 것입니다. 특정 런타임의 올바른 버전이 있는지 확인하고 충돌하는 종속성을 관리합니다.

다른 이점도 있을 것이라고 확신합니다. Go에서 멀티스레딩과 멀티프로세싱을 사용하기 쉽다는 이야기를 많이 들었습니다. 다음 단계로 이를 탐구하기 위한 미니 프로젝트를 만들 계획입니다. 아마도 여러 채널의 입력을 수신하고 이에 대한 응답으로 몇 가지 기본 작업을 수행할 수 있을 것입니다. 이전에 수행했던 일부 테스트 자동화 작업에서 이에 대한 사용 사례가 있었으므로 현재로서는 이 문제가 낯설지 않습니다.

위 내용은 Go와 함께하는 첫걸음의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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