Go 1.17 소개
최신 Go 릴리스인 버전 1.17은 Go 1.16 이후 6개월 후에 출시됩니다. 대부분의 변경 사항은 도구 체인, 런타임 및 라이브러리의 구현에 있습니다. 항상 그렇듯이 릴리스는 호환성에 대한 Go 1 약속을 유지합니다. 우리는 거의 모든 Go 프로그램이 계속해서 이전과 같이 컴파일 및 실행될 것으로 기대합니다.
언어 변경 부분
Go 1.17에는 언어에 대한 세 가지 작은 개선 사항이 포함되어 있습니다.
- 슬라이스에서 배열 포인터로의 변환: []T 유형의 표현식 s는 이제 배열 포인터 유형 *[N]T로 변환될 수 있습니다. a가 이러한 변환의 결과이면 범위에 있는 해당 인덱스는 동일한 기본 요소를 참조합니다. &a[i] == &s[i] for 0 <= i < N. len(s) N보다 작습니다.
- unsafe.Add: unsafe.Add(ptr, len)은 len을 ptr에 추가하고 업데이트된 포인터를 반환합다.
unsafe.Pointer(uintptr(ptr) + uintptr(len)). - unsafe.Slice: *T 유형의 표현식 ptr의 경우 unsafe.Slice(ptr, len)은 기본 배열이 ptr에서 시작하고 길이와 용량이 len인 유형 []T의 슬라이스를 반환합니다.
unsafe.Pointer의 안전 규칙을 준수하는 코드 작성을 단순화하기 위해 패키지 unsafe 개선 사항이 추가되었지만 규칙은 변경되지 않았습니다. 특히 unsafe.Pointer를 올바르게 사용하는 기존 프로그램은 계속 유효하며 새 프로그램은 unsafe.Add 또는 unsafe.Slice를 사용할 때 규칙을 따라야 합니다.
슬라이스에서 배열 포인터로의 새로운 변환은 런타임에 형식 변환이 패닉할 수 있는 첫 번째 경우입니다. 유형 변환이 결코 패닉 상태가 될 수 없다고 가정하는 분석 도구는 이러한 가능성을 고려하도록 업데이트되어야 합니다.
Ports
Darwin
Go 1.16 릴리스 노트에서 발표된 것처럼 Go 1.17에는 macOS 10.13 High Sierra 이상이 필요합니다. 이전 버전에 대한 지원이 중단되었습니다.
Windows
Go 1.17은 Windows(windows/arm64 포트)에서 64비트 ARM 아키텍처 지원을 추가합니다. 이 포트는 cgo를 지원합니다.
OpenBSD
OpenBSD(openbsd/mips64 포트)의 64비트 MIPS 아키텍처는 이제 cgo를 지원합니다.
Go 1.16에서 OpenBSD(openbsd/amd64 및 openbsd/arm64 포트)의 64비트 x86 및 64비트 ARM 아키텍처에서 시스템 호출은 기계 명령어를 직접 사용하는 대신 libc를 통해 이루어집니다. Go 1.17에서 이것은 OpenBSD(openbsd/386 및 openbsd/arm 포트)의 32비트 x86 및 32비트 ARM 아키텍처에서도 수행됩니다. 이것은 비정적 Go 바이너리에 대해 libc를 통해 시스템 호출이 이루어져야 하는 OpenBSD 6.9 이상과의 호환성을 보장합니다.
ARM64
이제 Go 프로그램은 모든 운영 체제의 64비트 ARM 아키텍처에서 스택 프레임 포인터를 유지 관리합니다. 이전에는 스택 프레임 포인터가 Linux, macOS 및 iOS에서만 활성화되었습니다.
loong64 GOARCH 값 예약됨
기본 Go 컴파일러는 아직 LoongArch 아키텍처를 지원하지 않지만 GOARCH 값 "loong64"를 예약했습니다. 즉, *_loong64.go라는 Go 파일은 이제 해당 GOARCH 값이 사용되는 경우를 제외하고 Go 도구에서 무시됩니다.
도구들
Go 명령어
go 1.17 모듈의 정리된 모듈 그래프
모듈이 go 1.17 이상을 지정하면 모듈 그래프에는 다른 go 1.17 모듈의 즉각적인 종속성만 포함되며 전체 전이 종속성은 포함되지 않습니다. (자세한 내용은 모듈 그래프 정리를 참조하십시오.)
go 명령이 제거된 모듈 그래프를 사용하여 전이 가져오기를 올바르게 해결하려면 각 모듈의 go.mod 파일에 해당 모듈과 관련된 전이 종속성에 대한 자세한 정보가 포함되어야 합니다. 모듈이 go.mod 파일에서 go 1.17 이상을 지정하면 이제 go.mod 파일에 전이적으로 가져온 패키지를 제공하는 모든 모듈에 대한 명시적 require 지시문이 포함됩니다. (이전 버전에서 go.mod 파일은 일반적으로 직접 가져온 패키지에 대한 명시적 요구 사항만 포함했습니다.)
모듈 그래프 프루닝에 필요한 확장된 go.mod 파일에는 메인 모듈에 있는 모든 패키지의 가져오기를 로드하는 데 필요한 모든 종속성이 포함되어 있기 때문에, 메인 모듈이 go 1.17 이상을 지정하면 go 도구는 더 이상 읽거나 다운로드하지 않습니다. 요청된 명령을 완료하는 데 필요하지 않은 경우 종속성을 위한 go.mod 파일. (지연 로딩 참조)
확장된 Go 1.17 go.mod 파일에서 명시적 요구 사항의 수가 훨씬 더 많을 수 있으므로 go 1.17 모듈의 간접 종속성에 대해 새로 추가된 요구 사항은 직접 종속성을 포함하는 블록과 별도의 require 블록에서 유지됩니다.
Go 1.17 프루닝된 모듈 그래프로의 업그레이드를 용이하게 하기 위해 go mod kid 하위 명령은 이제 -go 플래그를 지원하여 go.mod 파일에서 go 버전을 설정하거나 변경합니다. 종속성의 선택한 버전을 변경하지 않고 기존 모듈의 go.mod 파일을 Go 1.17로 변환하려면 다음을 실행하세요.
go mod tidy -go=1.17
기본적으로 go mod tint는 기본 모듈과 관련된 종속성의 선택된 버전이 이전 Go 릴리스(go 1.17을 지정하는 모듈의 경우 Go 1.16)에서 사용되는 것과 동일한 버전인지 확인하고 go.sum 항목을 유지합니다. 일반적으로 다른 명령에 필요하지 않은 종속성에 대해서도 해당 릴리스에 필요합니다.
-compat 플래그를 사용하면 go.mod 파일의 go 지시문에 지정된 버전까지 이전(또는 최신) 버전을 지원하도록 해당 버전을 재정의할 수 있습니다. Go 1.16에 대한 체크섬을 저장하지 않고 Go 1.17에 대해서만 go 1.17 모듈을 정리하려면:
go mod tidy -compat=1.17
기본 모듈이 -compat=1.17로 정리되더라도 go 1.16 또는 이전 모듈의 모듈이 필요한 사용자는 패키지가 호환되는 언어 및 라이브러리 기능만 사용하는 경우 계속 사용할 수 있습니다.
go mod graph 하위 명령은 또한 -go 플래그를 지원하여 표시된 Go 버전에 표시된 대로 그래프를 보고하도록 하여 그렇지 않으면 제거될 수 있는 종속성을 보여줍니다.
모듈 비추천 주석
모듈 작성자는 // Deprecated: 주석을 go.mod에 추가한 다음 새 버전에 태그를 지정하여 모듈을 더 이상 사용하지 않을 수 있습니다. go get now는 명령줄에 명명된 패키지를 빌드하는 데 필요한 모듈이 더 이상 사용되지 않는 경우 경고를 인쇄합니다.
go list -m -u 모든 종속성에 대한 사용 중단을 인쇄합니다(전체 메시지를 표시하려면 -f 또는 -json 사용). go 명령은 서로 다른 주요 버전을 별개의 모듈로 간주하므로 이 메커니즘을 사용하여 예를 들어 사용자에게 새 주요 버전에 대한 마이그레이션 지침을 제공할 수 있습니다.
go get
go get -insecure 플래그는 더 이상 사용되지 않으며 제거되었습니다. 종속성을 가져올 때 안전하지 않은 체계의 사용을 허용하려면 GOINSECURE 환경 변수를 사용하세요. -insecure 플래그는 또한 모듈 합계 유효성 검사를 우회합니다. 해당 기능이 필요한 경우 GOPRIVATE 또는 GONOSUMDB를 사용하십시오. 자세한 내용은 go help 환경을 참조하세요.
go get은 주 모듈 외부에 명령을 설치할 때 사용 중단 경고를 인쇄합니다(-d 플래그 제외). go install cmd@version 대신 @latest 또는 @v1.2.3과 같은 접미사를 사용하여 특정 버전에 명령을 설치해야 합니다. Go 1.18에서는 -d 플래그가 항상 활성화되고 go get은 go.mod의 종속성을 변경하는 데만 사용됩니다.
go.mod 파일에 go 지시문이 없습니다.
기본 모듈의 go.mod 파일에 go 지시문이 포함되어 있지 않고 go 명령이 go.mod 파일을 업데이트할 수 없는 경우 go 명령은 이제 현재 릴리스 대신 go 1.11을 가정합니다. (go mod init은 Go 1.12부터 자동으로 go 지시자를 추가했습니다.)
모듈 종속성에 명시적 go.mod 파일이 없거나 해당 go.mod 파일에 go 지시문이 포함되지 않은 경우 go 명령은 이제 현재 릴리스 대신 해당 종속성에 대해 go 1.16을 가정합니다. (GOPATH 모드에서 개발된 종속성은 go.mod 파일이 부족할 수 있으며 vendor/modules.txt는 현재까지 종속성의 go.mod 파일에 표시된 go 버전을 기록하지 않았습니다.)
공급업체 내용
기본 모듈이 go 1.17 이상을 지정하는 경우 go mod 공급업체는 이제 자체 go.mod 파일에서 각 공급업체 모듈이 표시한 go 버전으로 vendor/modules.txt에 주석을 추가합니다. 주석이 달린 버전은 공급업체 소스 코드에서 모듈의 패키지를 빌드할 때 사용됩니다.
기본 모듈이 go 1.17 이상을 지정하는 경우 go mod vendor는 공급업체 종속성에 대해 go.mod 및 go.sum 파일을 생략합니다. 그렇지 않으면 공급업체 트리 내에서 호출될 때 올바른 모듈 루트를 식별하는 go 명령의 기능을 방해할 수 있습니다.
비밀번호 프롬프트
기본적으로 go 명령은 SSH를 사용하여 Git 리포지토리를 가져올 때 SSH 비밀번호 프롬프트와 Git 자격 증명 관리자 프롬프트를 표시하지 않습니다. 이전에 다른 Git 비밀번호 프롬프트에서 그랬던 것처럼요. 암호로 보호된 SSH를 사용하여 비공개 Git 저장소에 인증하는 사용자는 go 명령이 암호로 보호된 SSH 키를 사용할 수 있도록 ssh-agent를 구성할 수 있습니다.
go mod download
go mod download가 인수 없이 호출되면 다운로드한 모듈 콘텐츠의 합계를 go.sum에 더 이상 저장하지 않습니다. 빌드 목록을 로드하는 데 필요한 go.mod 및 go.sum을 계속 변경할 수 있습니다. 이것은 Go 1.15의 동작과 동일합니다. 모든 모듈의 합계를 저장하려면 go mod download all을 사용하십시오.
//go:build lines
go 명령은 이제 //go:build 라인을 이해하고 // +build 라인보다 선호합니다. 새 구문은 Go와 마찬가지로 부울 표현식을 사용하며 오류가 발생하기 쉽습니다. 이 릴리스부터 새 구문이 완전히 지원되며 모든 Go 파일은 동일한 의미의 두 형식을 갖도록 업데이트해야 합니다. 마이그레이션을 돕기 위해 gofmt는 이제 두 양식을 자동으로 동기화합니다. 구문 및 마이그레이션 계획에 대한 자세한 내용은 https://golang.org/design/draft-gobuild를 참조하세요.
go run
이제 go run은 버전 접미사가 있는 인수를 허용합니다(예: go run example.com/cmd@v1.0.0). 이렇게 하면 현재 디렉토리 또는 상위 디렉토리(있는 경우)에 있는 go.mod 파일을 무시하고 모듈 인식 모드에서 패키지를 빌드하고 실행하기 위해 go run이 실행됩니다. 이것은 실행 파일을 설치하지 않거나 현재 모듈의 종속성을 변경하지 않고 실행하는 데 유용합니다.
Go fmt
gofmt(및 go fmt)는 이제 //go:build 라인을 // +build 라인과 동기화합니다. 파일에 // +build 행만 있는 경우 파일의 적절한 위치로 이동되고 일치하는 //go:build 행이 추가됩니다. 그렇지 않으면 // +build 라인은 기존 //go:build 라인을 기반으로 덮어씁니다. 자세한 내용은 https://golang.org/design/draft-gobuild를 참조하세요.
Vet
일치하지 않는 //go:build 및 // +build 라인에 대한 새로운 경고
Vet 도구는 이제 //go:build 및 // +build 행이 파일의 올바른 부분에 있고 서로 동기화되었는지 확인합니다. 그렇지 않은 경우 gofmt를 사용하여 수정할 수 있습니다. 자세한 내용은 https://golang.org/design/draft-gobuild를 참조하세요.
신호 호출에 대한 새로운 경고. 버퍼링되지 않은 채널에 알림
Vet 도구는 이제 신호 호출에 대해 경고합니다. 수신 신호가 버퍼링되지 않은 채널로 전송되는 알림. 버퍼링되지 않은 채널을 사용하면 신호로 전송된 신호가 누락될 위험이 있습니다. 채널에 보낼 때 알림이 차단되지 않습니다. 예를 들어:
c := make(chan os.Signal)
// signals are sent on c before the channel is read from.
// This signal may be dropped as c is unbuffered.
signal.Notify(c, os.Interrupt)
signal.Notify의 사용자는 예상 신호 속도를 유지하기 위해 충분한 버퍼 공간이 있는 채널을 사용해야 합니다.
Is, As 및 Unwrap 메서드에 대한 새로운 경고
Vet 도구는 이제 오류 패키지에서 예상한 것과 다른 서명을 가진 오류 인터페이스를 구현하는 유형에 대해 As, Is 또는 Unwrap이라는 메서드에 대해 경고합니다. errors.{As,Is,Unwrap} 함수는 이러한 메서드가 각각 Is(error) bool, As(interface{}) bool 또는 Unwrap() 오류를 구현할 것으로 예상합니다. errors.{As,Is,Unwrap} 함수는 이름은 같지만 서명이 다른 메서드는 무시합니다.
예를 들어:
type MyError struct { hint string }
func (m MyError) Error() string { ... } // MyError implements error.
func (MyError) Is(target interface{}) bool { ... } // target is interface{} instead of error.
func Foo() bool {
x, y := MyError{"A"}, MyError{"B"}
return errors.Is(x, y) // returns false as x != y and MyError does not have an `Is(error) bool` function.
}
Cover
커버 도구는 이제 golang.org/x/tools/cover의 최적화된 파서를 사용하며, 이는 대규모 커버리지 프로필을 구문 분석할 때 눈에 띄게 빨라질 수 있습니다.
Compiler
Go 1.17은 스택 대신 레지스터를 사용하여 함수 인수와 결과를 전달하는 새로운 방법을 구현합니다. Go 패키지 및 프로그램의 대표적인 세트에 대한 벤치마크는 약 5%의 성능 향상과 약 2%의 일반적인 바이너리 크기 감소를 보여줍니다. 이것은 현재 64비트 x86 아키텍처(linux/amd64, darwin/amd64 및 windows/amd64 포트)의 Linux, macOS 및 Windows에 대해 활성화되어 있습니다.
이 변경 사항은 안전한 Go 코드의 기능에 영향을 주지 않으며 대부분의 어셈블리 코드에 영향을 주지 않도록 설계되었습니다. 함수 인수에 액세스할 때 unsafe.Pointer 규칙을 위반하거나 함수 코드 포인터 비교와 관련된 문서화되지 않은 동작에 의존하는 코드에 영향을 미칠 수 있습니다. 기존 어셈블리 함수와의 호환성을 유지하기 위해 컴파일러는 새로운 레지스터 기반 호출 규칙과 이전 스택 기반 호출 규칙 간에 변환하는 어댑터 함수를 생성합니다. 이러한 어댑터는 일반적으로 어셈블리 코드에서 Go 함수의 주소를 가져오거나 Reflect.ValueOf(fn).Pointer() 또는 unsafe.Pointer를 사용하여 Go 코드에서 어셈블리 함수의 주소를 가져오는 것을 제외하고 사용자에게 보이지 않습니다. 어댑터의 주소. 이러한 코드 포인터의 값에 의존하는 코드는 더 이상 예상대로 작동하지 않을 수 있습니다. 어댑터는 또한 두 가지 경우에 매우 작은 성능 오버헤드를 유발할 수 있습니다. func 값을 통해 Go에서 간접적으로 어셈블리 함수를 호출하고 어셈블리에서 Go 함수를 호출합니다.
런타임의 스택 추적 형식(캐치되지 않은 패닉이 발생하거나 runtime.Stack이 호출될 때 인쇄됨)이 개선되었습니다. 이전에는 함수 인수가 메모리 레이아웃을 기반으로 하는 16진수 단어로 인쇄되었습니다. 이제 소스 코드의 각 인수가 쉼표로 구분되어 별도로 인쇄됩니다. 집계 형식(구조체, 배열, 문자열, 슬라이스, 인터페이스 및 복합) 인수는 중괄호로 구분됩니다. 주의할 점은 레지스터에만 있고 메모리에 저장되지 않는 인수 값이 정확하지 않을 수 있다는 것입니다. 일반적으로 정확하지 않은 함수 반환 값은 더 이상 인쇄되지 않습니다.
클로저를 포함하는 함수는 이제 인라인될 수 있습니다. 이 변경의 한 가지 효과는 클로저가 있는 함수가 함수가 인라인된 각 위치에 대해 별개의 클로저 코드 포인터를 생성할 수 있다는 것입니다. Go 함수 값은 직접 비교할 수 없지만 이 변경으로 인해 이 언어 제한을 우회하고 코드 포인터로 함수를 비교하기 위해 반사 또는 안전하지 않은 포인터를 사용하는 코드의 버그가 드러날 수 있습니다.
Linker
링커가 cgo를 사용하는 프로그램을 링크할 때 기본값인 외부 링크 모드를 사용하고 링커가 -I 옵션으로 호출되면 옵션은 이제 외부 링커에 -Wl,--dynamic-linker option.
Core library
Cgo
런타임/cgo 패키지는 이제 모든 Go 값을 C와 Go 간에 안전하게 전달하는 데 사용할 수 있는 안전한 표현으로 전환할 수 있는 새로운 기능을 제공합니다. 자세한 내용은 runtime/cgo.Handle을 참조하세요.
URL 쿼리 파싱
";"를 수락하는 데 사용되는 net/url 및 net/http 패키지 (세미콜론) "&"(앰퍼샌드) 외에 URL 쿼리의 설정 구분 기호로 사용됩니다. 이제 백분율로 인코딩되지 않은 세미콜론이 있는 설정은 거부되고 net/http 서버는 요청 URL에서 경고를 발견하면 Server.ErrorLog에 경고를 기록합니다.
예를 들어 Go 1.17 이전에는 URL example?a=1;b=2&c=3의 Query 메소드가 map[a:[1] b:[2] c:[3]]을 반환했지만 이제는 map을 반환합니다. [c:[3]].
이러한 쿼리 문자열이 발생하면 URL.Query 및 Request.FormValue는 세미콜론이 포함된 모든 설정을 무시하고 ParseQuery는 나머지 설정과 오류를 반환하고 Request.ParseForm 및 Request.ParseMultipartForm은 오류를 반환하지만 여전히 다음을 기반으로 요청 필드를 설정합니다. 나머지 설정.
net/http 사용자는 새로운 AllowQuerySemicolons 처리기 래퍼를 사용하여 원래 동작을 복원할 수 있습니다. 이렇게 하면 ErrorLog 경고도 표시되지 않습니다. 다른 시스템에서 캐시 키를 다르게 해석하는 경우 쿼리 구분 기호로 세미콜론을 허용하면 보안 문제가 발생할 수 있습니다. 자세한 내용은 issue 25192를 참조하세요.
TLS 엄격한 ALPN
Config.NextProtos가 설정되면 이제 서버는 구성된 프로토콜과 클라이언트가 보급한 ALPN 프로토콜(있는 경우) 간에 중복이 존재하도록 합니다. 상호 지원되는 프로토콜이 없으면 RFC 7301에서 요구하는 대로 no_application_protocol 경고와 함께 연결이 닫힙니다. 이는 ALPCA 프로토콜 간 공격을 완화하는 데 도움이 됩니다.
예외적으로 "h2" 값이 서버의 Config.NextProtos에 포함될 때 HTTP/1.1 클라이언트는 ALPN을 지원하지 않는 것처럼 연결할 수 있습니다. 자세한 내용은 issue 46310을 참조하십시오.
라이브러리에 대한 사소한 변경
항상 그렇듯이 Go 1 호환성 약속을 염두에 두고 라이브러리에 다양한 사소한 변경 및 업데이트가 있습니다.
새로운 메소드 File.OpenRaw, Writer.CreateRaw, Writer.Copy는 성능이 주요 관심사인 경우를 지원합니다.
Writer.WriteRune 메서드는 이제 다른 잘못된 룬과 마찬가지로 음수 룬 값에 대해 대체 문자 U+FFFD를 씁니다.
Buffer.WriteRune 메서드는 이제 다른 잘못된 룬과 마찬가지로 음수 룬 값에 대해 대체 문자 U+FFFD를 씁니다.
NewReader 함수는 새 형식 Reader의 값을 반환하도록 보장되며 마찬가지로 NewWriter는 새 형식 Writer의 값을 반환하도록 보장됩니다. 이러한 새로운 유형은 모두 Reader 또는 Writer의 재사용을 허용하는 Reset 메서드(Reader.Reset, Writer.Reset)를 구현합니다.
crypto/ed25519 패키지가 다시 작성되었으며 모든 작업은 이제 amd64 및 arm64에서 약 두 배 빠릅니다.
관찰 가능한 동작은 달리 변경되지 않았습니다.
CurveParams 메서드는 이제 가능한 경우 알려진 곡선(P-224, P-256 및 P-521)에 대한 더 빠르고 안전한 전용 구현을 자동으로 호출합니다. 이것은 최선의 접근 방식이며 애플리케이션은 일정 시간 CurveParams 메서드가 아닌 일반 메서드를 사용하는 것을 피하고 대신 P256과 같은 전용 Curve 구현을 사용해야 합니다.
P521 곡선 구현은 공식적으로 검증된 산술 연산 모델을 기반으로 하는 fiat-crypto 프로젝트에서 생성된 코드를 사용하여 다시 작성되었습니다. 이제 amd64 및 arm64에서 일정 시간 및 3배 더 빠릅니다. 관찰 가능한 동작은 달리 변경되지 않았습니다.
crypto/rand 패키지는 이제 macOS에서 getentropy syscall을 사용하고 Solaris, Illumos 및 DragonFlyBSD에서 getrandom syscall을 사용합니다.
새로운 Conn.HandshakeContext 메서드를 사용하면 진행 중인 TLS 핸드셰이크의 취소를 제어할 수 있습니다. 제공된 컨텍스트는 새로운 ClientHelloInfo.Context 및 CertificateRequestInfo.Context 메서드를 통해 다양한 콜백에서 액세스할 수 있습니다. 핸드셰이크가 완료된 후 컨텍스트를 취소해도 효과가 없습니다.
암호 제품군 주문은 이제 crypto/tls 패키지에서 완전히 처리됩니다. 현재 암호 제품군은 로컬 및 피어의 하드웨어를 모두 고려하여 보안, 성능 및 하드웨어 지원을 기반으로 정렬됩니다. 이제 Config.CipherSuites 필드와 Config.PreferServerCipherSuites 필드의 순서가 무시됩니다. Config.CipherSuites는 여전히 애플리케이션이 활성화할 TLS 1.0–1.2 암호 제품군을 선택할 수 있도록 합니다.
3DES 암호 제품군은 근본적인 블록 크기 관련 약점으로 인해 InsecureCipherSuites로 이동되었습니다. 여전히 기본적으로 활성화되어 있지만 위의 암호 제품군 순서 변경 덕분에 최후의 수단으로만 사용됩니다.
다음 릴리스인 Go 1.18부터 crypto/tls 클라이언트에 대한 Config.MinVersion은 기본적으로 TLS 1.2로 설정되어 기본적으로 TLS 1.0 및 TLS 1.1을 비활성화합니다. 애플리케이션은 Config.MinVersion을 명시적으로 설정하여 변경 사항을 재정의할 수 있습니다. 이것은 crypto/tls 서버에 영향을 미치지 않습니다.
이제 CreateCertificate는 제공된 개인 키가 부모의 공개 키(있는 경우)와 일치하지 않는 경우 오류를 반환합니다. 결과 인증서는 확인에 실패했습니다.
임시 GODEBUG=x509ignoreCN=0 플래그가 제거되었습니다.
ParseCertificate가 다시 작성되었으며 이제 ~70% 더 적은 리소스를 소비합니다. WebPKI 인증서를 처리할 때 관찰 가능한 동작은 오류 메시지를 제외하고 달리 변경되지 않았습니다.
BSD 시스템에서 이제 /etc/ssl/certs에서 신뢰할 수 있는 루트를 검색합니다. 이것은 FreeBSD 12.2+에서 새로운 시스템 신뢰 인증서 저장소에 대한 지원을 추가합니다.
다음 릴리스인 Go 1.18부터 crypto/x509는 SHA-1 해시 기능으로 서명된 인증서를 거부합니다. 자체 서명된 루트 인증서에는 적용되지 않습니다. SHA-1에 대한 실제 공격은 2017년에 입증되었으며 공개적으로 신뢰할 수 있는 인증 기관은 2015년 이후로 SHA-1 인증서를 발급하지 않았습니다.
B.Close 메소드는 이제 이 필드의 유형이 io.Closer 인터페이스를 구현하는 경우 커넥터 필드를 닫습니다.
새로운 NullInt16 및 NullByte 구조체는 null일 수 있는 int16 및 바이트 값을 나타냅니다. NullString과 유사한 Scan 메서드의 대상으로 사용할 수 있습니다.
SHT_MIPS_ABIFLAGS 상수가 추가되었습니다
binary.Uvarint는 낭비되는 계산을 피하기 위해 10바이트 후에 읽기를 중지합니다. 10바이트 이상이 필요한 경우 반환되는 바이트 수는 -11입니다.
이전 Go 버전은 잘못 인코딩된 변형을 읽을 때 더 큰 음수를 반환할 수 있었습니다.
새로운 Reader.FieldPos 메서드는 가장 최근에 Read에서 반환된 레코드의 지정된 필드 시작에 해당하는 행과 열을 반환합니다.
지시문 내에 주석이 표시되면 이제 완전히 생략되는 대신 단일 공백으로 대체됩니다.
선행, 후행 또는 다중 콜론이 있는 잘못된 요소 또는 속성 이름은 이제 Name.Local 필드에 수정되지 않은 상태로 저장됩니다.
잘못된 이름이 지정되면 플래그 선언이 이제 패닉 상태가 됩니다.
새로운 Context.ToolTags 필드에는 현재 Go 도구 모음 구성에 적합한 빌드 태그가 있습니다.
Source 및 Node 함수는 이제 //go:build 라인을 // +build 라인과 동기화합니다. 파일에 // +build 행만 있는 경우 파일의 적절한 위치로 이동되고 일치하는 //go:build 행이 추가됩니다. 그렇지 않으면 // +build 라인은 기존 //go:build 라인을 기반으로 덮어씁니다. 자세한 내용은 https://golang.org/design/draft-gobuild를 참조하세요.
새 SkipObjectResolution Mode 값은 선언에 대한 식별자를 확인하지 않도록 파서에 지시합니다. 이렇게 하면 구문 분석 속도가 향상될 수 있습니다.
구체적인 이미지 유형(RGBA, Gray16 등)은 이제 새로운 RGBA64Image 인터페이스를 구현합니다. 이전에 draw.Image를 구현한 구체적인 유형은 이제 image/draw 패키지의 새 인터페이스인 draw.RGBA64Image도 구현합니다.
새로운 FileInfoToDirEntry 함수는 FileInfo를 DirEntry로 변환합니다.
수학 패키지는 이제 MaxUint, MaxInt 및 MinInt의 세 가지 상수를 더 정의합니다. 32비트 시스템의 경우 해당 값은 각각 2^32 - 1, 2^31 - 1 및 -2^31입니다. 64비트 시스템의 경우 해당 값은 각각 2^64 - 1, 2^63 - 1 및 -2^63입니다.
Unix 시스템에서 MIME 유형 테이블은 이제 사용 가능한 경우 로컬 시스템의 공유 MIME 정보 데이터베이스에서 읽습니다.
Part.FileName은 이제 filepath.Base를 반환 값에 적용합니다. 이렇게 하면 Request.FormFile을 호출하는 net/http 서버와 같이 다중 부분 메시지를 수락하는 응용 프로그램에서 잠재적인 경로 탐색 취약점이 완화됩니다.
새로운 방법 IP.IsPrivate는 주소가 RFC 1918에 따른 개인 IPv4 주소인지 또는 RFC 4193에 따른 로컬 IPv6 주소인지 보고합니다.
Go DNS 해석기는 이제 IPv4 전용 또는 IPv6 전용 네트워크에 대한 주소를 확인할 때 두 주소 패밀리에 대해 쿼리하는 대신 하나의 DNS 쿼리만 보냅니다.
ErrClosed 센티넬 오류 및 ParseError 오류 유형은 이제 net.Error 인터페이스를 구현합니다.
ParseIP 및 ParseCIDR 함수는 이제 선행 0이 있는 10진수 구성 요소를 포함하는 IPv4 주소를 거부합니다. 이러한 구성 요소는 항상 10진수로 해석되지만 일부 운영 체제에서는 8진수로 처리합니다. Go 애플리케이션이 IP 주소의 유효성을 검사하는 데 사용한 다음 구성 요소를 8진수로 해석하는 Go가 아닌 애플리케이션과 함께 원래 형식으로 사용된 경우 이 불일치로 인해 보안 문제가 발생할 수 있습니다. 일반적으로 유효성 검사 후에 항상 값을 다시 인코딩하는 것이 좋습니다. 이렇게 하면 이러한 종류의 파서 정렬 오류 문제를 피할 수 있습니다.
net/http 패키지는 이제 클라이언트 또는 서버에서 TLS 핸드셰이크를 수행할 때 요청 컨텍스트와 함께 새로운 (*tls.Conn).HandshakeContext를 사용합니다.
이제 Server ReadTimeout 또는 WriteTimeout 필드를 음수 값으로 설정하면 즉각적인 시간 초과가 아니라 시간 초과가 없음을 나타냅니다.
이제 요청에 여러 호스트 헤더가 있는 경우 ReadRequest 함수가 오류를 반환합니다.
정리된 버전의 URL로 리디렉션할 때 ServeMux는 이제 항상 Location 헤더에 상대 URL을 사용합니다. 이전에는 요청의 전체 URL을 에코하여 클라이언트가 절대 요청 URL을 보내도록 할 수 있는 경우 의도하지 않은 리디렉션으로 이어질 수 있었습니다.
net/http에서 처리하는 특정 HTTP 헤더를 해석할 때 비ASCII 문자는 이제 무시되거나 거부됩니다.
Request.ParseForm이 Request.ParseMultipartForm에 의해 호출될 때 오류를 반환하는 경우 후자는 이제 반환하기 전에 Request.MultipartForm 채우기를 계속합니다.
이제 제공된 코드가 유효한 3자리 HTTP 상태 코드가 아닐 때 ResponseRecorder.WriteHeader가 패닉 상태가 됩니다. 이는 net/http 패키지의 ResponseWriter 구현 동작과 일치합니다.
새 메서드 Values.Has는 쿼리 매개 변수가 설정되었는지 여부를 보고합니다.
File.WriteString 메서드는 입력 문자열의 복사본을 만들지 않도록 최적화되었습니다.
새 Value.CanConvert 메서드는 값을 형식으로 변환할 수 있는지 여부를 보고합니다. 슬라이스가 너무 짧은 경우 슬라이스를 배열 포인터 유형으로 변환할 때 패닉을 피하기 위해 사용할 수 있습니다. 이전에는 이를 위해 Type.ConvertibleTo를 사용하는 것으로 충분했지만 슬라이스에서 배열 포인터 유형으로 새로 허용된 변환은 유형이 변환 가능하더라도 패닉이 발생할 수 있습니다.
새로운 StructField.IsExported 및 Method.IsExported 메서드는 구조체 필드 또는 유형 메서드를 내보내는지 여부를 보고합니다. PkgPath가 비어 있는지 여부를 확인하는 것보다 더 읽기 쉬운 대안을 제공합니다.
새로운 VisibleFields 함수는 익명 구조체 멤버 내부의 필드를 포함하여 구조체 유형의 모든 보이는 필드를 반환합니다.
ArrayOf 함수는 이제 음수 길이로 호출될 때 패닉이 발생합니다.
Type.ConvertibleTo 메서드를 확인하는 것만으로는 더 이상 Value.Convert 호출이 패닉하지 않는다는 것을 보장할 수 없습니다. 슬라이스의 길이가 N보다 작은 경우 `[]T`를 `*[N]T`로 변환할 때 패닉이 발생할 수 있습니다. 위의 언어 변경 섹션을 참조하세요.
Value.Convert 및 Type.ConvertibleTo 메서드는 언어가 허용하는 것과 일치하도록 동일한 이름을 가진 다른 패키지의 유형을 동일하게 취급하지 않도록 수정되었습니다.
할당 및 해제된 총 바이트 및 개체를 추적하는 새 메트릭이 추가되었습니다. 고루틴 스케줄링 지연의 분포를 추적하는 새로운 메트릭도 추가되었습니다.
블록 프로필은 더 이상 빈번한 짧은 이벤트보다 자주 발생하지 않는 긴 이벤트를 선호하도록 편향되지 않습니다.
strconv 패키지는 이제 부동 소수점 숫자의 형식을 지정하기 위해 Ulf Adams의 Ryū 알고리즘을 사용합니다. 이 알고리즘은 대부분의 입력에서 성능을 개선하고 최악의 경우 입력에서 99% 이상 더 빠릅니다.
새로운 QuotedPrefix 함수는 입력 시작 시 인용된 문자열(Unquote에서 이해하는 대로)을 반환합니다.
Builder.WriteRune 메서드는 이제 다른 잘못된 룬과 마찬가지로 음수 룬 값에 대해 대체 문자 U+FFFD를 씁니다.
atomic.Value에는 이제 추가 원자 연산을 제공하는 Swap 및 CompareAndSwap 메서드가 있습니다.
GetQueuedCompletionStatus 및 PostQueuedCompletionStatus 함수는 이제 더 이상 사용되지 않습니다. 이러한 함수에는 잘못된 서명이 있으며 golang.org/x/sys/windows 패키지의 동등한 기능으로 대체되었습니다.
유닉스 계열 시스템에서 자식 프로세스의 프로세스 그룹은 이제 신호가 차단된 상태로 설정됩니다. 이것은 부모가 백그라운드 프로세스 그룹에 있을 때 자식에게 SIGTTOU를 보내는 것을 방지합니다.
Windows 버전의 SysProcAttr에는 두 개의 새 필드가 있습니다. AdditionalInheritedHandles는 새 자식 프로세스에서 상속할 추가 핸들 목록입니다. ParentProcess는 새 프로세스의 상위 프로세스를 지정하는 것을 허용합니다.
상수 MSG_CMSG_CLOEXEC는 이제 DragonFly 및 모든 OpenBSD 시스템에서 정의됩니다(일부 OpenBSD 시스템 및 모든 FreeBSD, NetBSD 및 Linux 시스템에서 이미 정의됨).
상수 SYS_WAIT6 및 WEXITED는 이제 NetBSD 시스템에서 정의됩니다(SYS_WAIT6은 이미 DragonFly 및 FreeBSD 시스템에서 정의되었으며 WEXITED는 이미 Darwin, DragonFly, FreeBSD, Linux 및 Solaris 시스템에서 정의되었습니다).
testing
테스트 및 벤치마크의 실행 순서를 제어하는 새로운 테스트 플래그 -shuffle을 추가했습니다.
새로운 T.Setenv 및 B.Setenv 메서드는 테스트 또는 벤치마크 기간 동안 환경 변수 설정을 지원합니다.
새 SkipFuncCheck 모드 값은 템플릿 파서를 변경하여 함수가 정의되었는지 확인하지 않습니다.
이제 Time 유형에는 fmt 패키지에서 %#v 형식 지정자로 인쇄할 때 시간에 대해 더 유용한 값을 반환하는 GoString 메서드가 있습니다.
새 Time.IsDST 메서드를 사용하여 시간이 구성된 위치의 일광 절약 시간제인지 여부를 확인할 수 있습니다.
새로운 Time.UnixMilli 및 Time.UnixMicro 메서드는 각각 1970년 1월 1일 UTC 이후 경과된 밀리초 및 마이크로초 수를 반환합니다.
새로운 UnixMilli 및 UnixMicro 함수는 주어진 Unix 시간에 해당하는 현지 시간을 반환합니다.
패키지는 이제 시간을 구문 분석하고 형식화할 때 소수 자릿수 초의 구분 기호로 쉼표 ","를 허용합니다. 예를 들어 이제 다음 시간 레이아웃이 허용됩니다.
- 2006-01-02 15:04:05,999999999 -0700 MST
- Mon Jan _2 15:04:05,000000 2006
- Monday, January 2 15:04:05,000 2006
새로운 상수 레이아웃은 기준 시간을 정의합니다.
Is, IsGraphic, IsLetter, IsLower, IsMark, IsNumber, IsPrint, IsPunct, IsSpace, IsSymbol 및 IsUpper 함수는 이제 다른 유효하지 않은 룬과 마찬가지로 음수 룬 값에 대해 false를 반환합니다.
'프로그래밍(Web) > Golang' 카테고리의 다른 글
[바미] Golang JSON 필수 값 체크하기. (0) | 2022.07.21 |
---|---|
[바미] Go 1.18 Release Notes (0) | 2022.02.22 |
[바미] Go - os.Args를 이용하여 localhost port 번호 지정하기. (0) | 2021.11.11 |
[바미] Go - Logrus과 lumberjack을 사용하여 Log를 찍어보자! (2) | 2021.06.25 |
[바미] 디버그 모드 시 Version of Delve is too old for this version of Go 에러 뜰 때 해결 방법 (0) | 2021.06.08 |