program tip

Go에서 크기 조정이 가능한 배열을 구현하는 방법

radiobox 2021. 1. 10. 17:05
반응형

Go에서 크기 조정이 가능한 배열을 구현하는 방법


저는 C ++ 배경에서 왔으며 std::vector이와 같은 클래스 를 사용하는 데 익숙합니다 . 다음과 같은 동적 배열이 필요하다고 가정합니다.

type a struct {
    b int
    c string
}

이를 수행하는 표준 방법은 무엇입니까?

스 니펫은 매우 유용합니다.


append()내장 사용

예:

type mytype struct {
  a, b int
}

func main() {
  a := []mytype{mytype{1, 2}, mytype{3, 4}}
  a = append(a, mytype{5, 6})
}

추가에 대한 자세한 내용 사양참조하십시오 .


Go Slice에는 데이터, 길이 및 용량의 세 가지 요소가 포함됩니다.

s := make([]int, 0, 10)

변수 s는 길이가 0이고 용량이 10 인 int 조각입니다. 내장 된 len () 및 cap () 함수를 사용하면 조각의 길이와 용량을 얻을 수 있습니다.

len(s) == 0
cap(s) == 10

슬라이스 길이를 늘리려면 간단히 다시 슬라이스하면됩니다.

s = s[0:5]
// len(s) == 5
// cap(s) == 10

길이를 줄이려면 하위 슬라이스를 사용할 수 있습니다.

s = s[0:1]
// len(s) == 1

make ()를 호출하는 더 짧은 방법이 있습니다.

a := make([]int, 10) 
// len(a) == cap(a) == 10

b := make([]int)
// len(b) == cap(b) == 0

모두 훌륭하고 좋지만, 슬라이스의 길이를 용량 이상으로 늘려야하는 경우 어떻게해야합니까? 이렇게하려면 새 슬라이스를 할당하고 이전 슬라이스의 내용을 새 슬라이스에 복사해야합니다. ( "복사"기능은 또 다른 내장 기능입니다.)

t := make([]int, len(s), 20)
copy(t, s)

효과적인 이동 문서는 필요하다면 크기 조정, 다른 하나 개의 슬라이스를 추가? 추가 기능을 구현하는, 조금 더 예 걸린다.

슬라이스는 어레이에 의해 지원됩니다. 특정 용량의 슬라이스를 만들면 () 해당 용량의 배열이 백그라운드에 할당됩니다. 슬라이스는 효과적으로 해당 배열에 대한 "스마트 포인터"가됩니다. 해당 슬라이스 (또는 해당 슬라이스의 하위 슬라이스)를 다른 함수에 전달하면 동일한 배열에 대한 포인터로 전달됩니다. 이것은 서브 슬라이스를 생성하는 데 매우 저렴하게 만듭니다. 이는 비용이 많이 드는 백업 어레이의 할당입니다.

Go 표준 라이브러리에는 슬라이스를 수동으로 관리 할 필요가없는 여러 컨테이너 패키지 (예 : 벡터)가 포함되어 있습니다. 속도를 위해 슬라이스를 사용하고 편의를 위해보다 정교한 컨테이너 클래스를 사용합니다. (저는 여전히 대부분의 작업에 슬라이스를 사용합니다.)

You may be wondering why you need to go to all this trouble. After all, a lot of languages provide dynamically resized arrays as primitives. The reason for this is tied to Go's philosophy. The language designers don't presume to know what the appropriate allocation policy is for your program; instead they give you the tools you need to build your own data structures.


The idiomatic way to do this has changed. The addition of the built-in append() function means that you can extend a slice like so:

type a struct {
    b int
    c string
}

func main(){
    var mySlice []a
    mySlice = append(mySlice,a{5,"pizza"})
}

Append() will append the given item to the slice if there is room or extend the slice if it's not bigger enough.

More information about append() is here http://golang.org/doc/go_spec.html#Appending_and_copying_slices


you might also be able to make do with a slice. which is an array that knows its current length. And can have a separate current length and maximum capacity. Note the values passed for initial size and capacity do not have to be constants so you can create a function which builds and returns slices of different lengths based on its parameters.

The up side is that a slice []Int can just be indexed like an array, and will return ints when used in this way.

The downside is that it will not automatically grow byound its stated capacity. Effective Go has an example of how you would go about handling reallocation.

the code would be

type mytype struct {
   a, b int
}




func main() {

  sl := make([]mytype, 10, 50) //slice of 10 items, max capacity 50 these do not have to be constant expressions.
  sl[0] = mytype{1,2}
   //...
  for i, value := range sl {
  // ... do stuff with value
  }
}

Hi we can simply do this in two ways

type mytype struct {
  a, b int
}

Just do like this

  1. Without append

__

a := []mytype{mytype{1, 2}, mytype{3, 4}, mytype{4, 5}}
  1. With append

__

a:=  append([]mytype{}, mytype{1, 2}, mytype{3, 4}, mytype{4, 5})

Add as much as you want. First one is an easy way to do this. Hope this will help you.

ReferenceURL : https://stackoverflow.com/questions/3387273/how-to-implement-resizable-arrays-in-go

반응형