Go:基础规则介绍

时间:July 18, 2018 分类:

目录:

Go基础规则介绍

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程序通过package来组织,和python类似
  • 只有package为main的包可以包含main函数
  • 一个可执行程序中有且只有一个main包

如果执行了一个没有main包的程序会报以下错误,操作方式注释掉package main改为别的

[root@why 23:57:47 go_code]#go run hello.go 
go run: cannot run non-main package

如果没有main函数报错

[root@why 23:59:14 go_code]#go run hello.go 
# command-line-arguments
runtime.main_main·f: relocation target main.main not defined
runtime.main_main·f: undefined: "main.main"

示例组织结构

//当前程序的包名
package main

//导入其他的包
import fmt

//常量的定义
const PI = 3.14

//全局变量的声明和赋值

var name = "gopher"

//一般类型声明

type newType int 

//结构声明

type gopher struct{

}

//接口声明

type golang interface{

}

//由main函数作为程序入口点启动

func main() {
    fmt.Println("Hello, World!")
}

多个包导入

import "fmt"
import "os"
import "io"

简写

import (
    "fmt"
    "os"
    "io"
)

导入包之后可以通过<packageName>.<FuncName>进行包中函数的调用,如果导入的包未调用其中的函数或者类型会报编译错误

imported and not used: "io"

别名

import std "fmt"

省略调用

import . "fmt"

下面就可以直接使用Println("Hello, World!")

和简写多个包引入类似的

//常量定义
const (
    PI = 3.14
    const1 = "1"
    const2 = 2
)

//全局变量声明
var (
    name = "gopher"
    name1 = "1"
    name2 = 2
)

对于全局变量只是对全局时可以如此声明,对于函数体内是不能使用这种方式来声明的。

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

可见性规则

Go语言中,使用大小写来决定该类型,变量,类型,接口,结构或者函数是否可以被外部包所调用,函数名为小写的为private,而大写的为public

Go基本类型

基本类型

布尔型: bool

  • 长度:1字节
  • 取值范围:true, false
  • 注意事项:不能使用数字代替true或false

整型:int/unit

根据运行平台可能为32或者64位

8位整型:int8/unit8

  • 长度:1字节
  • 取值范围:-128~127/0~255
package main

import (
    "fmt"
    "math"
)

func main(){
    fmt.Println(math.MaxInt8)
}

字节型:byte(unit8别名)

16位整型:int16/unit16

  • 长度:2字节
  • 取值范围:-32768~32767/0~65535

32位整型:int32(别名rune)/unit32

  • 长度:4字节
  • 取值范围:-2^31~2^31-1/0~2^32-1

64位整型:int64/unit64

  • 长度:8字节
  • 取值范围:-2^63~2^63-1/0~2^63=4-1

浮点型:float32/float64

  • 长度:4/8字节
  • 取值范围:精确到7/15位小数位

复数:complex64/complex128

  • 长度:8/16字节

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

其他值类型

  • array, struct, string

引用类型

  • slice, map, chan

接口类型

  • inteface

函数类型

  • func

类型零值

零值并不等于空值,而是当变量被声明为某种类型后的默认值,通常情况下值类型的默认值为0,bool为false,string为空字符串。

可以通过程序来进行测试

package main

import (
    "fmt"
)

func main(){
    var a string
    fmt.Println(a)
}

类型别名

type (
    byte    int8
    rune    int32
    文本    string
)

定义别名甚至可以用中文

var b 文本
b = "中文"

但是可能会有坑~

变量和常量

单个变量的声明与赋值

  • 变量的声明格式:var <变量名称> <变量类型>
  • 变量的赋值格式:<变量名称> = <表达式>
  • 声明的同时赋值:var <变量名称> <变量类型> = <表达式>
  • 当然还可以省略变量类型去让golang自行匹配一下,如果想把var也省略掉,就要写成:<变量名称> := <表达式>,不过不能使用在全局变量中

多个变量的声明与赋值

  • 全局变量的声明可以使用var()的方式进行简写
  • 全局变量的声明不可以省略var,但是可以使用并行的方式
  • 所有的变量都可以使用类型判断
  • 局部变量中不可以使用var()的方式简写,只能使用并行方式var a, b, c, d = 1, 2, 3, 4

对于变量名,还有

变量类型转换

  • Go不存在隐式转换,所有类型必须显示声明
  • 转换只能发生在两种兼容的类型之间
  • 类型转换格式 [:]= ()

示例强制转换float32类型为int类型

var a float32 = 1.1
b := int(a)

示例将数字转换为字符串

package main

import (
    "fmt"
)

func main() {
    var a int = 65
    b := string(a)
    fmt.Println(b)
}

执行结果

[root@why 20:21:11 go_code]#go run temp.go
A

string()表示将数据转换成文本格式,因为计算机中存储的任何东西都是以数字形式存在,本质上都试数字,因此函数自认的认为我们需要是用数字65表示的文本A。

示例操作

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var a int = 65
    b := strconv.Itoa(a)
    // a = strconv.Atoi(b)
    fmt.Println(b)
}

常量定义

  • 常量的值在编译的时候就已经确定了
  • 常量的定义格式与变量基本相同
  • 定义常量的时候,等号右侧只能是常量或者常量表达式
  • 常量表达式中的函数必须是内置函数
  • 使用const关键字定义常量

常量名最好为全部大写,当然大写就可以被包的外部调用,所以可以在大写字母前再加一个下划线就不能被外部的包调用了

package main

import (
    "fmt"
)


const (
    a = 1
    b
    c
)

func main() {
    fmt.Println(a)
    fmt.Println(b)
    fmt.Println(c)
}

执行结果

[root@why 20:08:05 go_code]#go run changliangtest.go
1
1
1

常量初始化规则

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

运算符

Go中运算符均是从左往右结合

优先级

  • ^ ! (一元运算符)
  • * / % << >> & &^
  • + - | ^ (二元运算符)
  • == != <= =>
  • <- (专门用于channel)
  • &&
  • ||

示例

/*
 6: 0110
11: 1011
--------
&   0010 = 2       都为1为1
|   1111 = 15      一个为1就是1
^   1101 = 13      一个1一个0为1
$^  0100 = 4       第二个为1,强制把第一个改为0

指针

Go中虽然包里了指针,但是和其他语言不同,在Go中不支持指针运算及'->'运算符,而是直接采用'.'选择符来操作指针目标对象的成员

  • 操作符'&'取变量内存地址,使用'*'通过指针间接访问目标对象
  • 默认值为nil而非NULL

语句

递增递减语句

++和--作为语句而并不是作为表达式

判断语句if

if语句可以初始化,比较多样化

  • 条件表达式没有括号
  • 支持一个初始化表达式(可以是并行的模式)
  • 左大括号必须和条件语句或者else在同一行
  • 支持单行模式
  • 初始化语句中的变量为block级别,同时隐藏外部同名变量

示例代码

func main() {
    a := true
    if a, b, c := 1, 2, 3; a+b+c > 6 {
        fmt.Println("大于6")
    } else {
        fmt.Println("小于等于6")
        fmt.Println(a)
    }
    fmt.Println(a)
}

循环语句for

  • Go只有for一个循环语句关键字,但是支持三种形式
  • 初始化和步进表达式可以是多个值
  • 条件语句每次循环都会被重新检查,因此不建议在条件语句中使用函数,尽量提前计算好条件并以变量或常量代替
  • 左大括号必须和条件语句在同一行

for循环的第一种形式

直接执行,约等于python中的while,需要自动跳出

func main() {
    a := 1
    for {
        a++
        if a > 3 {
            break
        }
    }
    fmt.Println(a)
}

根据条件进行循环

func main() {
    a := 1
    for a > 3 {
        a++
    }
    fmt.Println(a)
}

第三种初始数据进行循环

func main() {
    a := 1
    for i := 0; i < 3; i++ {
        a++
    }
    fmt.Println(a)
}

选择语句switch

  • 可以使用任何类型或表达式作为条件语句
  • 不需要写break,一旦条件符合自动终止
  • 如果希望继续执行一个case,需要使用fallthrough语句
  • 支持一个初始化表达式(可以是并行方式),右侧需跟分号
  • 左大括号必须和条件语句在同一行

示例switch使用

根据a的值进行switch

func main (){
    a := 1
    switch a {
        case 0:
            fmt.Println("a=0")
        case 1:
            fmt.Println("a=1")
        default:
            fmt.Println("None")
    }
}

根据a的值进行判断

func main (){
    a := 1
    switch {
        case a >= 0:
            fmt.Println("a>=0")
        case a >= 1:
            fmt.Println("a>=1")
        default:
            fmt.Println("None")
    }
}

在switch中定义a

func main (){
    switch a := 1{
        case a >= 0:
            fmt.Println("a>=0")
        case a >= 1:
            fmt.Println("a>=1")
        default:
            fmt.Println("None")
    }
}

fallthrough可以在进行判断后继续执行

func main (){
    switch a := 1{
        case a >= 0:
            fmt.Println("a>=0")
            fallthrough
        case a >= 1:
            fmt.Println("a>=1")
        default:
            fmt.Println("None")
    }
}

跳转语句goto,break,continue

  • 三个语法都可以配合标签使用
  • 标签名区分大小写,若不使用会造成编译错误
  • break和continue配合标签可用于多层循环的跳出
  • goto是调整执行的位置,与其他两个语句配合标签的结果不同

break跳出循环,配合标签是跳出标签的循环

func main (){
    LABEL:
        for {
            for i := 0; i < 10; i++ {
                if i > 2 {
                    break LABEL
                } else {
                    fmt.Println(i)
                }
            }
        }
}

这个的打印结果为0,1,2,而不是一直循环下去

continue是跳出当次循环

func main (){
    LABEL:
        for i := 0; i < 10; i++ {
            for {
                fmt.Println(i)
                continue LABEL
            }
        }
}

打印结果也是0到9,而不是循环的输出

goto是调整程序的执行位置

func main (){
    for i := 0; i < 10; i++ {
        for {
            fmt.Println(i)
            goto LABEL
        }
    }
    LABEL:
        fmt.Println("ok")
}

输出完0之后直接跳转到LABEL了,输出了ok