Go에서 `append(x, x...)`가 슬라이스를 새로운 백업 배열에 복사하는 이유는 무엇입니까?

PHPz
풀어 주다: 2024-02-10 11:12:23
앞으로
978명이 탐색했습니다.

为什么 `append(x, x...)` 将切片复制到 Go 中的新支持数组中?

php 편집자 Yuzi는 모두가 공통적으로 묻는 질문에 답할 것입니다. Go에서 'append(x, x...)'가 슬라이스를 새로운 지원 배열에 복사하는 이유는 무엇입니까? Go 프로그래밍 언어에서 `append` 함수는 요소를 슬라이스에 추가하는 데 사용됩니다. 'append' 함수를 사용할 때 슬라이스 용량이 충분하지 않으면 Go는 새 기본 배열을 만들고 원본 슬라이스의 요소를 새 기본 배열에 복사합니다. Go에서 슬라이스는 동적 배열에 대한 참조이기 때문입니다. 슬라이스 용량이 충분하지 않으면 더 많은 요소를 수용하기 위해 새 배열을 만들어야 합니다. 이 메커니즘은 슬라이스의 연속성과 확장성을 보장하지만 일부 성능 손실도 가져옵니다.

질문 내용

go의 슬라이싱 팁 wiki 및 go 라이브러리(예: 이 예)에서는 슬라이스를 새 백업 배열에 복사하기 위해 다음과 같은 코드를 볼 수 있습니다.

으아아아

내가 이해한 내용은 다음과 같습니다.

  • append의 두 번째 인수로 제공된 슬라이스의 모든 항목은 새 백업 배열에 복사됩니다.
  • append 的第一个参数中,代码使用完整切片表达式。 (我们可以将第一个参数重写为 a[0:0:0],但如果省略,将提供第一个 0의 첫 번째 매개변수에서 코드는 전체 슬라이스 표현식을 사용합니다. (첫 번째 인수를 a[0:0:0]로 다시 작성할 수 있지만 생략하면 첫 번째
  • 가 제공됩니다. 여기서는 더 큰 의미와 관련이 없다고 생각합니다.)
  • 사양에 따라 생성된 슬라이스는 원본 슬라이스와 동일한 유형이어야 하며 길이와 용량이 0이어야 합니다.
  • copy 代替 append (다시 말하지만 직접적인 관련은 없지만
  • 대신 copy를 사용하면 더 명확하게 읽을 수 있습니다.)

append(someslice[:0:0], someslice...) 创建一个新的支持数组。我最初也很困惑为什么 append그러나 append(someslice[:0:0], someslice...) 구문이 왜 새로운 백업 배열을 생성하는지 완전히 이해하지 못합니다. 또한 처음에는

작업이 원본 슬라이스를 엉망으로 만들거나 자르지 않은 이유에 대해 혼란스러웠습니다.

내 추측:
  • newslice := oldslice이 모든 것이 필요하고 유용하다고 생각합니다. 왜냐하면
  • 만 할당하면 하나의 변경 사항이 다른 하나에도 반영되기 때문입니다. 일반적으로 당신은 이것을 원하지 않습니다.
  • append
  • 의 결과를 원본 슬라이스에 할당하지 않기 때문에(go에서는 일반적임) 원본 슬라이스에는 아무 일도 일어나지 않습니다. 어떤 방식으로든 잘리거나 변경되지 않습니다.
  • anyslice[:0:0] 的长度和容量均为零,因此如果 go 要将 anyslice 요소가 결과에 할당되므로 새로운 백업 배열을 만들어야 합니다. 이것이 새로운 백업 어레이를 만드는 이유
  • 인가요?
  • anyslice... 没有元素会发生什么? go playground 上的一个片段表明,如果您在空切片上使用此附加技巧,则副本和原始副本最初具有相同的支持数组。 (编辑:正如评论者所解释的,我误解了这个片段。该片段显示这两个项目最初是相同的,但是都没有支持数组。它们都指向最初为通用零值。)由于两个切片的长度和容量都为零,因此当您向其中一个切片添加任何内容时,该切片将获得一个新的后备数组。所以我猜,效果还是一样的。即appendanyslice...에 요소가 없으면 어떻게 되나요? Go Playground의 스니펫은 빈 슬라이스에 이 추가 트릭을 사용하면 복사본과 원본이 처음에 동일한 백업 배열을 갖는다는 것을 보여줍니다. (편집: 댓글 작성자가 설명했듯이 이 스니펫을 오해했습니다. 스니펫은 두 프로젝트가 원래 동일했지만 어느 쪽도 배열을 지원하지 않습니다는 것을 보여줍니다. 둘 다 일반을 가리킵니다. 0 값.) 두 슬라이스 모두 길이와 용량이 0이므로 슬라이스 중 하나에 무엇이든 추가하면 해당 슬라이스는 새로운 지원 어레이를 얻습니다. 그래서 그 효과는 여전히 같다고 생각합니다. 즉, 두 조각은 복사 후에 서로 영향을 미칠 수 없습니다.
  • 이 다른 플레이그라운드 스니펫은 슬라이스에 0개 이상의 요소가 있는 경우 append 복사 메소드가 즉시 새로운 백업 배열을 생성한다는 것을 보여줍니다. 이 경우 결과로 나온 두 조각은 즉각적으로 분리됩니다.

아마도 이것에 대해 너무 걱정할 것입니다. 하지만 왜 트릭이 그렇게 작동하는지에 대해 좀 더 철저한 설명을 듣고 싶습니다. append(a[:0:0], a...)

해결 방법

anySlice[:0:0]의 길이와 용량이 0이므로 Go는 결과에 anySlice의 요소를 할당하려면 새로운 백업 배열을 생성해야 합니다. 이것이 새로운 백업 어레이가 생성된 이유입니까?

용량이

이니까 그렇죠. 0

https://pkg.go.dev/[이메일 보호됨]#append

용량이 충분하면 새 요소를 수용할 수 있도록 대상이 다시 슬라이스됩니다. 그렇지 않은 경우 새로운 기본 배열이 할당됩니다.

  • 비어 있지 않은 슬라이스로는 충분하지 않습니다. 새 배열을 할당해야 합니다. cap=0

위 내용은 Go에서 `append(x, x...)`가 슬라이스를 새로운 백업 배열에 복사하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:stackoverflow.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!