func main() {
a := []string{"Hello1", "Hello2", "Hello3"}
fmt.Println(a)
// [Hello1 Hello2 Hello3]
a = append(a[:0], a[1:]...)
fmt.Println(a)
// [Hello2 Hello3]
}
추가 기능을 사용하면 삭제 트릭이 어떻게 작동합니까?
첫 번째 요소 (빈 배열) 전에 모든 것을 잡는 것처럼 보입니다.
그런 다음 첫 번째 요소 뒤에 모든 것을 추가하십시오 (위치 0)
… (도트 도트 도트)의 기능은 무엇입니까?
답변
a
슬라이스는 어디에 있고 i
삭제할 요소의 인덱스는 다음 과 같습니다.
a = append(a[:i], a[i+1:]...)
...
Go의 variadic 인수에 대한 구문입니다.
기본적으로 함수를 정의 할 때 전달 하는 모든 인수를 해당 유형의 한 조각에 넣습니다. 그렇게하면 원하는만큼 많은 인수를 전달할 수 있습니다 (예 : 원하는 fmt.Println
만큼 많은 인수를 취할 수 있음).
이제 함수를 호출 할 때 ...
반대가 수행됩니다. 슬라이스의 압축을 풀고 별도의 인수로 변수를 가변 함수에 전달합니다.
이 라인이하는 일 :
a = append(a[:0], a[1:]...)
본질적으로 :
a = append(a[:0], a[1], a[2])
이제 궁금 할 수도 있습니다.
a = append(a[1:]...)
음의 함수 정의 append
는
func append(slice []Type, elems ...Type) []Type
따라서 첫 번째 인수는 올바른 유형의 슬라이스 여야하고 두 번째 인수는 가변적이므로 빈 슬라이스를 전달한 다음 나머지 슬라이스의 압축을 풀어 인수를 채 웁니다.
답변
두 가지 옵션이 있습니다.
A : 배열 순서 유지에 관심이 있습니다.
a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]
B : 당신은 질서를 유지하는 것에 신경 쓰지 않는다 (아마 더 빠를 것이다) :
a[i] = a[len(a)-1] // Replace it with the last one. CAREFUL only works if you have enough elements.
a = a[:len(a)-1] // Chop off the last one.
배열이 포인터 인 경우 메모리 누수에 대한 영향을 보려면 링크를 참조하십시오.
https://github.com/golang/go/wiki/SliceTricks
답변
[a:]
-, [:b]
-및 -표시 의 색인 [a:b]
을 요소 색인으로 생각하는 대신 요소 주변 및 사이의 간격의 0
색인으로 생각하십시오 0
.
그냥 파란색 숫자를 보면, 그것은에 무슨 일이 일어나고 있는지 볼 훨씬 쉽게 : [0:3]
은 분리 장치의 모든 것을 [3:3]
비어 있고 [1:2]
얻을 것이다 {"B"}
. 그러면 [a:]
짧은 버전 [a:len(arrayOrSlice)]
, [:b]
짧은 버전 [0:b]
및 [:]
짧은 버전이 [0:len(arrayOrSlice)]
있습니다. 후자는 일반적으로 필요할 때 배열을 슬라이스로 변환하는 데 사용됩니다.
답변
… 가변 인수에 대한 구문입니다.
나는 그것이 []Type)
append 함수와 같이 slice ( )를 사용하여 컴파일러에 의해 구현되었다고 생각합니다 .
func append(slice []Type, elems ...Type) []Type
“append”에서 “elems”를 사용할 때 실제로는 slice ([] type)입니다. ” a = append(a[:0], a[1:]...)
“는 ” a = append(a[0:0], a[1:])
“을 의미합니다
a[0:0]
아무것도없는 슬라이스입니다
a[1:]
“Hello2 Hello3″입니다.
이것이 작동하는 방법입니다
답변
허용되는 답변 솔루션으로 색인이 범위를 벗어났습니다. 이유 : 범위 시작시 값을 하나씩 반복하지 않고 인덱스별로 반복합니다. 슬라이스가 범위 내에있는 동안 슬라이스를 수정하면 문제가 발생할 수 있습니다.
기존 답변 :
chars := []string{"a", "a", "b"}
for i, v := range chars {
fmt.Printf("%+v, %d, %s\n", chars, i, v)
if v == "a" {
chars = append(chars[:i], chars[i+1:]...)
}
}
fmt.Printf("%+v", chars)
예상 :
[a a b], 0, a
[a b], 0, a
[b], 0, b
Result: [b]
실제 :
// Autual
[a a b], 0, a
[a b], 1, b
[a b], 2, b
Result: [a b]
올바른 방법 (솔루션) :
chars := []string{"a", "a", "b"}
for i := 0; i < len(chars); i++ {
if chars[i] == "a" {
chars = append(chars[:i], chars[i+1:]...)
i-- // form the remove item index to start iterate next item
}
}
fmt.Printf("%+v", chars)
출처 : https://dinolai.com/notes/golang/golang-delete-slice-item-in-range-problem.html
답변
golang의 위키에서는 슬라이스에서 요소 삭제를 포함하여 슬라이스에 대한 몇 가지 트릭을 보여줍니다.
링크 : 여기에 링크 설명을 입력하십시오
예를 들어 a는 숫자 i 요소를 삭제하려는 슬라이스입니다.
a = append(a[:i], a[i+1:]...)
또는
a = a[:i+copy(a[i:], a[i+1:])]