Ⅰ. go语言的关键字

breakdefaultfuncinterfaceselect
casedefergomapstruct
chanelsegotopackageswitch
constfallthroughifrangetype
continueforimportreturnvar

除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符:

appentboolbytecapclosecomplexcomplex64complex128uint16
copyfalsefloat32float64imagintint8int16uint32
int32int64iotalenmakenewnilpanicuint64
printprintlnrealrecoverstringtrueuintuint8uintptr

举例说明

foo #合法
foo1 #合法
_foo #合法
变量 #合法
变量1 #合法
_变量 #合法

1foo #不合法
1 #不合法
type #不合法
go #不合法

Ⅱ. 变量声明格式

<命名> <类型>

例如

x   int  //定义x为整数类型

使用var来声明变量

    var x int  //表示声明一个名为x的整数类型
    var b int = 1 // 表示声明一个名为b的整数变量,且附上初值为1
    var b = 1   //不需要声明类型自动推断

如果有多个变量同时声明,我们可以采用var加括号批量进行声明

以下方式通常用于声明全局变量

var {
        a,b int   //同时声明a,b整数
        c float64
    }

简短声明方式

变量在声明的时候如果有初始值,可以使用:=进行简短的声明方式
注意:=左边的变量不应该是已经声明过的,否则会导致编译错误

    a := 1  //声明a为1的整数
    b := int64(1)   //声明b为1的64位整数

我们知道可以在变量的初始化时省略变量的类型而由系统自动推断,声明语句写上 var 关键字其实是显得有些多余了,因此我们可以将它们简写为 a := 50 或 b := false。

a 和 b 的类型(int 和 bool)将由编译器自动推断。

这是使用变量的首选形式,但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值。使用操作符 := 可以高效地创建一个新的变量,称之为初始化声明。

如果在相同的代码块中,我们不可以再次对于相同名称的变量使用初始化声明,例如:a := 20 就是不被允许的,编译器会提示错误 no new variables on left side of :=

但是 a = 20 是可以的,因为这是给相同的变量赋予一个新的值。如果你在定义变量 a 之前使用它,则会得到编译错误 undefined: a

如果你声明了一个局部变量却没有在相同的代码块中使用它,同样会得到编译错误,例如下面这个例子当中的变量 a:

例子:

    package main

    import "fmt"

    func main() {
       var a string = "abc"
       fmt.Println("hello, world")
    }

尝试编译这段代码将得到错误 a declared and not used。
此外,单纯地给 a 赋值也是不够的,这个值必须被使用

所以解决方法:fmt.Println("hello, world", a)会移除错误。

全局变量是允许声明但不使用。 同一类型的多个变量可以声明在同一行,如:
var a b c int

多变量可以在同一行进行赋值,如:

    var a, b int
    var c string
    a, b, c = 5, 7, "abc"

上面这行假设了变量 a,b 和 c 都已经被声明,否则的话应该这样使用:
a, b, c := 5, 7, "abc"
右边的这些值以相同的顺序赋值给左边的变量,所以 a 的值是 5, b 的值是 7,c 的值是 "abc"。
这被称为 并行同时 赋值
如果你想要交换两个变量的值,则可以简单地使用 a, b = b, a。

空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。
_ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。

并行赋值也被用于当一个函数返回多个返回值时,比如这里的 val 和错误 err 是通过调用 Func1 函数同时得到:val, err = Func1(var1)。

常量定义

1、定义的时候,必须制定值
2、指定的类型主要有三类,布尔,数字,字符串,其中数字类型包含rune,interger,floating-point,complex,它们都属于基本数据类型。
3、不能使用 :=

常量定义格式
const identifier [type] = value

你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。

  • 显式类型定义: const b string = "abc"
  • 隐式类型定义: const b = "abc"

多个相同类型的声明可以简写为:

const c_name1, c_name2 = value1, value2

    const a=64   //定义常量值为64的值

    const {      //常量用作枚举
        b = 4
        c = 0.1
    }

下列是常量的应用代码:

    package main

    import "fmt"

    func main() {
       const LENGTH int = 10
       const WIDTH int = 5   
       var area int
       const a, b, c = 1, false, "str" //多重赋值

       area = LENGTH * WIDTH
       fmt.Printf("面积为 : %d", area)
       println()
       println(a, b, c)   
    }

以上实例运行结果为:

面积为 : 50
1 false str

常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:

    package main

    import "unsafe"
    const (
        a = "abc"
        b = len(a)
        c = unsafe.Sizeof(a)
    )

    func main(){
        println(a, b, c)
    }

以上代码的运行结果:
abc 3 16

最后输出为16的原因
字符串类型在 go 里是个结构, 包含指向底层数组的指针和长度,这两部分每部分都是 8 个字节,所以字符串类型大小为 16 个字节。

iota

iota,特殊常量,可以认为是一个可以被编译器修改的常量。

在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1。

iota 可以被用作枚举值:

    const (
        a = iota
        b = iota
        c = iota
    )

第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式:

    const (
        a = iota
        b
        c
    )

iota 用法

    package main

    import "fmt"

    func main() {
        const (
                a = iota   //0
                b          //1
                c          //2
                d = "ha"   //独立值,iota += 1
                e          //"ha"   iota += 1
                f = 100    //iota +=1
                g          //100  iota +=1
                h = iota   //7,恢复计数
                i          //8
        )
        fmt.Println(a,b,c,d,e,f,g,h,i)
    }

以上实例运行结果为:
0 1 2 ha ha 100 100 7 8

看个有趣的的 iota 实例:

    package main

    import "fmt"
    const (
        i=1<<iota
        j=3<<iota
        k
        l
    )

    func main() {
        fmt.Println("i=",i)
        fmt.Println("j=",j)
        fmt.Println("k=",k)
        fmt.Println("l=",l)
    }

以上实例运行结果为:
i= 1
j= 6
k= 12
l= 24

iota 表示从 0 开始自动加 1,所以 i=1<<0, j=3<<1(<< 表示左移的意思),即:i=1, j=6,这没问题,关键在 k 和 l,从输出结果看 k=3<<2,l=3<<3

简单表述:

i=1:左移 0 位,不变仍为 1;
j=3:左移 1 位,变为二进制 110, 即 6;
k=3:左移 2 位,变为二进制 1100, 即 12;
l=3:左移 3 位,变为二进制 11000,即 24。

完整代码实例:

    package main
    func main(){
        var too string
        var too2 string = "hello"
        var(
            foo3,foo4 string
        )
        foo5 := "hello"  //不带声明格式的只能出现在函数体
        const c1 = 3
        const (
            c2 = 4
            c3 = 5
        )
        c3 = 1   //报错:常量值不可再被修改 
    }

版权声明:本文为原创文章,版权归 heroyf 所有
本文链接: https://heroyf.club/2018/06/09/go-lesson1


“苹果是给那些为了爱选择死亡的人的奖励”