结构体-学习Go语言

阅读笔记

pointers.go

package main

import "fmt"

func main() {
    i, j := 42, 2701

    p := &i         // point to i
    fmt.Println(*p) // read i through the pointer
    *p = 21         // set i through the pointer
    fmt.Println(i)  // see the new value of i

    p = &j         // point to j
    *p = *p / 37   // divide j through the pointer
    fmt.Println(j) // see the new value of j
}

笔记

Go 拥有指针。指针保存了值的内存地址。

类型 *T 是指向 T 类型值的指针。其零值为 nil。
& 操作符会生成一个指向其操作数的指针。
这也就是通常所说的“间接引用”或“重定向”。

structs.go

package main

import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    fmt.Println(Vertex{1, 2})
}

笔记

  1. 这个不是c语言的结构体是一样的吗?

struct-fields.go

package main

import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    v.X = 4
    fmt.Println(v)
}

笔记

  1. 内部实现是否类似c语言的指针?

struct-pointers.go

package main

import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    p := &v
    p.X = 1e9
    fmt.Println(v)
}

笔记

  1. v 和 p 都是指向结构体的指针吧
  2. p使用隐式间接引用

struct-literals.go

package main

import "fmt"

type Vertex struct {
    X, Y int
}

var (
    v1 = Vertex{1, 2}  // has type Vertex
    v2 = Vertex{X: 1}  // Y:0 is implicit
    v3 = Vertex{}      // X:0 and Y:0
    p  = &Vertex{1, 2} // has type *Vertex
)

func main() {
    fmt.Println(v1, p, v2, v3)
}

笔记

  1. 结构体会初始化字段的默认值
  2. 特殊的前缀 & 返回一个指向结构体的指针。

参考链接

  1. 指针
  2. 结构体
  3. 结构体字段
  4. 结构体指针
  5. 结构体文法

控制流程-学习Go语言

阅读笔记

if-with-a-short-statement.go

package main

import (
    "fmt"
    "math"
)

func pow(x, n, lim float64) float64 {
    if v := math.Pow(x, n); v < lim {
        return v
    }
    return lim
}

func main() {
    fmt.Println(
        pow(3, 2, 10),
        pow(3, 3, 20),
    )
}

笔记

同 for 一样, if 语句可以在条件表达式前执行一个简单的语句。

该语句声明的变量作用域仅在 if 之内。

(在最后的 return 语句处使用 v 看看。)

1. 这个特性很好。
2. if 的条件表达类似于PHP的表达式。
   if ( v = math.Pow(x,n) && v < lim){}

参考链接

  1. if
  2. if 的简短语句
  3. if 和 else

函数值-学习Go语言

阅读笔记

functions-values.go

package main

import (
    "fmt"
    "math"
)

func compute(fn func(float64, float64) float64) float64 {
    return fn(3, 4)
}

func main() {
    hypot := func(x, y float64) float64 {
        return math.Sqrt(x*x + y*y)
    }
    fmt.Println(hypot(5, 12))

    fmt.Println(compute(hypot))
    fmt.Println(compute(math.Pow))
}

笔记

函数也是值。它们可以像其它值一样传递。
函数值可以用作函数的参数或返回值。
1. 函数可以传值进去
2. 5 12 的平方根 = 13
3. (fn func(float64, float64) float64) 包含起来会好理解些,可以认为是一个申明。

functions-closures.go

package main

import "fmt"

func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

func main() {
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
        fmt.Println(
            pos(i),
            neg(-2*i),
        )
    }
}

笔记

  1. Go 函数可以是一个闭包。闭包是一个函数值,它引用了其函数体之外的变量。该函数可以访问并赋予其引用的变量的值,换句话说,该函数被“绑定”在了这些变量上。
  2. 可以想一想JavaScirpt的闭包概念,和Go的闭包是不是有一些类似?

参考链接

  1. 函数值
  2. 函数的闭包