Golang学习笔记(二):类型、变量、常量

基本类型

1.基本类型列表


类型        长度     说明

bool         1      true/false,默认false, 不能把非0值当做true(不用数字代表true/false)

byte         1      uint8 别名

rune         4      int32别名。 代表一个unicode code point

int/unit            一来所运行的平台,32bit/64bit

int8/uint8   1     -128 ~ 127; 0 ~ 255

int16/uint16 2     -32768 ~ 32767; 0 ~ 65535

int32/uint32 4     -21亿 ~ 21亿, 0 ~ 42亿

int64/uint64 8

float32      4     精确到7位小数,相当于c的float float64      8     精确到15位小数,相当于c的double

complex64    8 complex128   16

uintptr            足够保存指针的32位、64位整数,指针(可以存指针的整数型) array              值类型,数组 struct             值类型,结构体 string             值类型,字符串类型,常用 slice              引用类型,切片 map                引用类型,字典 channel            引用类型,通道 interface          接口类型,接口 function           函数类型,函数

2.类型转换

不支持隐式类型转换,必须进行显式类型转换

转换只发生在两种互相兼容的类型之间: 各类int不允许相互赋值或操作,不然会在编译时报错


<type>(expression)


示例

package main

import "fmt"

func main(){     a := 0x1234     b := 1234.56     c := 256

    fmt.Printf("%x\n", uint8(a))     fmt.Printf("%d\n", int(b))     fmt.Printf("%f\n", float64(c)) }


结果

34

1234

256.000000

3.类型别名


type t_str string

var b t_str = "a str"


4.类型默认值

声明不赋值,类型零值,非空值,而是声明后的默认值


bool: false

integers: 0

floats: 0.0

string: ""

pointers,functions,interfaces,slices,channels,maps: nil

保留字


break      case   chan     const        continue

default    defer  else     fallthrough  for

func       go     goto     if           import

interface  map    package  range        return

select     struct switch   type         var

变量

1.变量声明


//第一种,指定变量类型,声明后若不赋值,使用默认值

var v_name v_type

v_name = value

//第二种,根据值自行判定变量类型 var v_name = value

//第三种,省略var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误. v_name := value

e.g. var a int = 10 var b = 10 c : = 10

示例:


package main

var a = 1234

var b string = "hello"

var c bool

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

结果:


1234 hello false

2.多变量声明:


//类型相同多个变量, 非全局变量

var vname1, vname2, vname3 type

vname1, vname2, vname3 = v1, v2, v3

var vname1, vname2, vname3 = v1, v2, v3 //和python很像,不需要显示声明类型,自动推断

vname1, vname2, vname3 := v1, v2, v3 //出现在:=左侧的变量不应该是已经被声明过的,否则会导致编译错误

//类型不同多个变量, 全局变量, 局部变量不能使用这种方式 var (     vname1 v_type1     vname2 v_type2 )


示例:

package main

var x, y int var (  //这种只能出现在全局变量中,函数体内不支持     a int     b bool )

var c, d int = 1, 2 var e, f = 123, "hello"

//这种不带声明格式的只能在函数体中出现 //g, h := 123, "hello"

func main(){     g, h := 123, "hello"     println(x, y, a, b, c, d, e, f, g, h) }


结果:

0 0 0 false 1 2 123 hello 123 hello

注意:

A.多变量赋值时,将先行计算所有左侧变量的值,再进行赋值


    i := 0

    i, l[i] = 1, 2

    //get i = 1, l[0] = 2

    sc[0], sc[0] = 1, 2     //get sc[0] = 2


B.垃圾桶_

    func test()(int, string) {

        return 123, "abc"

    }

    a, _ := test()

C.已声明但是没有使用的变量会在编译阶段报错,较Python 更为严格

常量

常量可以是字符,字符串,布尔或数字

常量赋值是编译期的行为

1.常量声明

在编译阶段就能确定下来的值,在运行时无法改变该值
常量可以定义为数值、布尔值或字符串等类型


const constantName = value

const Pi float32 = 3.1415926

const c_name [type] = value const c_name1, c_name2 = value1, value2 const (     c_name1 = vluae1     c_name2 = value2 )

=右侧,必须为常量或常量表达式,如果使用到了函数,必须为内置函数(编译期行为)

const i = 10000

说明:


A.常量必须是编译期能确定的Number(char/integer/float/complex)、String和bool

B.在定义常量数组时,如果不提供初始化值,则表示与上行常量类型,值,完全相同

    const (         a = "abc"         b     )     //则 b = "abc"

C.常量可以用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

枚举

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

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

不提供初始值,则表示使用上一行的表达式

1.声明:

iota生成从0开始的自动增长枚举值,意味着,多一个枚举值,iota+=1,无论是否使用

基本语法


const (

    a = 1

    b = 2

)

const (     a = iota //0     b  //1     c  //2 )

const (     _ = iota     a    //1     b    //2 )

iota用法


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

    )

}

const (     x = iota // 0     y = iota // 1     z = iota // 2     w //省略,默认和前面一样字面值   w = iota, 即3 ) const v = iota //遇到const关键字,iota重置

注意: 每行的变量数必须一致 const ( A, B = iota, iota C, D E, F )


func main() {

    println(A,B,C,D,E,F)

}

//结果: 0 0 1 1 2 2   【各自增长】

运算符

Go运算符全部是从左到右结合的

不支持运算符重载


优先级    运算符                        说明

  高   * / % << >> & &^(AND NOT)

       + - ! ^

       == != < <= > >=

       <-                             channel运算符

       &&

  低   ||


在go中,++ --为语句,而非表达式

package main

func main(){     i := 1     i ++     println(i)

    b := i     println(b)

    //syntax error: unexpected ++, expecting semicolon or newline or }     //c := i++     //意味着, ++/--不能出现在等号右侧 }

指针

Go保留了指针, *T表示T对应的指针类型

如果包含包名, 则应该是 *.T

代表指针类型的符号 '*' 总是和类型放在一起,而不是紧挨着变量名

同样支持指针的指针**T

1.声明


var a, b *int


2.说明

操作符&取变量地址,用*透过指针变量间接访问目标对象

默认值是nil,没有NULL常量

不支持指针运算,不支持‘->'预算福,直接'.'选择符操作指针目标对象成员

可以在unsafe.Pointer和任意类型指针间进行转换

可以将unsafe.Pointer转换为uintptr,然后变相做指针运算,uintptr可以转换为整数

3.示例


package main

import "fmt"

type User struct {     Id int     Name string } func main(){     i := 100     var p *int = &i  //取地址

    println(*p)   //取值

    up := &User{1, "Jack"}     up.Id = 100  //直接取只针对想成员     fmt.Println(up)

    u2 := *up  //拷贝对象     u2.Name = "Tom"     fmt.Println(up, u2) }

4.结果:


100

&{100 Jack}

&{100 Jack} {100 Tom}


分组声明

import (

    "fmt"

    "os"

)

const (     i = 100  //首行必须有常量表达式     pi = 3.1415 )

var (  //全局变量可用,函数体内不支持     i int     pi float32 )