>백엔드 개발 >Golang >nil 슬라이스, non-nil 슬라이스, Go 언어의 빈 슬라이스

nil 슬라이스, non-nil 슬라이스, Go 언어의 빈 슬라이스

WBOY
WBOY앞으로
2024-02-08 21:18:081282검색

Go 语言中 nil 切片、非 nil 切片、空切片

php 편집기 Xiaoxin은 Go 언어의 슬라이스 유형을 소개합니다. Go 언어에서 슬라이스에는 nil 슬라이스, non-nil 슬라이스, 빈 슬라이스의 세 가지 상태가 있습니다. 이 세 가지 슬라이싱 상태는 사용 시 서로 다른 의미와 특성을 갖습니다. 이러한 슬라이스 유형 간의 차이점을 이해하면 Go 언어의 슬라이스 기능을 더 잘 이해하고 사용하는 데 도움이 됩니다. 다음으로, 이 세 가지 슬라이스 유형의 구체적인 기능과 용도를 살펴보겠습니다.

질문 내용

저는 Go 프로그래밍이 처음입니다. 나는 Go 프로그래밍 책에서 슬라이스가 세 부분, 즉 배열에 대한 포인터, 길이, 용량으로 구성되어 있다는 것을 읽었습니다.

다음 사항에 대해 혼란스럽습니다.

  • nil 슬라이스(슬라이스에는 가리키는 기본 배열이 없습니다. len = 0, cap=0)
  • len = 0, cap = 0인 0이 아닌 슬라이스만
  • 빈 조각.

nil과 빈 슬라이스가 같은 것인지 누가 말해 줄 수 있나요? 둘 다 다르다면 이 둘의 차이점이 무엇인지 알려주세요. 슬라이스가 비어 있는지 테스트하는 방법은 무엇입니까? 또한 길이와 용량이 0인 0이 아닌 슬라이스에서 포인터는 어떤 값을 보유합니까?

해결 방법

관찰 가능한 동작

nil는 빈 슬라이스(용량 0)와 동일하지 않지만 관찰 가능한 동작은 동일합니다(거의 항상). 내 말은:

  • 내장된 len()cap() 함수
  • 에 전달할 수 있습니다.
  • 이를 for range 재정의할 수 있습니다(반복 횟수는 0회가 됩니다)
  • 슬라이싱할 수 있습니다(Spec: 표현식 슬라이싱 에 설명된 제한 사항을 위반하지 않는 한 결과도 빈 슬라이스가 됩니다)
  • 길이가 0이므로 내용을 변경할 수 없습니다(값을 추가하면 새 슬라이스 값이 생성됨)

이 간단한 예를 확인하세요(1개의 nil 切片和 2 个非 nil 슬라이스와 2개의 비

빈 슬라이스):

으아악 출력(Go Playground

에서 사용해 보세요):

으아악 nil 切片进行切片会生成 nil 切片,对非 nil 切片进行切片会生成非 nil (

슬라이스를 자르면

슬라이스가 생성되고, nil 进行比较来区分,它们在其他方面的行为都是相同的。 但请注意,许多软件包确实会将切片与 nil 进行比较,并且可能会基于此进行不同的操作(例如 encoding/ jsonfmt 아닌 슬라이스를 자르면 아닌 슬라이스가 생성됩니다.)

슬라이스 값을 미리 선언된 식별자와 비교해야만 차이점을 알 수 있다는 점을 제외하면

, 그 외에는 동일하게 동작합니다. 그러나 많은 패키지는 슬라이스를 와 비교하고 이에 따라 다르게 작동할 수 있습니다(예: encoding/jsonfmt 패키지). nil 切片转换为数组指针将生成非 nil 指针,将 nil 切片转换为数组指针将生成 nil

유일한 차이점은

슬라이스를 배열 포인터로 변환0 进行比较:len(s) == 0。无论它是 nil 切片还是非 nil(

Go 1.17

의 언어에 추가됨)입니다. 비 슬라이스를 배열 포인터로 변환하면 비 포인터가 생성되고,

슬라이스를 배열 포인터로 변환하면

포인터가 생성됩니다.

조각이 비어 있는지 확인하려면 해당 길이를 0(len(s) == 0)과 비교하면 됩니다. 슬라이스이든 비reflect.SliceHeader슬라이스이든 양수 용량이 있는지 여부는 중요하지 않습니다. 요소가 없으면 비어 있습니다. 으아악

인쇄(

Go Playgroundnil 切片,该结构将具有其零值,即其所有字段都将为零值,即:0에서 시도해 보세요):

으아악

하층nil 切片的容量和长度等于 0LenCap 字段,则很可能是 0,但 Data 指针可能不是。它不会,这就是它与 nil

슬라이스 값은

에 정의된 구조로 표시됩니다.

으아악 🎜 🎜 슬라이스의 경우 구조의 값은 0입니다. 즉, 모든 필드의 값이 0입니다(예: 0). 🎜 🎜비🎜 슬라이스의 용량과 길이가 0, LenCap 필드와 같은 경우 0 이지만 Data 포인터는 그렇지 않을 수도 있습니다. 그렇지 않습니다, 이것이 🎜슬라이스와 다른 점입니다. 크기가 0인 기본 배열을 가리킵니다. 🎜 🎜Go 사양에서는 크기가 0인 다양한 유형의 값이 동일한 메모리 주소를 가질 수 있도록 허용합니다. 🎜사양: 시스템 참고 사항: 크기 및 정렬 보증: 🎜🎜

让我们检查一下。为此,我们调用 unsafe 包的帮助,并“获取” reflect.SliceHeader 结构“视图” “我们的切片值:

var s1 []int
s2 := []int{}
s3 := make([]int, 0)

fmt.Printf("s1 (addr: %p): %+8v\n",
    &s1, *(*reflect.SliceHeader)(unsafe.Pointer(&s1)))
fmt.Printf("s2 (addr: %p): %+8v\n",
    &s2, *(*reflect.SliceHeader)(unsafe.Pointer(&s2)))
fmt.Printf("s3 (addr: %p): %+8v\n",
    &s3, *(*reflect.SliceHeader)(unsafe.Pointer(&s3)))

输出(在 Go Playground 上尝试一下):

s1 (addr: 0x1040a130): {Data:       0 Len:       0 Cap:       0}
s2 (addr: 0x1040a140): {Data: 1535812 Len:       0 Cap:       0}
s3 (addr: 0x1040a150): {Data: 1535812 Len:       0 Cap:       0}

我们看到了什么?

  • 所有切片(切片头)都有不同的内存地址
  • nil 切片具有 0 数据指针
  • s2s3 切片确实具有相同的数据指针,共享/指向相同的 0 大小的内存值

위 내용은 nil 슬라이스, non-nil 슬라이스, Go 언어의 빈 슬라이스의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 stackoverflow.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제