零值:nil
    方法定义中接受者为指针,传进去的既可以是指针又可以是值。
    方法定义中函数参数为指针,传进去的只能是指针。

    v.Scale(5) 可以解释为 (&v).Scale(5),也可以解释为 (v).Scale(5),关键是看函数 Scale 的接收器是否是指针,v 是否是指针。
    如同把 p.X 解释为 (
    p).X

    通过 = 可以把普通类型赋值给一个接口类型变量,需要有两个前提:

    • 这个普通类型实现了接口里声明的方法(也就是接口中的方法的接受器是该变量类型)
    • 普通类型必须和方法的接收器类型保持一致

    fmt.Println 背后是 Stringer 接口

    ————————————
    变量声明时初始化可以忽略类型(「var =」语法),变量会从初始值中获取类型

    var a, b int = 1, 2
    var c, d = 1, 2
    并且 「var =」可以用 「:=」来代替,但是由于函数外必须以关键字开头,所以 「:=」不能出现在函数外
    ———————————-
    常量使用「const =」语法,不能使用「:=」语法
    ———————————-
    defer 栈,defer 语句
    ———————————
    结构体的初始化使用 typeName{},相当于普通变量初始化等号的右边。
    初始化结构体中特定字段使用 : 而不是 =
    (*p).X == p.X
    ——————————-
    数组的初始化和结构体一样,typeNameP{}
    ———————————
    切片的文法和就像没有长度的数组 []int{3, 4, 6}
    没有底层数组的切片为 nil 。
    ——————————-
    映射要通过 make(map[keyType]ValType) 初始化,因为其零值为 nil ,不能直接用。
    当然也有映射的文法。

    1. var mm = map[int]string {
    2. 3: "aaa",
    3. 5: "bbb",
    4. }