이 글은 골든래빗 《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 |