6.struct_types

Declare, create and initialize struct types

// Sample program to show how to declare and initialize struct types.

package main

import "fmt"

// example represents a type with different fields.
//示例表示具備不一樣字段的類型。

type example struct {
    flag    bool
    counter int16
    pi      float32
}

func main() {
    // Declare a variable of type example set to its
    // zero value.

    var e1 example

    //  display the value
    fmt.Printf("%+v\n", e1)

    // Declare a variable of type example and init using
    // a struct literal.

    e2 := example{
        flag:    true,
        counter: 11,
        pi:      3.14159,
    }
    // display the field values
    fmt.Println("flag", e2.flag)
    fmt.Println("counter", e2.counter)
    fmt.Println("pi", e2.pi)

    /*
        {flag:false counter:0 pi:0}
        flag true
        counter 11
        pi 3.14159
    */
}

Anonymous struct types

package main

import "fmt"

func main() {
    // Declare a variable of an anonymous type and init
    // using a struct literal.
    e := struct {
        flag    bool
        counter int16
        pi      float32
    }{
        flag:    true,
        counter: 10,
        pi:      3.14159,
    }

    // Display the values.
    fmt.Printf("%+v\n", e)
    fmt.Println("Flag", e.flag)
    fmt.Println("Counter", e.counter)
    fmt.Println("Pi", e.pi)
    
    /*
       {flag:true counter:10 pi:3.14159}
       Flag true
       Counter 10
       Pi 3.14159
    */
}

Named vs Unnamed types 命名類型和匿名類型

// Sample program to show how variables of an unnamed type can
// be assigned to variables of a named type, when they are
// identical.
package main

import "fmt"

// example represents a type with different fields.
type example struct {
    flag    bool
    counter int16
    pi      float32
}

func main() {
    // Declare a variable of an anonymous type and init
    // using a struct literal.
    e := struct {
        flag    bool
        counter int16
        pi      float32
    }{
        flag:    true,
        counter: 10,
        pi:      3.14159,
    }

    // Create a value of type example.
    var ex example

    // Assign the value of the unnamed struct type
    // to the named struct type value.
    // 分配未命名的struct類型的值。
    // 到命名的struct類型值。
    ex = e

    // Display the values.
    fmt.Printf("%+v\n", ex)
    fmt.Printf("%+v\n", e)
    fmt.Println("Flag", e.flag)
    fmt.Println("Counter", e.counter)
    fmt.Println("Pi", e.pi)
    
    
/*

{flag:true counter:10 pi:3.14159}
{flag:true counter:10 pi:3.14159}
Flag true
Counter 10
Pi 3.14159

*/  
    
}

結構體類型排列

// go get honnef.co/go/structlayout/cmd/...

// Alignment is about placing fields on address alignment boundaries
// for more efficient reads and writes to memory.

// Sample program to show how struct types align on boundaries.
// https://github.com/dominikh/go-tools/tree/master/cmd/structlayout
// go get honnef.co/go/structlayout/cmd/...

//對齊方式是在地址對齊邊界上放置字段。
//爲了更有效地讀寫內存。

//示例程序,以顯示結構類型如何在邊界上對齊。
package main

import (
    "fmt"
    "unsafe"
)

// No byte padding. 沒有字節填充。
type nbp struct {
    a bool //   1 byte              sizeof 1
    b bool //   1 byte              sizeof 2
    c bool //   1 byte              sizeof 3 - Aligned on 1 byte
}

// Single byte padding. 單個字節填充。
type sbp struct {
    a bool //   1 byte              sizeof 1
    //          1 byte padding      sizeof 2
    b int16 //  2 bytes             sizeof 4 - Aligned on 2 bytes
}

// Two byte padding.
type tbp struct {
    a bool //   1 byte              size 1
    //          3 bytes padding     size 4
    b int32 //  4 bytes             size 8 - Aligned on 2 bytes
}

// Four byte padding.
type fbp struct {
    a bool //   1 byte              size 1
    //          7 bytes padding     size 8
    b int64 //  8 bytes             size 16 - Aligned on 8 bytes
}

// Eight byte padding on 64bit Arch. Word size is 8 bytes.
// 在64位的Arch上有8個字節的填充。字大小是8個字節。
type ebp64 struct {
    a string // 16 bytes            size 16
    b int32  //  4 bytes            size 20
    //           4 bytes padding    size 24
    c string // 16 bytes            size 40
    d int32  //  4 bytes            size 44
    //           4 bytes padding    size 48 - Aligned on 8 bytes
}

// No padding on 32bit Arch. Word size is 4 bytes.
// To see this build as 32 bit: GOARCH=386 go build
type ebp32 struct {
    a string //  8 bytes            size  8
    b int32  //  4 bytes            size 12
    c string //  8 bytes            size 20
    d int32  //  4 bytes            size 24 - Aligned on 4 bytes
}

// No padding.
type np struct {
    a string // 16 bytes            size 16
    b string // 16 bytes            size 32
    c int32  //  8 bytes            size 40
    d int32  //  8 bytes            size 48 - Aligned on 8 bytes
}

func main() {
    // structlayout -json github.com/ardanlabs/gotraining/topics/go/language/struct_types/advanced/example1 nbp | structlayout-pretty
    var nbp nbp
    size := unsafe.Sizeof(nbp)
    fmt.Printf("SizeOf[%d][%p %p %p]\n", size, &nbp.a, &nbp.b, &nbp.c)
    /* SizeOf[3][0xc42001408a 0xc42001408b 0xc42001408c] */

    // =========================================================================

    // structlayout -json github.com/ardanlabs/gotraining/topics/go/language/struct_types/advanced/example1 sbp | structlayout-pretty
    var sbp sbp
    size = unsafe.Sizeof(sbp)
    fmt.Printf("SizeOf[%d][%p %p]\n", size, &sbp.a, &sbp.b)
    /* SizeOf[4][0xc4200140c0 0xc4200140c2] */

    // =========================================================================

    // structlayout -json github.com/ardanlabs/gotraining/topics/go/language/struct_types/advanced/example1 tbp | structlayout-pretty
    var tbp tbp
    size = unsafe.Sizeof(tbp)
    fmt.Printf("SizeOf[%d][%p %p]\n", size, &tbp.a, &tbp.b)
    /* SizeOf[8][0xc4200140d0 0xc4200140d4] */

    // =========================================================================

    // structlayout -json github.com/ardanlabs/gotraining/topics/go/language/struct_types/advanced/example1 fbp | structlayout-pretty
    var fbp fbp
    size = unsafe.Sizeof(fbp)
    fmt.Printf("SizeOf[%d][%p %p]\n", size, &fbp.a, &fbp.b)
    /* SizeOf[16][0xc4200140e0 0xc4200140e8] */

    // =========================================================================

    // structlayout -json github.com/ardanlabs/gotraining/topics/go/language/struct_types/advanced/example1 ebp | structlayout-pretty
    var ebp64 ebp64
    size = unsafe.Sizeof(ebp64)
    fmt.Printf("SizeOf[%d][%p %p %p %p]\n", size, &ebp64.a, &ebp64.b, &ebp64.c, &ebp64.d)
    /* SizeOf[48][0xc42007a180 0xc42007a190 0xc42007a198 0xc42007a1a8] */

    // =========================================================================

    // structlayout -json github.com/ardanlabs/gotraining/topics/go/language/struct_types/advanced/example1 np | structlayout-pretty
    var np np
    size = unsafe.Sizeof(np)
    fmt.Printf("SizeOf[%d][%p %p %p %p]\n", size, &np.a, &np.b, &np.c, &np.d)
    /* SizeOf[40][0xc42007a1b0 0xc42007a1c0 0xc42007a1d0 0xc42007a1d4]  */
}

// https://github.com/ardanlabs/gotraining/tree/master/topics/go/language/struct_types
相關文章
相關標籤/搜索