2장 기본 데이터 타입과 선언

2024.03.19

2.1 내장 타입

  • Go는 다른 언어와 마찬가지로 동일한 내장 타입(built-in type)을 갖고 있다.
    • boolean
    • integer
    • float
    • string

2.1.1 제로 값

  • Go는 대부분의 최신 언어들과 마찬가지로, 선언되었지만 값이 할당되지 않은 모든 변수에게 기본값인 제로 값(zero value)을 할당한다.
  • 명시적으로 제로 값을 넣는 것은 코드를 더 명확하게 하고 C와 C++ 프로그램에서 발견된 소스의 버그들을 제거한다.

2.1.2 리터럴

  • Go에서 리터럴은 숫자, 문자 혹은 문자열을 쓰는 것을 나타낸다.
  • 정수(integer) 리터럴은 일련의 자이다. 일반적으로 10진수를 의미하지만 다른 접두사를 사용하여 진법을 변경하여 사용할 수 있다.
  • 부동소수점(floating point) 리터럴은 값에서 소분수를 구분하는 소수점이 있다.
  • 룬(rune) 리터럴은 문자를 나타내며, 작은 따옴표로 묶어 사용한다. 다른 언어들과는 달리, Go에서는 작은따옴표와 큰따옴표는 혼용할 수 없다.
  • 문자 리터럴을 표시하는 방법에는 두 가지가 있다.
    • 해석된 문자열 리터럴(interpreted string literal)로 큰따옴표를 사용해서 만들 수 있다.
    • 로우 문자열(raw string) 리터럴을 사용하여 문자열에서 역슬래시, 큰따옴표 혹은 줄 바꿈을 그대로 포함할 수 있다.
  • Go는 실용적인 언어이기에 리터럴은 타입이 지정되어 있지 않다. 개발자가 특정 타입으로 지정하기 전까지 타입을 강제하지 않는 것이다.

2.1.3 불리언

  • bool 타입이 변수는 두 값(true or false) 중에 하나를 가진다.
  • bool의 제로 값은 false이다.

2.1.4 숫자 타입

  • Go는 아래와 같은 정수 타입을 지원한다.
    • int8, int16, int32, int64, uint8, uint16, uint32, uint64
  • Go는 아래와 같은 부동소수점 타입을 지원한다.
    • float32, float64
  • 정수와 같이 부동소수점의 제로 값도 0이다.
  • float은 부정확하기 때문에, 부정확한 값을 허용할 수 있는 상황에서만 사용하자. ( 그래픽이나 과학적 연산 )
  • 부동소수점에 나머지 연산(% )을 제외하고 모든 수학 연산과 비교 연자를 사용할 수 있다.
  • Go는 부동소수점 변수를 ==!= 의 사용으로 변수를 비교하게 하지만 사용하지 않는 것이 좋다. 부동소수점은 태생적으로 부정확한 값을 가지므로, 값을 같다고 생각하고 비교해도 같지 않을 수 있다.

2.1.5 문자열과 룬 맛보기

  • 문자열의 제로 값은 비어 있는 문자열이다.
  • Go에서 문자열의 속성은 불변이다. 문자열 변수에 값을 재할당할 수 있지만 이미 할당되어 있는 값을 변경할 수는 없다.

2.1.6 명시적 타입 변환

  • 의도의 명확성과 가독성의 중시하는 언어로서 변수들 간 자동 타입 변환을 허용하지 않는다. 변수 타입이 서로 맞지 않을 때, 명시적으로 타입 변환을 해주어야 한다.
  • 모든 타입 변환을 명시적으로 해야하기 때문에, 다른 Go 타입을 불리언을 취급할 수 없다.
    • 변수 x가 0과 같은지 확인해야 한다면, x == 0 여야 한다.
    • 문자열이 비어있는지 확인하려면, s == "" 로 해야 한다.

2.2 var Versus :=

  • GO에서 변수를 선언하는 다양한 방법이 있다.
    • var 키워드 사용
    • 선언리스트들 괄호를 묶어서 한꺼번에 선언
    • 함수 내에서 := 연산자를 사용한 짧은 선언
    • := 연산자를 사용하여 다양한 변수를 한꺼번에 선언
  • := 연산자는 함수 밖에서는 사용이 불가능하다.
var x int = 10
var x = 10 // 타입이 예상되는 변수라면 타입 생략 가능

var x,y int = 10, 20 // 하나의 라인에 여러 개의 변수 선언

var x,y int // 제로 값을 할당

var (
  x    int
  y           = 20
  z    int    = 30
  d, e        = 40, "hello"
  f, g string
) // 선언 리스트를 묶어서 한꺼번에 변수 선언
  • 함수 내에서 가장 흔한 선언 방법은 := 을 사용하는 것이다.
  • 패키지 블록이라는 범위내에서 함수 외부에 변수를 선언하는 것은 거의 없다. 값의 변경이 일어나는 패키지 레벨 변수는 좋지 않다.
  • 패키지 블록 내에서는 사실상 변경 부루가능한 변수 선언만 해야 한다.

2.3 const 사용

  • Go에서는 const 키워드로 상수를 선언할 수 있다.
const x int64 = 10

const (
  idKey   = "id"
  nameKey = "name"
)
  • Go의 const 는 매우 제한적이다. Go에서 상수는 리터럴에 이름을 부여하는 방법이다.
  • 컴파일러가 컴파일을 하는 동안에 파악할 수 있는 값을 가지고 있을 수 있다. 그 값들은 아래와 같다.
    • 숫자 리터럴
    • true, false
    • 문자열
    • 룬 문자
    • 내장 함수 complex, real, imag , len , cap
  • Go는 실행 중에 계산된 값을 변경할 수 없도록 지정하는 방법을 제공하지 않는다. 변경 불가능한 배열, 슬라이스, 맵, 구조체와 같은 것은 없고 변경 불가능하게 선언하는 방법도 없다. 함수 내에서 변수가 수정되고 있는지 명백하므로 불변성은 그리 중요치 않다.

2.4 타입 지정 상수와 타입 미지정 상수

  • 일반적으로, 상수에 타입을 지정하지 않는 것은 조금 더 유연함을 가질 수 있다.
const x = 10

var y int = x
var z float64 = x
var d byte = x
  • 타입 지정 상수는 다음과 같이 선언할 수 있다.
const typedX int = 10

// 위 상수는 int에만 직접 할당할 수 있다.
// 다른 타입에 할당하는 경우에는 컴파일 오류가 발생한다.

2.5 사용하지 않는 변수

  • Go 언어의 목표 중 하나는 대규모 팀이 프로그램을 개발하는 과정에서 더 쉽게 협업하도록 하는 것이다.
  • 지역 변수를 선언하고 사용하지 않는다면 컴파일 오류가 발생할 것이다.
  • Go 컴파일러는 접근하지 않는 패키지 레벨 변수 생성을 내버려 둘 것이다. 이는 패키지 레벨 변수 만드는 것을 피해야 하는 이유다.

2.6 변수와 상수 이름 짓기

  • Go의 문자와 숫자의 정의는 다른 언어들보다 조금 더 넓은 의미를 가진다. 문자 또는 숫자로 간주되는 모든 유니코드 문자가 허용된다.
_0 := 0_0
π := 3

// 코드는 정상 동작을 하지만 이런 이름은 사용하지는 말자
  • 관용적인 Go는 스네이크 표기법을 사용하지 않기 때문에 밑줄 사용은 드물다. 카멜 표기법을 사용한다.
  • Go는 패키지 레벨 선언의 이름에서 첫 번째 문자의 대소문자 사용으로 패키지 외부에서 접근 가능한지 여부를 결정한다.
  • 타입은 변수 이름에서 제외되어야 하지만 범위가 더 넓어지면, 값이 무엇을 나타내는지 명확하게 하는 더 완벽한 이름이 필요하다.