Go의 상수: 기본을 넘어서

Linda Hamilton
풀어 주다: 2024-11-09 05:35:02
원래의
772명이 탐색했습니다.

Go’s Constants: Beyond Basics

처음 Go에 입문했을 때 저는 상수가 단순하고 제한적이라고 생각했습니다. 단지 고정된 값일 뿐 화려할 것은 없습니다. 하지만 좀 더 깊이 파고들수록 꽤 다재다능하다는 것을 알게 되었습니다. 예, 고정된 값이지만 Go에서는 유연하고 효율적인 방식으로 값을 처리합니다. 꽤 멋지다. 몇 가지 실제 사례를 통해 이것이 무엇을 의미하는지 살펴보겠습니다.

유형이 없는 값으로서의 상수(사용될 때까지)

Go에서는 실제로 사용할 때까지 상수의 유형이 지정되지 않는 경우가 많습니다. 기본 종류가 있지만 값이 맞는 한 다른 유형의 변수에 할당할 수 있습니다. 이로 인해 정적으로 유형이 지정된 언어에서는 특이한 방식으로 적응할 수 있습니다.

그 모습은 다음과 같습니다.

const x = 10
var i int = x
var f float64 = x
var b byte = x
로그인 후 복사
로그인 후 복사
로그인 후 복사

슈뢰딩거의 역설과 유사하게 x는 할당할 때까지 int, float64 또는 바이트일 수 있습니다. 이러한 임시 유연성을 통해 x는 코드의 다양한 유형과 원활하게 작동할 수 있습니다. 캐스팅이 필요하지 않아 깔끔하게 유지됩니다.

표현식에 다양한 유형의 상수를 혼합할 수도 있으며 Go는 결과에 가장 적합한 유형을 찾아냅니다.

const a = 1.5
const b = 2
const result = a * b // result is float64
로그인 후 복사
로그인 후 복사
로그인 후 복사

a는 부동 소수점 숫자이므로 Go에서는 전체 표현을 float64로 승격합니다. 따라서 정밀도 손실에 대해 걱정할 필요가 없습니다. Go가 처리합니다. 하지만 주의하세요. 결과를 int에 할당하려고 하면 오류가 발생합니다. Go는 데이터 손실이 발생할 수 있는 암시적 변환을 허용하지 않습니다.

제한사항

이러한 유연성은 훨씬 더 중요합니다. 변수에 상수를 할당하면 해당 변수의 유형이 설정됩니다.

const y = 10
var z int = y       // z is an int
var k float64 = y   // y can still be used as float64
로그인 후 복사
로그인 후 복사
로그인 후 복사

하지만 이것을 시도해 보면:

const y = 10.5
var m int = y       // Error: constant 10.5 truncated to integer
로그인 후 복사
로그인 후 복사
로그인 후 복사

Go는 명시적인 캐스트 없이 부동 소수점 상수를 정수로 자동 변환하지 않기 때문에 오류를 발생시킵니다. 따라서 상수는 유연하지만 호환되지 않는 변수에 맞게 유형을 변경하지는 않습니다.

유형 기본값 이해

유형을 지정하지 않고 유형이 지정되지 않은 상수를 사용하면 기본 유형을 가정합니다.

  • 유형이 지정되지 않은 정수 상수 기본값은 정수입니다.

  • 유형이 지정되지 않은 부동 소수점 상수 기본값은 float64입니다.

  • 유형이 지정되지 않은 룬 상수 기본값은 rune(int32)입니다.

  • 유형이 지정되지 않은 복합 상수 기본값은 complex128입니다.

  • 유형이 지정되지 않은 문자열 상수 기본값은 문자열입니다.

  • 유형이 지정되지 않은 부울 상수 기본값은 bool입니다.

다음은 빠른 테이블입니다.

Constant Kind Can Adapt To
Untyped Integer int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64, complex64, complex128
Untyped Float float32, float64, complex64, complex128
Untyped Complex complex64, complex128
Untyped Rune rune, int32, any integer type that can hold the value
Untyped String string
Untyped Boolean bool

컴파일 시간 평가 및 성능

Go는 컴파일 타임에 상수를 평가할 뿐만 아니라 상수 표현식도 최적화합니다. 즉, 계산에 상수를 사용할 수 있으며 Go는 컴파일 중에 결과를 계산합니다.

const x = 10
var i int = x
var f float64 = x
var b byte = x
로그인 후 복사
로그인 후 복사
로그인 후 복사

그래서 c는 런타임에 다시 계산되지 않습니다. Go는 이미 컴파일 타임에 520이라는 것을 알아냈습니다. 이는 특히 속도가 중요한 코드에서 성능을 향상시킬 수 있습니다. Go는 상수를 사용하여 프로그램이 실행될 때마다 계산을 수행하는 대신 한 번만 계산을 처리합니다.

조건부 컴파일의 상수

Go에는 다른 언어처럼 전처리기가 없지만 if 문에 상수를 사용하여 컴파일 타임에 코드를 포함하거나 제외할 수 있습니다.

const a = 1.5
const b = 2
const result = a * b // result is float64
로그인 후 복사
로그인 후 복사
로그인 후 복사

디버그가 false인 경우 컴파일러는 if 조건이 결코 true가 아닐 것임을 알고 블록 내부의 코드를 생략할 수 있습니다. 이렇게 하면 최종 바이너리가 더 작아질 수 있습니다. 꽤 편리하죠?

큰 숫자 작업

Go 상수의 강력한 기능 중 하나는 매우 큰 숫자를 지원한다는 것입니다. Go의 유형이 지정되지 않은 숫자 상수는 메모리와 컴파일러에 의해서만 제한되는 "무한" 정밀도를 갖습니다.

const y = 10
var z int = y       // z is an int
var k float64 = y   // y can still be used as float64
로그인 후 복사
로그인 후 복사
로그인 후 복사

bigNum이 float64나 int와 같은 내장 숫자 유형보다 훨씬 크더라도 Go를 사용하면 이를 상수로 정의할 수 있습니다. 컴파일 타임에 다음과 같은 큰 숫자로 계산을 수행할 수 있습니다.

const y = 10.5
var m int = y       // Error: constant 10.5 truncated to integer
로그인 후 복사
로그인 후 복사
로그인 후 복사

iota로 입력된 상수

Go를 사용해 본 적이 있다면 아마도 열거형 상수를 생성하는 방법을 본 적이 있을 것입니다. 증분값을 자동으로 할당해주기 때문에 유용합니다.

iota를 사용하여 상수 선언에 표현식을 사용하여 관련 상수를 만들 수도 있습니다.

const a = 100
const b = 5
const c = a * b + 20 // c is computed at compile time
로그인 후 복사
로그인 후 복사

이 코드는 비트 이동을 사용하여 킬로바이트, 메가바이트, 기가바이트 및 테라바이트에 대한 상수를 정의합니다. 컴파일 타임에 계산됩니다. 일련의 관련 상수를 생성하는 깔끔한 방법입니다.

저는 iota가 이런 종류의 작업에 정말 도움이 된다고 생각합니다. Go에는 내장된 열거형 유형이 없으므로 iota 식별자와 사용자 정의 유형을 사용하여 열거형을 효과적으로 시뮬레이션할 수 있습니다.

비트 단위 연산 및 시프트가 포함된 상수

상수는 비트 연산과 시프트를 사용할 수 있으며 내장된 유형보다 더 큰 값을 생성할 수도 있습니다.

const debug = false

func main() {
    if debug {
        fmt.Println("Debugging enabled")
    }
    // The above block might be removed by the compiler if debug is false
}
로그인 후 복사
로그인 후 복사

여기서 ShiftedValue는 이동량이 크기 때문에 매우 큰 숫자가 됩니다. 이 값은 표준 정수 유형에 비해 너무 크지만 할당을 시도할 때까지 상수로 유효합니다.

const bigNum = 1e1000 // This is a valid constant
로그인 후 복사

이는 상수가 변수에 저장할 수 없는 값을 나타낼 수 있음을 보여주므로 매우 큰 숫자를 사용하여 컴파일 시간 계산이 가능합니다.


상수 제한

Go의 상수는 유연하지만 할 수 없는 일도 있습니다.

포인터로 상수를 참조할 수 없습니다

상수에는 런타임 시 메모리 주소가 없습니다. 따라서 상수의 주소를 가져오거나 포인터를 사용할 수 없습니다.

const x = 10
var i int = x
var f float64 = x
var b byte = x
로그인 후 복사
로그인 후 복사
로그인 후 복사

유형이 지정된 nil 포인터가 있는 상수

nil은 포인터, 슬라이스, 맵, 채널 및 함수 유형의 변수에 할당될 수 있지만 유형이 지정된 nil 포인터를 보유하는 상수는 만들 수 없습니다.

const a = 1.5
const b = 2
const result = a * b // result is float64
로그인 후 복사
로그인 후 복사
로그인 후 복사

이는 Go에서 상수의 불변성과 컴파일 타임 특성을 추가합니다.

상수 선언의 함수 호출

len, cap, real, imag, complex와 같은 상수 표현식에는 특정 내장 함수만 사용할 수 있습니다.

const y = 10
var z int = y       // z is an int
var k float64 = y   // y can still be used as float64
로그인 후 복사
로그인 후 복사
로그인 후 복사

내장된 기능을 사용할 수 있기 때문입니다

복합 유형 및 상수

상수는 슬라이스, 맵, 구조체와 같은 복합 유형을 직접적으로 나타낼 수 없습니다. 하지만 상수를 사용하여 초기화할 수 있습니다.

const y = 10.5
var m int = y       // Error: constant 10.5 truncated to integer
로그인 후 복사
로그인 후 복사
로그인 후 복사

위 코드는 슬라이스를 상수로 선언할 수 없기 때문에 작동하지 않습니다. 그러나 변수 슬라이스 내에서 상수를 사용할 수 있습니다.

const a = 100
const b = 5
const c = a * b + 20 // c is computed at compile time
로그인 후 복사
로그인 후 복사

slice와 같은 유형 자체는 상수가 아니므로 상수로 선언할 수 없다는 점을 기억하세요. 하지만 내부 요소는 상수일 수 있습니다.

필요 시 명시적 변환

유형 불일치 또는 정밀도 손실 가능성으로 인해 유형이 지정되지 않은 상수를 직접 할당할 수 없는 경우 명시적인 유형 변환을 사용해야 합니다.

const debug = false

func main() {
    if debug {
        fmt.Println("Debugging enabled")
    }
    // The above block might be removed by the compiler if debug is false
}
로그인 후 복사
로그인 후 복사

마무리

이 글을 통해 상수에 대한 더 나은 아이디어를 얻을 수 있기를 바랍니다. 이는 단순히 고정된 값이 아닙니다. 뿐만 아니라 코드를 더욱 표현력 있고 효율적으로 만들 수 있는 유연한 기능이기도 합니다.

저는 아직 Go에 대한 경험을 공유하는 것이 상대적으로 낯설고 배우고 발전하고 싶습니다. 이 게시물이 유익하다고 생각하거나 개선할 수 있는 방법에 대한 제안이 있으면 댓글에 게시해 주세요.

'Go의 UTF-8 지원: 흥미로운 제한'에 대한 내 첫 번째 Reddit 게시물(로그인이 필요하지 않음)은 상당한 관심을 불러일으켰습니다.

여러분의 피드백을 기다리겠습니다.

위 내용은 Go의 상수: 기본을 넘어서의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿