go基础编程day2类型、变量、常量、运算符

const var type几个关键词的简单使用

package main

import "fmt"

// 定义常量
const (
    P      = 3.14
    const1 = 1
    const2 = "2"
    const3 = 3
)

//全局变量的声明与赋值
var (
    name  = "james"
    age   = 18
    name2 = "nihao"
)

// 一般类型的声明 type关键字
type (
    newType int
    type1   float32
    type2   string
)

func main() {
    fmt.Printf("Hello %s!\n", name) // Hello james!
}

重点理解第三个type关键词,已知这些类型,int,string等等,但是type可以声明自己的类型,这里newType属于一个新的类型,但是他的基础类型还是int,但跟int并不是同一个类型newType是他的命名

go基本类型

  • 布尔型:bool
    长度:1字节
    取值范围:true、false
    注意:不能像某些语言一样使用01数字来代表true或者false

  • 整型:int/uint
    根据运行平台可能为32位(uint)或者64位(int)

  • 8位整型:int8/uint8
    长度:1字节
    取值范围:-128~127/0~255

  • 字节型:byte(uint8别名)

  • 16位整型:int16/uint16
    长度:2字节
    取值范围:-32768~32767/0~65535

  • 32位整型:int32(rune)/uint32
    长度:4字节
    取值范围:(232/2~232/2-1)/(0~2^32-1)

  • 64位整型:int64/uint64
    长度:8字节
    取值范围:同理

  • 浮点型:float32/float64
    长度:4/8字节
    精准度:精确到7/15小数位

  • 复数:complex64/complex128
    长度:8/16字节

  • 足够保存指针的32位或64位整数型:uintptr

  • 其他值类型:
    array、struct、string

  • 引用类型:
    slice、map、chan

  • 接口类型:interface

  • 函数类型:func

注意区分值类型和引用类型,会在后面变量传递的时候有区别

类型零值

零值并不等于空值,而是当变量被声明为某种类型后的默认值,就是说你在声明他的时候就存在值了,通常情况下值类型的默认值为0,比如int,就是一个0,slice就是多个或一个0,bool的默认值为false,string为空的字符串

package main

import "fmt"

func main() {
    var a int
    var b []int
    var c string
    var d bool
    fmt.Println(a)
    fmt.Println(b)
    fmt.Println(c)
    fmt.Println(d)
}

/*
0
[]

false
*/

类型别名

// 一般类型的声明 type关键字
type (
    newType int
    type1   float32
    type2   string
)

就是为类型起一个别名,注意的是基础类型与别名之后的类型并不完全对等,赋值等等需要转换

单个变量的声明与赋值

这个我刚看也有点愁人,声明和赋值的方法很多,并不是会简单好用的一种就够了,毕竟也要读别人的代码,所以必须全部掌握

第一种:声明-赋值

package main

import "fmt"

func main() {
    // 声明 var-命名-类型
    var a int
    // 赋值
    a = 111
    fmt.Println(a) // 111
}

第二种:类型推断

package main

import "fmt"

func main() {
    // 赋值并类型推断
    var a = 111
    fmt.Println(a) // 111
}

第三种:声明并赋值简单写法

package main

import "fmt"

func main() {
    // 声明并赋值简单写法
    a := 111
    fmt.Println(a) // 111
}

这些方式不仅适用int等等这些类型的声明,也适用一些其他类型的声明,所以要掌握

系统推断的声明赋值前提是在使用过程中值的类型不会发生转变,否则会抛出错误

声明赋值变量要注意的点:

  • 全局变量声明不能省略var关键字换成:=来声明

  • 多个全局变量可以使用var()进行简写

  • 所有的变量都可以使用类型推断

  • 局部变量不可以使用var()方式简写,只能使用并行方式

package main

import "fmt"

// 全局变量 支持多个变量赋值,支持并行,不可省略var
var (
    a      = "hello"
    b      = "hi"
    aa, bb = 1, 2
)

func main() {
    // 不可以使用括号,但是可以使用并行,可以省略var使用简写
    var a, b, c, d int
    a, b, c, d = 1, 2, 3, 4
        // 也可以忽略赋值,只用_来代替变量名,可用于多返回值但是不需要全部返回值的时候
        // 上面两句等价 var a, b, c, d int = 1, 2, 3, 4
    e, f, g := 5, "ss", 6
    fmt.Println(a, b, c, d, e, f, g)
}

变量的类型转换

  • go中不存在隐式转换,所有类型转换必须显式声明
  • 转换只能发生在两种相互兼容的类型之间
package main

import "fmt"

func main() {
    var a float32 = 1.1
    b := int(a)
    fmt.Println(b) // 1

    var c bool = true
    d := int(c) // cannot convert c (type bool) to type int
}

要注意数字转字符串的时候会转为对应的字母,想要真正的转换成字符串需要库strconv

package main

import "fmt"
import "strconv"

func main() {
    var a int = 65
    b := string(a)
    fmt.Println(b) // A
    // int转string
    c := strconv.Itoa(a)
    fmt.Println(c) // 65
    d, e := strconv.Atoi(c)
    fmt.Println(d)
    fmt.Println(e)
}

常量及运算符

常量的定义

  • 常量的值在编译时就已经确认
  • 常量定义格式与变量基本相同
  • 等号右侧必须是常量或者常量表达式(必须是常量,不能是运行中产生的)
  • 常量表达式中的函数必须是内置函数(自己写的函数不可以)
  • ++ --作为语句并不作为表达式 即不能放在等号右边
package main

import "fmt"

const a int = 2
const b = "A"

const (
    c = a + 1
    d = a * 3
    // 没有表达式或者常量的话会自动选择上一行的表达式,前提是这两行格式相同
    e
    f, g = 22, 33
)

func main() {
    fmt.Println(a) // 2
    fmt.Println(b) // A
    fmt.Println(c) // 3
    fmt.Println(d) // 6
    fmt.Println(e) // 6
    fmt.Println(f) // 22
    fmt.Println(g) // 33
}

常量的初始化规则与枚举

  • 在定义常量组时,如果不提供初始值,则表示将使用上行的表达式
  • 使用相同的表达式不代表具有相同的值
  • iota是常量的计数器,从0开始,组中每定义一个常量自动递增1
  • 通过初始化规则与iota可以达到枚举的效果
  • 每遇到一个const关键字,iota就会重置为0
package main

import "fmt"

const (

    // 使用双引号是会输出字符串A,单引号输出对应的数字
    a = 'A'
    b
    // 此时iota为2
    c = iota
    d
)

const (
    // 新的关键词const iota从0开始
    e = iota
)

func main() {
    fmt.Println(a) // 65
    fmt.Println(b) // 65
    fmt.Println(c) // 2
    fmt.Println(d) // 3
    fmt.Println(e) // 0
}

枚举应用

package main

import (
    "fmt"
)

const (
    a      = 0
    Monday = iota
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
    Sunday
)

func main() {
    fmt.Println(Sunday) // 7
}

运算符

  • go语言中运算符同样遵循从左至右的运算顺序
  • 优先级(从高到低)
    ^ ! (一元运算)
    * / % << >> & &^
    + - | ^ (二元运算)
    == != < <= >=
    <- (专用与channel)
    &&
    ||

新接触:
>> << 左移/右移多少位
& | ^ &^ 四个位运算符

/*
6:  0110
11: 1011

---------

两个数位运算先转换为2进制

&   0010 = 2    和
|   1111 = 15   或
^   1101 = 13   对比过程中只存在一个1则为1
&^  0100 = 4    如果第二个数对应的位置为1,则将第一个数对应的位置转换为0
之后再转换回10进制

*/

func main() {
    fmt.Println(6 & 11)  // 2
    fmt.Println(6 | 11)  // 5
    fmt.Println(6 ^ 11)  // 13
    fmt.Println(6 &^ 11)  // 4
}

单个的&变为了位运算符,&&作为‘与’运算符,左边条件不成立则右边不执行

实现计算机存储单位的枚举

const (
    B float64 = 1 << (iota * 10)
    KB
    MB
    GB
    TB
)

func main() {

    fmt.Println(B)  // 1
    fmt.Println(KB)  // 1024
    fmt.Println(MB)  // 1.048576e+06
    fmt.Println(GB)  // 1.073741824e+09
    fmt.Println(TB)  // 1.099511627776e+12
}

指针

指针属于要深入了解的东西,

  • go虽然保留了指针,但是在go中并不支持指针运算以及->运算符,而是采用.选择符来操作指针目标对象成员

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

  • 默认值为nil非NULL

package main

import (
    "fmt"
)

func main() {
    a := 1
    // 声明指向int的指针p
    var p *int
    // 赋值p
    p = &a
    fmt.Println(p) // 0xc420014100
    fmt.Println(&a) // 0xc420014100
    fmt.Println(a) // 1
}

你可能感兴趣的:(go基础编程day2类型、变量、常量、运算符)