골롱 절편 메커니즘을 깊이 이해하다

2131 단어
원문
  • 슬라이드는 항상 설명이 있어야 합니다. 이 코드 코드를 보십시오
  • package main
    
    import (
        "fmt"
        "unsafe"
    )
    
    type Slice struct {
        ptr unsafe.Pointer // Array pointer
        len int            // slice length
        cap int            // slice capacity
    }
    
    //         ,      int   
    // 32  int length = 4
    // 64  int length = 8
    var intLen = int(unsafe.Sizeof(int(0)))
    
    func main() {
        s := make([]int, 10, 20)
    
        //        slice memory    
        if intLen == 4 { // 32 
            m := *(*[4 + 4*2]byte)(unsafe.Pointer(&s))
            fmt.Println("slice memory:", m)
        } else { // 64  
            m := *(*[8 + 8*2]byte)(unsafe.Pointer(&s))
            fmt.Println("slice memory:", m)
        }
    
        //  slice        Slice struct
        slice := (*Slice)(unsafe.Pointer(&s))
        fmt.Println("slice struct:", slice)
        fmt.Printf("ptr:%v len:%v cap:%v 
    ", slice.ptr, slice.len, slice.cap) fmt.Printf("golang slice len:%v cap:%v
    ", len(s), cap(s)) s[0] = 0 s[1] = 1 s[2] = 2 // arr := *(*[3]int)(unsafe.Pointer(slice.ptr)) fmt.Println("array values:", arr) // slice len slice.len = 15 fmt.Println("Slice len: ", slice.len) fmt.Println("golang slice len: ", len(s)) }
  • 뭘 알아냈어?
  • 비축 지식:
  • unsafe.Pointer는 c 언어의 void*
  • 와 유사
  • unsafe.Pointer가 차지하는 공간 = int 유형이 차지하는 바이트 수
  • 결론:
  • 슬라이스의 구조는 슬라이스 구조체와 같다

  • //   cap  ,  array ptr      
    s := make([]int, 1)
    
    fmt.Printf("len:%d cap: %d array ptr: %v 
    ", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s))) for i := 0; i < 5; i++ { s = append(s, i) fmt.Printf("len:%d cap: %d array ptr: %v
    ", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s))) } fmt.Println("Array:", s)
  • 위의 메인 프로그램을 교체합니다. 당신은 무엇을 발견했습니까?
  • 매번 append, 주소가 변하는데cap가 부족할 때 복제 작업이 발생한다는 뜻이다.
  • 실제 고는 append에서 캡을 확대하는 것이 규칙적이다.캡이 1024보다 작으면 매번 2*캡으로 확대하고 1024보다 크면 매번 1.25*캡으로 확대한다.그래서 위 테스트에서cap변화는 1, 2, 4, 8
  • 좋은 웹페이지 즐겨찾기