CafeM0ca

[Go] slice 탐구 본문

Programming/Go

[Go] slice 탐구

M0ca 2020. 11. 23. 03:49
반응형

A Tour of Go 정리

code convention은 https://github.com/golang/go/wiki/CodeReviewComments?fbclid=IwAR1RtGyVpP_iPKMqReVwKfufv0aD9J7JQfwuTNFnnVgxKbW5MMpMcqKCj-o 를 바탕으로 습관을 들이자.

array

var a [10]int

위 처럼 사이즈가 고정되어 있다.

slice

slice 자료형은 동적으로 크기가 달라진다.

package main

import "fmt"

func addSliceValue(s []int) {
  for i := 0; i < len(s); i++ {
    s[i]++
  }
}

func main() {
    primes := [6]int{2, 3, 5, 7, 11, 13} // primes는 array

  var s []int = primes[1:4] // s는 slice. slice 자료형은 []int 형태로 괄호 안에 값을 넣지 않음
    fmt.Println("sliced prime s:", s)

    primes[3] = 0
    fmt.Println("prime[3] = 0")
    fmt.Println("s:", s)

    fmt.Println("Call addSliceValue, passing slice")
    addSliceValue(s)

    fmt.Println("primes:", primes) // s의 값이 조작되면서 원본인 primes에 영향
  fmt.Println("s:", s)

    fmt.Println("Call addSliceValue, passing sliced array")
    addSliceValue(primes[:])
    fmt.Println("primes:", primes) // primes의 값이 바뀌면서 s값도 바뀜
    fmt.Println("s:", s)
}

sliced prime s: [3 5 7]
prime[3] = 0
[3 5 0]
s: [3 5 0]
Call addSliceValue, passing slice
primes: [2 4 6 1 11 13]
s: [4 6 1]
Call addSliceValue, passing sliced array
primes: [3 5 7 2 12 14]
s: [5 7 2]

slice 자료형은 데이터를 저장하지 않는다.

https://jacking75.github.io/go_slice/?fbclid=IwAR30PBcbvhGaEdjRnkBOlTxwonz0J2V9xsca5cSJJ1mpvTzWai_ZcPYEIJM 에 따르면 배열에 대한 포인터와 길이와 용량을 가진 값으로 표현한다.

같이 참고하면 좋음

http://golang.site/go/article/13-Go-컬렉션---Slice

slice는 std::vector처럼 len이 capacibility보다 커지면 capacibility를 2배로 늘린다.

immutable하게 slice

추후 추가

make로 slice 생성

package main

import "fmt"

func main() {
    a := make([]int, 5)
    printSlice("a", a)

    b := make([]int, 0, 5)
    printSlice("b", b)

    c := b[:2]
    printSlice("c", c)

    d := c[2:5]
    printSlice("d", d)
}

func printSlice(s string, x []int) {
    fmt.Printf("%s len=%d cap=%d %v\n",
        s, len(x), cap(x), x)
}

append 함수

package main

import "fmt"

func main() {
    var s []int
    printSlice(s) // len=0 cap=0 []

    // append works on nil slices.
    s = append(s, 0)
    printSlice(s) // len=1 cap=1 [0]

    // The slice grows as needed.
    s = append(s, 1)
    printSlice(s) // len=2 cap=2 [0 1]

    s = append(s, -1)
    printSlice(s) // len=3 cap=4 [0 1 -1]

    // We can add more than one element at a time.
    s = append(s, 2, 3, 4)
    printSlice(s) // len=6 cap=8 [0 1 -1 2 3 4]
}

func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

range

func addSliceValue(s []int) {
  for i := 0; i < len(s); i++ {
    s[i]++
  }
}

위 코드를 range로 바꿔보면

func addSliceValue(s []int) {
  for i, element := range s {
    s[i]++
    //  element++
  }
}

i는 s의 index고 element는 s[i]로 보면 된다.

element++하면 s[i]++을 기대하지만 그렇게 값이 바뀌지 않으니 조심!

출력만 한다면 element를 출력하면 되고, 값을 바꾸고 싶다면 s[i]로 접근하자.

만약 둘 중 하나를 사용하지 않는다면 blank identifier를 사용하자

func addSliceValue(s []int) {
  for i, _ := range s {
    s[i]++
  }
}

// of
func addSliceValue(s []int) {
  for _, element := range s {
    fmt.Println(element)
  }
}

range는 return값이 2개라는 점. (index와 copy한 element)

반응형

'Programming > Go' 카테고리의 다른 글

[Go] Type assertion, Type switch  (0) 2020.12.04
[Go] Interface  (0) 2020.12.04
[Go] method, receiver (go 리시버)  (0) 2020.12.04
[Go] A Tour of Go Exercise : Fibonacci closure 풀이  (0) 2020.12.03
[Go] A Tour of Go: Exercise Maps 풀이  (0) 2020.12.02
Comments