• 7.pointers


    // Sample program to show the basic concept of pass by value.
    package main
    
    func main() {
    	// Declare variable of type int with a value of 10.
    	count := 10
    
    	// Display the "value of" and "address of" count.
    	println("count:	Value Of[", count, "]	Addr Of[", &count, "]")
    
    	// Pass the "value of" the count.
    	increment(count)
    
    	println("count:	Value Of[", count, "]	Addr Of[", &count, "]")
    
    }
    
    // increment declares count as a pointer variable whose value is
    // always an address and points to values of type int.
    //增量声明count作为一个指针变量,其值为。
    //始终是一个地址,并指向int类型的值。
    
    //go:noinline
    func increment(inc int) {
    
    	// Increment the "value of" inc.
    	inc++
    	println("inc:	Value Of[", inc, "]	Addr Of[", &inc, "]")
    }
    
    /*
    count:	Value Of[ 10 ]	Addr Of[ 0xc420045f68 ]
    inc:	Value Of[ 11 ]	Addr Of[ 0xc420045f58 ]
    count:	Value Of[ 10 ]	Addr Of[ 0xc420045f68 ]
    */
    
    

    Sharing data I

    // Sample program to show the basic concept of using a pointer
    // to share data.
    package main
    
    func main() {
    
    	// Declare variable of type int with a value of 10.
    	count := 10
    
    	// Display the "value of" and "address of" count.
    	println("1.count:	Value Of[", count, "]		Addr Of[", &count, "]")
    
    	// Pass the "address of" count.
    	increment(&count)
    
    	println("3.count:	Value Of[", count, "]		Addr Of[", &count, "]")
    }
    
    // increment declares count as a pointer variable whose value is
    // always an address and points to values of type int.
    //go:noinline
    func increment(inc *int) {
    
    	// Increment the "value of" count that the "pointer points to".
    	*inc++
    	println("2.inc:	Value Of[", inc, "]	Addr Of[", &inc, "]	Value Points To[", *inc, "]")
    }
    
    /*
    1.count:	Value Of[ 10 ]		Addr Of[ 0xc420045f68 ]
    2.inc:	Value Of[ 0xc420045f68 ]	Addr Of[ 0xc420045f58 ]	Value Points To[ 11 ]
    3.count:	Value Of[ 11 ]		Addr Of[ 0xc420045f68 ]
    */
    
    

    Sharing data II

    // Sample program to show the basic concept of using a pointer
    // to share data.
    //示例程序演示使用指针的基本概念。
    //分享数据。
    package main
    
    import "fmt"
    
    // user represents a user in the system.//用户代表系统中的用户。
    type user struct {
    	name   string
    	email  string
    	logins int
    }
    
    func main() {
    	// Declare and initialize a variable named bill of type user.
    	bill := user{
    		name:  "Bill",
    		email: "bill@ardanlabs.com",
    	}
    
    	//** We don't need to include all the fields when specifying field
    	// names with a struct literal.
    
    	// Pass the "address of" the bill value. 通过“地址”的票据价值。
    	display(&bill)
    
    	// Pass the "address of" the logins field from within the bill value.
    	increment(&bill.logins)
    
    	// Pass the "address of" the bill value.
    	display(&bill)
    
    }
    
    // increment declares logins as a pointer variable whose value is
    // always an address and points to values of type int.
    func increment(logins *int) {
    	*logins++
    	fmt.Printf("&logins[%p] logins[%p] *logins[%d]
    ", &logins, logins, *logins)
    }
    
    // display declares u as user pointer variable whose value is always an address
    // and points to values of type user.
    func display(u *user) {
    	fmt.Printf("%p	%+v
    ", u, *u)
    }
    
    /* 
    0xc42007a180	{name:Bill email:bill@ardanlabs.com logins:0}
    &logins[0xc42000c030] logins[0xc42007a1a0] *logins[1]
    0xc42007a180	{name:Bill email:bill@ardanlabs.com logins:1}
    
    */
    

    Escape Analysis 溢出分析

    //逸出分析
    // Escape Analysis
    
    // Escape Analysis Flaws:
    // https://docs.google.com/document/d/1CxgUBPlx9iJzkz9JWkb6tIpTe5q32QDmz8l0BouG0Cw/view
    
    // Sample program to teach the mechanics of escape analysis.
    package main
    
    // user represents a user in the system.
    type user struct {
    	name  string
    	email string
    }
    
    // main is the entry point for the application.
    func main() {
    	u1 := createUserV1()
    	u2 := createUserV2()
    
    	println("u1", &u1, "u2", &u2)
    	/*
    		V1 0xc420045ef8
    		V2 0xc42000a040
    		u1 0xc420045f50 u2 0xc420045f48
    
    	*/
    }
    
    // createUserV1 creates a user value and passed
    // a copy back to the caller.
    //go:noinline
    func createUserV1() user {
    	u := user{
    		name:  "Bill",
    		email: "bill@ardanlabs.com",
    	}
    
    	println("V1", &u)
    
    	return u
    }
    
    // createUserV2 creates a user value and shares
    // the value with the caller.
    //go:noinline
    func createUserV2() *user {
    	u := user{
    		name:  "Bill",
    		email: "bill@ardanlabs.com",
    	}
    
    	println("V2", &u)
    
    	return &u
    }
    
    /*
    // See escape analysis and inling decisions.
    $ go build -gcflags "-m -m"
    # github.com/ardanlabs/gotraining/topics/go/language/pointers/example4
    ./example4.go:27: cannot inline createUserV1: marked go:noinline
    ./example4.go:41: cannot inline createUserV2: marked go:noinline
    ./example4.go:17: cannot inline main: non-leaf function
    ./example4.go:33: createUserV1 &u does not escape
    ./example4.go:49: &u escapes to heap
    ./example4.go:49: 	from ~r0 (return) at ./example4.go:49
    ./example4.go:45: moved to heap: u
    ./example4.go:47: createUserV2 &u does not escape
    ./example4.go:21: main &u1 does not escape
    ./example4.go:21: main &u2 does not escape
    // See the intermediate assembly phase before
    // generating the actual arch-specific assembly.
    $ go build -gcflags -S
    "".createUserV1 t=1 size=221 args=0x20 locals=0x38
    	0x0000 00000 (github.com/ardanlabs/gotraining/.../example4.go:27)	TEXT	"".createUserV1(SB), $56-32
    	0x0000 00000 (github.com/ardanlabs/gotraining/.../example4.go:27)	MOVQ	(TLS), CX
    	0x0009 00009 (github.com/ardanlabs/gotraining/.../example4.go:27)	CMPQ	SP, 16(CX)
    	0x000d 00013 (github.com/ardanlabs/gotraining/.../example4.go:27)	JLS	211
    	0x0013 00019 (github.com/ardanlabs/gotraining/.../example4.go:27)	SUBQ	$56, SP
    	0x0017 00023 (github.com/ardanlabs/gotraining/.../example4.go:27)	MOVQ	BP, 48(SP)
    	0x001c 00028 (github.com/ardanlabs/gotraining/.../example4.go:27)	LEAQ	48(SP), BP
    // See the actual machine representation by using
    // the disasembler.
    $ go tool objdump -s main.main example4
    TEXT main.main(SB) github.com/ardanlabs/gotraining/topics/go/language/pointers/example4/example4.go
    	example4.go:18	0x104bf31	e8ba000000		CALL main.createUserV1(SB)
    	example4.go:18	0x104bf36	488b0424		MOVQ 0(SP), AX
    	example4.go:18	0x104bf3a	488b4c2408		MOVQ 0x8(SP), CX
    	example4.go:18	0x104bf3f	488b542410		MOVQ 0x10(SP), DX
    	example4.go:18	0x104bf44	488b5c2418		MOVQ 0x18(SP), BX
    	example4.go:18	0x104bf49	4889442428		MOVQ AX, 0x28(SP)
    	example4.go:18	0x104bf4e	48894c2430		MOVQ CX, 0x30(SP)
    	example4.go:18	0x104bf53	4889542438		MOVQ DX, 0x38(SP)
    	example4.go:18	0x104bf58	48895c2440		MOVQ BX, 0x40(SP)
    // See a list of the symbols in an artifact with
    // annotations and size.
    $ go tool nm example4
     104bff0 T main.createUserV1
     104c0d0 T main.createUserV2
     104c1e0 T main.init
     10b2940 B main.initdone.
     104bf10 T main.main
     106cf80 R main.statictmp_4
    */
    
    
    // Sample program to show how stacks grow/change.
    package main
    
    // Number of elements to grow each stack frame.
    // Run with 10 and then with 1024
    const size = 1024
    
    // main is the entry point for the application.
    func main() {
    	s := "HELLO"
    	stackCopy(&s, 0, [size]int{})
    }
    
    // stackCopy recursively runs increasing the size
    // of the stack.
    func stackCopy(s *string, c int, a [size]int) {
    	println(c, s, *s)
    
    	c++
    	if c == 10 {
    		return
    	}
    
    	stackCopy(s, c, a)
    }
    
    
    /*
    0 0xc420089f60 HELLO
    1 0xc420089f60 HELLO
    2 0xc420099f60 HELLO
    3 0xc420099f60 HELLO
    4 0xc420099f60 HELLO
    5 0xc420099f60 HELLO
    6 0xc4200b9f60 HELLO
    7 0xc4200b9f60 HELLO
    8 0xc4200b9f60 HELLO
    9 0xc4200b9f60 HELLO
    */
    
    

    练习

    package main
    
    import "fmt"
    
    func main() {
    
    	// Declare an integer variable with the value of 20.
    	value := 20
    
    	// Display the address of and value of the variable.
    	fmt.Println("Address Of:", &value, "Value Of:", value)
    
    	// Declare a pointer variable of type int. Assign the
    	// address of the integer variable above.
    	p := &value
    
    	// Display the address of, value of and the value the pointer
    	// points to.
    	fmt.Println("Address Of:", &p, "Value Of:", p, "Points To:", *p)
    }
    
    
    /*
    Address Of: 0xc4200140a0 Value Of: 20
    Address Of: 0xc42000c030 Value Of: 0xc4200140a0 Points To: 20
    */
    
    // Declare a struct type and create a value of this type. Declare a function
    // that can change the value of some field in this struct type. Display the
    // value before and after the call to your function.
    package main
    
    import "fmt"
    
    // user represents a user in the system.
    type user struct {
    	name        string
    	email       string
    	accessLevel int
    }
    
    func main() {
    
    	// Create a variable of type user and initialize each field.
    	bill := user{
    		name:        "Bill",
    		email:       "bill@ardanlabs.com",
    		accessLevel: 1,
    	}
    
    	// Display the value of the accessLevel field.
    	fmt.Println("access:", bill.accessLevel)
    
    	// Share the bill variable with the accessLevel function
    	// along with a value to update the accessLevel field with.
    	accessLevel(&bill, 10)
    
    	// Display the value of the accessLevel field again.
    	fmt.Println("access:", bill.accessLevel)
    }
    
    // accessLevel changes the value of the users access level.
    func accessLevel(u *user, accessLevel int) {
    
    	// Set of value of the accessLevel field to the value
    	// that is passed in.
    	u.accessLevel = accessLevel
    }
    
    
    /*
    access: 1
    access: 10
    */
    
  • 相关阅读:
    laravel excel 导入
    linux 怎么解压
    mysql分表和表分区详解
    mysql主从复制windows-》linux
    Redis和Memcache的区别
    mysql group by 用法解析(详细)
    [置顶] mysql常用函数
    mysql测试数据库employees一些sql语句
    session入mysql
    session入库
  • 原文地址:https://www.cnblogs.com/zrdpy/p/8586930.html
Copyright © 2020-2023  润新知