수색…
소개
슬라이스는 프로그래머가 메모리 관리에 대해 걱정할 필요없이 필요한만큼 요소를 추가 할 수 있도록 배열을 캡슐화하는 데이터 구조입니다. 슬라이스는 매우 효율적으로 하위 슬라이스로자를 수 있습니다. 결과 슬라이스는 모두 같은 내부 배열을 가리키기 때문입니다. Go 프로그래머는 대개 다른 프로그래밍 언어에서 수행되는 배열 복사를 피하기 위해이 기능을 활용합니다.
통사론
- slice : = make ([] type, len, cap) // 새 슬라이스를 만듭니다.
- slice = append (slice, item) // 슬라이스에 항목을 추가합니다.
- slice = append (slice, items ...) // 슬라이스에 항목의 조각을 추가합니다.
- len : = len (slice) // 슬라이스의 길이를 구합니다.
- cap : = cap (slice) // 슬라이스의 용량을 얻습니다.
- elNum : = copy (dst, slice) // 슬라이스의 내용을 다른 슬라이스로 복사합니다.
슬라이스에 추가 중
slice = append(slice, "hello", "world")
두 슬라이스 추가하기
slice1 := []string{"!"}
slice2 := []string{"Hello", "world"}
slice := append(slice1, slice2...)
요소 제거 / "조각"조각
슬라이스에서 하나 이상의 요소를 제거해야하거나 기존의 다른 하위 슬라이스로 작업해야하는 경우; 다음 방법을 사용할 수 있습니다.
다음 예제에서는 int of slice를 사용하지만 모든 유형의 슬라이스에서 작동합니다.
그래서 우리는 조각이 필요합니다. 마녀에게서 몇 가지 요소를 제거 할 것입니다.
slice := []int{1, 2, 3, 4, 5, 6}
// > [1 2 3 4 5 6]
제거 할 요소의 색인이 필요합니다.
// index of first element to remove (corresponding to the '3' in the slice)
var first = 2
// index of last element to remove (corresponding to the '5' in the slice)
var last = 4
그래서 우리는 원하지 않는 요소를 제거하면서 슬라이스를 "조각"할 수 있습니다 :
// keeping elements from start to 'first element to remove' (not keeping first to remove),
// removing elements from 'first element to remove' to 'last element to remove'
// and keeping all others elements to the end of the slice
newSlice1 := append(slice[:first], slice[last+1:]...)
// > [1 2 6]
// you can do using directly numbers instead of variables
newSlice2 := append(slice[:2], slice[5:]...)
// > [1 2 6]
// Another way to do the same
newSlice3 := slice[:first + copy(slice[first:], slice[last+1:])]
// > [1 2 6]
// same that newSlice3 with hard coded indexes (without use of variables)
newSlice4 := slice[:2 + copy(slice[2:], slice[5:])]
// > [1 2 6]
하나의 요소 만 제거하려면 다음과 같이 제거 할 마지막 인덱스로 첫 번째 AND 요소로이 요소의 인덱스를두면됩니다.
var indexToRemove = 3
newSlice5 := append(slice[:indexToRemove], slice[indexToRemove+1:]...)
// > [1 2 3 5 6]
// hard-coded version:
newSlice5 := append(slice[:3], slice[4:]...)
// > [1 2 3 5 6]
그리고 슬라이스 시작 부분에서 요소를 제거 할 수도 있습니다.
newSlice6 := append(slice[:0], slice[last+1:]...)
// > [6]
// That can be simplified into
newSlice6 := slice[last+1:]
// > [6]
또한 슬라이스 끝에서 일부 요소를 제거 할 수 있습니다.
newSlice7 := append(slice[:first], slice[first+1:len(slice)-1]...)
// > [1 2]
// That can be simplified into
newSlice7 := slice[:first]
// > [1 2]
새 슬라이스에 첫 번째 슬라이스와 정확히 동일한 요소가 포함되어야한다면 같은 것을 사용할 수 있지만
last := first-1
사용할 수 있습니다.
(인덱스가 이전에 계산 된 경우 유용 할 수 있습니다)
길이와 용량
조각에는 길이와 용량이 모두 있습니다. 슬라이스의 길이는 슬라이스에 현재 있는 요소의 수이며, 용량은 슬라이스가 재 할당해야하기 전에 보유 할 수있는 요소의 수 입니다.
내장 된 make()
함수를 사용하여 슬라이스를 생성 할 때 길이와 선택적으로 용량을 지정할 수 있습니다. 용량을 명시 적으로 지정하지 않으면 지정된 길이가됩니다.
var s = make([]int, 3, 5) // length 3, capacity 5
내장 된 len()
함수를 사용하여 슬라이스 길이를 확인할 수 있습니다.
var n = len(s) // n == 3
내장 된 cap()
함수를 사용하여 용량을 확인할 수 있습니다.
var c = cap(s) // c == 5
make()
의해 생성 된 요소는 슬라이스의 요소 유형에 대한 0 값으로 설정됩니다.
for idx, val := range s {
fmt.Println(idx, val)
}
// output:
// 0 0
// 1 0
// 2 0
인덱스가 용량 내에 있어도 슬라이스 길이를 초과하는 요소에는 액세스 할 수 없습니다.
var x = s[3] // panic: runtime error: index out of range
그러나 용량이 길이를 초과하는 경우 재 할당하지 않고 새 요소를 추가 할 수 있습니다.
var t = []int{3, 4}
s = append(s, t) // s is now []int{0, 0, 0, 3, 4}
n = len(s) // n == 5
c = cap(s) // c == 5
새 요소를 수용 할 수있는 용량이 부족한 슬라이스에 추가하면 기본 배열이 충분한 용량으로 재 할당됩니다.
var u = []int{5, 6}
s = append(s, u) // s is now []int{0, 0, 0, 3, 4, 5, 6}
n = len(s) // n == 7
c = cap(s) // c > 5
따라서 불필요한 재 할당을 피하기 위해 필요한 공간을 알고 있다면 슬라이스를 처음 만들 때 충분한 용량을 할당하는 것이 일반적으로 좋은 습관입니다.
한 슬라이스에서 다른 슬라이스로 내용 복사
슬라이스의 내용을 초기에 비어있는 슬라이스로 복사하려면 다음 단계를 수행하십시오.
- 원본 조각 만들기 :
var sourceSlice []interface{} = []interface{}{"Hello",5.10,"World",true}
- 다음을 사용하여 대상 슬라이스를 만듭니다.
- 길이 = sourceSlice의 길이
var destinationSlice []interface{} = make([]interface{},len(sourceSlice))
- 대상 슬라이스의 기본 배열이 소스 슬라이스의 모든 요소를 수용 할만큼 충분히 크기 때문에 내장 된
copy
사용하여 요소를 복사 할 수 있습니다.
copy(destinationSlice,sourceSlice)
조각 만들기
슬라이스는 프로그래머가 데이터 목록을 저장하는 일반적인 방법입니다.
슬라이스 변수를 선언하려면 []Type
구문을 사용하십시오.
var a []int
한 줄에 슬라이스 변수를 선언하고 초기화하려면 []Type{values}
구문을 사용하십시오.
var a []int = []int{3, 1, 4, 1, 5, 9}
슬라이스를 초기화하는 또 다른 방법은 make
함수를 사용하는 make
입니다. 세 가지 인수 : 슬라이스 Type
(또는 맵 ), length
및 capacity
.
a := make([]int, 0, 5)
append
사용하여 새 슬라이스에 요소를 추가 할 수 있습니다.
a = append(a, 5)
len
사용하여 슬라이스의 요소 수를 확인하십시오.
length := len(a)
cap
사용하여 슬라이스의 용량을 확인하십시오. 용량은 슬라이스의 메모리에 현재 할당 된 요소의 수입니다. 언제든지 Go가 자동으로 더 큰 슬라이스를 생성하므로 언제든지 용량에 슬라이스를 추가 할 수 있습니다.
capacity := cap(a)
일반적인 인덱싱 구문을 사용하여 슬라이스의 요소에 액세스 할 수 있습니다.
a[0] // Gets the first member of `a`
range
슬라이스에 for
루프를 사용할 수도 있습니다. 첫 번째 변수는 지정된 배열의 인덱스이고 두 번째 변수는 인덱스 값입니다.
for index, value := range a {
fmt.Println("Index: " + index + " Value: " + value) // Prints "Index: 0 Value: 5" (and continues until end of slice)
}
슬라이스 필터링
새로운 기본 배열을 할당하지 않고 슬라이스를 필터링하려면 :
// Our base slice
slice := []int{ 1, 2, 3, 4 }
// Create a zero-length slice with the same underlying array
tmp := slice[:0]
for _, v := range slice {
if v % 2 == 0 {
// Append desired values to slice
tmp = append(tmp, v)
}
}
// (Optional) Reassign the slice
slice = tmp // [2, 4]
슬라이스의 0 값
slice의 0 값은 길이와 용량이 0
nil
입니다. nil
슬라이스에는 기본 배열이 없습니다. 그러나 []int{}
또는 make([]int, 5)[5:]
와 같이 길이와 용량이 0
아닌 슬라이스가 없습니다.
nil 값을 가진 모든 타입은 nil
slice로 변환 될 수 있습니다 :
s = []int(nil)
슬라이스가 비어 있는지 테스트하려면 다음을 사용하십시오.
if len(s) == 0 {
fmt.Ptintf("s is empty.")
}