Go语言 - 程序结构

1 - 声明

go语言中有四个主要声明:变量( var ) - 常量( const ) - 类型( type )- 函数( func )
例:下面的程序声明一个常量 / 一个函数 和 一对变量

package main

import "fmt"

const boilingF = 212.0

func main() {
    var f = boilingF
    var c = (f - 32) * 5 / 9
    fmt.Printf("boiling point = %gF or %gC\n", f, c)
}

下面函数 fToC 封装量温度转换的逻辑,这样可以只定义一次而在多个地方使用。这里main调用了他两次。

package main

import "fmt"

func main() {
    const free, boil = 32.0, 212.0
    fmt.Printf("%gF = %gC\n", free, fToC(free))
    fmt.Printf("%gF = %gC\n", free, fToC(boil))
}

func fToC(f float64) float64 {
    return (f - 32) * 5 / 9
}
2 - 指针

如果一个变量声明为var x int ,表达式 &x ( x 的地址 ) 获取一个指向整型的指针

x := 1  
p := &x  # p是整型指针,指向x
*p = 2   # 等于 x = 2

var x, y int
fmt.Println(&x == &x, &x == &y, &x == nil) # true false false

# =============================================
package main

import "fmt"

func f() *int {
    v := 1
    return &v
}
# 每次调用 f() 都会返回一个不同的值
func main() {
    fmt.Println(f() == f())  # false
}

# =============================================
# 因为一个指针包含变量地址。所以传递一个指针参数给函数,能够让函数更新间接传递变量值
package main

import "fmt"

func incr(p *int) int {
    *p++
    return *p
}

func main() {
    v := 1
    incr(&v)    # 副作用:v= 2
    println(incr(&v)) # "3" v = "3"
}
3 - new函数()

内置函数new() 表达式new(T)创建一个未命名的T类型变量。初始化为T类型的零值,并返回其地址。

p := new(int)
fmt.Println(*p)  # 0
*p = 2
fmt.Println(*p)  # 2
4 - 变量的声明周期

声明周期是指在程序执行过程中变量存在的时间段。

# 变量 t 在循环开始时创建,x/y 在循环的每次迭代中创建。

for t := 0.0; t < cycles*2*math.Pi; t += res{
    x := math.Sin(t)
    y := math.Sin(t*freq + phase)
    img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5),
        blackIndex)
}

# 我们在 f 函数里的x一定要使用堆空间,因为它在f函数返回后还可以从global变量访问,这种情况我们说x从f中逃逸。
# 相反,当g函数返回时,变量*y变得不可访问,可回收。因为*y不用逃逸。
# 不用逃逸在性能优化上是有好处的。因为每一次逃逸都需要额外的一次内存分配过程

var global *int
func f() {
    var x int
    x = 1
    global = &x
}

func g() {
    y := new(int)
    *y = 1
}

你可能感兴趣的:(Go语言 - 程序结构)