Ⅰ. go语言的关键字

break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

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

appent bool byte cap close complex complex64 complex128 uint16
copy false float32 float64 imag int int8 int16 uint32
int32 int64 iota len make new nil panic uint64
print println real recover string true uint uint8 uintptr

举例说明

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


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