5.17

w0nyyy·2022년 5월 18일
1

2.5 사용하지 않는 변수

  • 지역 변수는 반드시 사용되어야 함
  • 사용되지 않는 상수는 허용

2.6 변수와 상수 이름 짓기

* Go는 유니코드 문자를 식별자로 허용

  • 권장하지 않음

* Go는 관용적으로 스네이크 표기법 사용하지 않음

  • 낙타 표기법, 파스칼 표기법 사용

* 상수: 모든 문자를 대문자, 각 단어는 밑줄로 구분

  • Go는 이러한 일반 상수 이름 규칙을 따르지 않는다
  • 패키지에 포함된 요소를 외부에 노출시킬지(expose) 여부를 식별자의 첫글자가 대소문자 여부로 결정

* 함수 내에서는 짧은 변수 이름 선호

  • 변수의 의미보다 간결성을 선호하는 Go

* 짧은 이름

  • 코드 간결
  • 코드의 복잡도 판별 기준

* 패키지 블록 내

  • 설명적인 변수, 상수 이름 사용하자

chap. 03 복합타입

3.1 배열(array)

* 같은 타입의 여러 데이터를 담음
* 시퀀스 타입 (순서 중요)
* Go에서는 선호하지 않음(특별한 경우에만 사용)
* 선언 시 크기를 지정해야 함
* 크기를 변경할 수 없다

* 선언 방법
1) 제로 값으로 선언: 배열의 크기와 배열 내 요소 타입 지정
2) 배열 초깃값 지정: 배열 리터럴 사용
3) 희소 배열: 대부분의 요소가 0인 배열
4) 배열 크기 지정하지 않고: 배열 리터럴 필요
5) 다차원 배열: []의 개수가 차원 수

* 배열 요소 접근

  • [] 사용

* 배열 길이

  • len() 함수

* Go에서 배열을 잘 사용하지 않는 이유

  • 배열의 크기가 배열의 타입을 결정하는데 사용되기 때문
  • 즉, 원소의 타입이 같은 배열이라도 크기가 다르면 다른 타입
  • 크기(길이)가 다르면 타입 변환도 불가능

3.2 슬라이스

  • 일련의 값(시퀀스)을 저장하는 자료 구조
  • 순서 중요
  • 슬라이스의 크기는 타입의 일부가 아니다 (배열과의 큰 차이점)
  • 슬라이스 간 비교는 불가 (배열과 다른 점)

* 슬라이스 선언 (슬라이스 크기를 지정하지 않음)
1) 슬라이스 초깃값 지정: 슬라이스 리터럴
2) 희소 슬라이스
3) 다차원 슬라이스
4) 제로 슬라이스: 슬라이스 리터럴 없이 선언만 하는 것
- 슬라이스의 제로 값은 **nil**
- nil : 값의 부재(absence of value) 상태
- nil은 타입이 없음
5) 비어있는 슬라이스: 슬라이스 리터럴에 초깃값이 없는 것

* 슬라이스의 길이

  • len() 함수 사용

3.2.2 append

  • 슬라이스에 새로운 요소 추가
  • append의 결과를 할당하지 않으면 컴파일 에러

3.2.3 수용력(capacity)

  • 예약된(미리 준비된) 연속적인(consecutive) 메모리 공간의 크기
  • 길이와 수용력
  • 수용력 >= 길이
  • 요소가 추가되면 길이는 커지고 결국 수용력과 같아짐
  • 길이과 수용력이 같은 상태에서 요소가 추가되면 Go 런타임이 더 큰 수용력을 가지는 **새로운** 슬라이스를 할당, 원본 슬라이스의 값들은 새 슬라이스에 복사됨, 추가된 값은 새 슬라이스에 append되고 이 새 슬라이스가 반환된다.
  • 수용력이 1024 보다 작으면 2배 증가, 그렇지 않으면 25%씩 확장
  • cap() vs. len()

3.2.4 make()

  • 슬라이스에 저장될 요소 개수를 미리 알 수 있다면 make()를 사용해 효율적인 슬라이스 작업을 도모할 수 있다
  • make로 생성한 슬라이스에 append를 사용할 땐 주의할 것

3.2.5 슬라이스 선언

  • var data []int => nil
  • var data = []int{} => nil(X)

* 슬라이스를 아래 방식 중 어떤 걸로 생성할 지 정리해 봅시다.(p.75)

  • 제로 슬라이스
  • 슬라이스 리터럴
  • make()

3.2.6 슬라이싱의 슬라이싱

  • 슬라이스 연산자(:)
    - 슬라이스로부터 슬라이스 생성

  • 슬라이스 연산자를 사용하면 복사본을 만들지 않고 메모리를 공유함

  • 슬라이싱과 append를 함께 사용하면 혼란이 가중됨

  • 하위 슬라이스의 수용력
    = 원본 슬라이스의 수용력 - 하위 슬라이스 시작 오프셋

  • 하위 슬라이스와 append를 아무 생각 없이 사용하면 혼란이 가중된다.
    - 의도치 않은 값 변경이 발생
    - 완전한 슬라이스 표현식(full slice expression)으로 해결

  • 완전한 슬라이스 표현식
    - 하위 슬라이스에 얼마나 많은 메모리를 공유할 것인지를 지정
    - 슬라이스 연산때 콜론을 한 번 더 사용하여 세번째 인자에 원본 슬라이스에서 하위 슬라이스의 마지막 요소의 위치 지정
    - 슬라이스 연산의 세 번째 인자의 값을 두 번째 인자의 값과 같도록 설정

3.2.7 배열을 슬라이스로 변환

  • 배열에 슬라이스 연산 적용
  • 메모리 공유 문제 존재

3.2.8 copy

  • copy() 내장 함수
  • copy의 첫 번째 인자는 슬라이스이어야 함

3.3 문자열과 룬 그리고 바이트

  • 문자열은 룬으로 이루어진 것은 아니다.
  • 문자열은 바이트의 시퀀스이다.
  • 문자열의 길이는 바이트 수
  • 문자열에 슬라이스 연산 사용 가능
  • 문자열은 수정불가(immutable)이므로 슬라이스의 메모리 공유 문제가 없음
  • 유니코드로 구성되므로 슬라이스를 했을 때 문자가 깨지는 우려가 있음
  • 문자열은 바이트 슬라이스 또는 룬 슬라이스로 변환 가능

3.4 맵

  • 순서 없는 데이터 처리 유용
  • (Key, Value) Pair
    [SYNTAX]
    var 변수명 map[키타입]값타입
  • 생성
    1) nil 맵(제로 값 할당): map의 제로 값은 nil
    - nil 맵은 길이 0
    - nil 맵의 값을 읽으면 맵 값이 되는 타입의 제로 값
    - nil 맵에 값을 쓰려고 하면 패닉 발생
    2) 비어 있는 맵 리터럴: 비어 있는 맵 생성
    - nil 맵과 다르다
    - 길이는 0
    - 비어 있는 맵 리터럴이 할당된 맵을 읽고 쓸 수 있다.
    3) 값이 있는 맵 리터럴
    - 키와 값을 콜론으로 구분
    - 마지막 요소(키, 값)의 끝에 콤마(,)를 붙인다.
    4) make() 함수로 생성
    - 맵의 요소 개수를 안다면
    - 길이는 0 (make()로 슬라이스 만드는 것과 다름)
    - 초기 지정 개수 이상으로 커질 수 있다.
    - 맵의 제로 값은 nil
    - 맵은 비교 불가능, 단 nil과 같은지 다른지는 비교 가능

3.4.1 맵 읽고 쓰기

  • := 연산자는 사용 불가
  • 아직 설정되지 않은 키에 할당된 값을 읽으면 값 타입의 제로 값이 반환된다.

3.4.2 콤마 OK 관용구(idiom)

  • 맵의 키에 대응되는 값이 없어도 제로 값이 리턴되지만
  • 맵에 키가 존재하는지 확인할 필요가 있을 때 주로 사용하는 패턴
    - 맵에 키가 없어서 제로 값이 반환되는 건지
    - 실제로 키가 있는데 해당 값이 제로인 건지

3.4.3 맵 (요소) 삭제

  • delete() 내장 함수 사용
  • 키가 존재하지 않거나 nil 맵인 경우 아무것도 일어나지 않음
  • delete() 함수는 반환값이 없음

3.4.4 맵을 셋(집합)으로 이용

  • 집합(셋)
    - Uniqueness, 순서 없음
  • Go는 집합형을 직접 지원하지 않고 맵을 통해 간접적으로 지원
    - 집합의 원소로 쓰고 싶은 타입을 맵의 키 타입으로
    - 맵의 값을 불리언으로 설정

3.5 구조체

  • 여러 데이터 타입을 한데 묶어서 다루고 싶을 때 사용
  • struct 키워드, type 키워드
  • 구조체는 사용자 정의 타입
  • 따라서 바로 사용할 순 없고
  • 1) 구조체 정의 -> 2) 구조체를 타입으로 하는 변수 선언
  • 구조체 항목들은 콤마로 구분하지 않는다
  • 구조체는 어떤 블록 레벨에서도 정의 가능
  • 구조체의 제로 값
    - 구조체를 구성하는 항목들의 제로 값
  • 구조체 리터럴
    - 첫 번째 방법
    - 구조체 항목 값은 구조체 정의한 순서대로 나열
    - 구조체 항목 값은 콤마로 구분하고 마지막 항목에서 콤마를 붙여야 함
    - 두 번째 방법
    - 맵 리터럴과 유사
    - 순서 무관
    - 생략할 경우 제로 값으로 설정
  • 위 두 방법을 혼용할 수 없음
  • 제로 구조체와 비어 있는 구조체는 차이점이 없다
  • 구조체의 멤버(항목)을 접근할 때는 인덱싱이 아니라 점 표기법을 사용

3.5.1 익명 구조체

  • 한 번만 사용할 구조체
  • type 생략 -> 구조체 이름이 없다.
  • 구조체 변수만 존재
  • 주요 용도
    - 마샬링, 언마샬링
    - 테스트 작성

3.5.2 구조체 비교와 변환

  • 구조체 비교는 항목에 따라 다름
  • 두 개의 구조체가 같은 이름, 순서, 타입으로 구성되어 있으면 구조체 간에 타입 변환 가능

0개의 댓글