이 글은 골든래빗 《Tucker 의 Go 언어프로그래밍》의 2단계 써머리입니다.
목차
- 슬라이스
 - 메서드
 - 인터페이스
 - 함수 고급편
 - 자료구조
 
슬라이스 (slice)
→ var 변수명 []타입 선언
→ 변수명 := []타입{} 선언
→ 동적 배열: 자동으로 배열 크기를 증가 시키는 자료구조
→ 배열 가리키는 포인터, 요소개수(Len), 전체 배열 길이(Cap)으로 구성된 구조체
append()
→ 슬라이스만의 기능 (요소 추가) → append(추가하고자 하는 슬라이스, 추가하는 요소) = 새로운 슬라이스 결과 반환
	slice := []int{1, 2, 3, 4, 5}
	slice3 := append([]int{}, slice...)
	fmt.Println(slice3)
	// [1 2 3 4 5]
	slice4 := append([]int{}, slice[0], slice[1], slice[2], slice[3], slice[4])
	fmt.Println(slice4)
	// [1 2 3 4 5]
슬라이싱 Slicing
→ 배열의 일부를 집어내는 기능: 슬라이스 반환 → 배열의 일부 = 배열[시작인덱스:끝인덱스]
- 처음부터 슬라이싱: 시작인덱스 생략가능
	slice4 := []int{1, 2, 3, 4, 5}
	slice5 := slice4[0:3]
	slice6 := slice4[:3]
	// slice4:  [1 2 3 4 5] 5 5
	// slice5:  [1 2 3] 3 3
	// slice6:  [1 2 3] 3 3
- 끝까지 슬라이싱: 끝인덱스 생략가능
	slice7 := []int{1, 2, 3, 4, 5}
	slice8 := slice4[2:len(slice7)]
	slice9 := slice4[2:]
	// slice7:  [1 2 3 4 5] 5 5
	// slice8:  [3 4 5] 3 3
	// slice9:  [3 4 5] 3 3
- 전체 슬라이싱: 시작인덱스, 끝인덱스 생략가능 (배열 전체를 가리키는 슬라이스 생성)
- 배열을 슬라이스로 바꾸고 싶을때 사용
	slice10 := []int{1, 2, 3, 4, 5}
	slice12 := slice10[0:len(slice10)]
	slice11 := slice10[:]
	// slice10:  [1 2 3 4 5] 5 5
	// slice11:  [1 2 3 4 5] 5 5
	// slice12:  [1 2 3 4 5] 5 5
- cap크기 조절
- slice[시작인덱스:끝인덱스:최대인덱스]
- len == 끝인덱스 - 시작인덱스
- cap == 최대인덱스 - 시작인덱스
	slice13 := []int{1, 2, 3, 4, 5}
	slice14 := slice13[1:3]
	slice15 := slice13[1:3:4]
	// slice13:  [1 2 3 4 5] 5 5
	// slice14:  [2 3] 2 4
	// slice15:  [2 3] 2 3
	slice16 := []int{1, 2, 3, 4, 5, 6, 7, 8}
	slice17 := slice16[1:3]
	slice18 := slice16[1:3:4]
	// slice13:  [1 2 3 4 5 6 7 8] 8 8
	// slice14:  [2 3] 2 7 (최대인덱스: 8 - 시작인덱스: 1)
	// slice15:  [2 3] 2 3 (최대인덱스: 4 - 시작인덱스: 1)
- 끝에서 한개전 (끝 인덱스를 정확하게 적어야함:음수X)
	slice19 := []int{1, 2, 3, 4, 5}
	slice20 := slice19[2:len(slice19)-1]
	// slice19:  [1 2 3 4 5] 5 5
	// slice20:  [3 4] 2 3 
메서드
→ 호출시 값 모두 복사
→ 값 중심의 메서드 만들때 사용
→ 호출자 인스턴스 접근 불가
→ 복사되는 양에 따라서 성능상 문제
package main
import "fmt"
type myInt int
func (a myInt) add(b int) int {
	// return a + b // ERROR
	return int(a) + b
}
func main() {
	var a myInt = 10
	fmt.Println(a.add(30))
	var b int = 20
	// fmt.Println(b.add(50))  // ERROR
	// 다른 타입이라서 메서드 사용불가
	fmt.Println(myInt(b).add(50))
}
package main
import (
	fmt
)
type account stuct {
	balance int
}
func withdrawFunc(a *account, amount int) { // 일반 함수 표현
	a.balance -= amount
}
func (a *account) withdrawFunc(amount int) { // 메서드 표현
	a.balance -= amount
}
func main() {
	a := &account{100}
	withdrawFunc(a, 30) // 함수 형태 호출
	a.withdrawFunc(30) // 메서드 형태 호출
	fmt.Printf("%d \\n", a.balance)
}
인터페이스
→ 구현을 포함하지 않는 메서드 집합
→ interface{}
→ 모든 타입을 받고 싶을 때 사용
  var a Interface
  t := a.(ConcreteType)
  // 타입 변환한 결과, 성공여부 (bool) -> 런타임 에러 방지 
  t, ok := a.(ConcreteType)
  if ok {
    ...
  }
  // 한줄로
  if t, ok := a.(ConcreteType); ok {
    ...
  }
함수 고급편
가변 인수 함수
→ 함수 인수 개수가 고정적이지 않은 함수 → 인수 타입 앞에 ... 붙여서 해당 타입 인수 여러개 받는 가변 인수임을 표시
defer 지연 실행
→ 함수가 종료되기 직전에 실행하는 코드
→ 맨 마지막에 defer 쓴게 먼저 실행됨 (stack 스택: FILO / LIFO)
package main
import (
	"fmt"
	"os"
)
func main() {
	// defer 명령문
	f, err := os.Create("test.txt")
	if err != nil {
		fmt.Println("failed to create a file", err)
		return
	}
	defer fmt.Println("반드시 호출")
	defer f.Close()
	defer fmt.Println("파일 닫기")
	fmt.Println("파일에 Hello 적기")
	fmt.Fprintln(f, "Hello")
	// 파일에 Hello 적기
	// 파일 닫기
	// 반드시 호출
}
'STUDY > Go Lang' 카테고리의 다른 글
| [3단계] Go 프로그래밍에 유용한 기법 익히기 (2) (0) | 2023.11.13 | 
|---|---|
| [3단계] Go 프로그래밍에 유용한 기법 익히기 (1) (0) | 2023.11.05 | 
| [Go Lang] 고급 기법으로 Go 레벨업하기 (2) (0) | 2023.10.29 | 
| [GoLang] 가볍게 Go 입문하기 (2) (1) | 2023.10.15 | 
| [GoLang] 가볍게 Go 입문하기 (1) (0) | 2023.10.07 |