目录
  • 导包
  • 工程管理
  • 变量
    • 变量声明
    • 格式化输出
    • 基本数据类型
    • 强制类型转换
    • 接收键盘输入
  • 常量
    • 常量声明
    • iota 枚举
  • 运算符
    • 算术运算符
    • 赋值运算符
    • 关系运算符
    • 逻辑运算符
  • 条件语句
    • if 语句
    • switch 语句
  • 循环语句
    • 函数
      • 函数定义
      • 参数列表
      • 函数返回值
      • 函数类型
      • 匿名函数
      • 递归函数

    导包

    示例:工程结构如下

    GOPATH 设置为工程根目录(E:\GO_PROJECT)

    test1.go

    package package_test
    
    import "fmt"
    
    /*
    定义函数
    */
    func Func1() {
        fmt.Println("test1 func1")
    }
    

    test2.go

    package package_test
    
    import "fmt"
    
    func Func2() {
        fmt.Println("test2 func2")
    }
    

    testmain.go

    package main
    
    import "dir1/dir2"  // 导入的是【目录名】
    
    func main() {
        package_test.Func1()  // 调用的是【包名】
    }
    

    运行:

    // 方式一
    go bulid testmain.go  // 编译(生成可执行文件)
    ./ testmain  // 运行(可执行文件)
    
    //方式二
    go run testmain.go  // 编译+运行
    

    导包结论:

    一个 GO 程序中一定要有 main 包和 main 函数,这是 GO 程序执行的入口。

    编译器会根据指定的相对路径去搜索包然后导入,这个相对路径是从 GOROOT 或 GOPATH(workspace)下的 src 下开始搜索:

    • GOROOT
    • 项目 GOPATH
    • 全局 GOPATH

    GOlang 和 Java 的区别是,在 GO 中 import 的是目录,而不是包名;并且 GO 没有强制要求包名和目录名需要一致,即包和目录是两个不同的概念。

    import 导入的是源文件所在的目录名,而不是定义的包名。

    在代码中引用包内的成员时,使用定义的包名而不是目录名。

    在习惯上将包名和目录名保证一致,但这并不是强制规定。

    在同一级目录中,所有源文件只能使用相同的包名。

    同一包名下的变量名、函数名等不能重复。

    多个目录下的相同包名,彼此无关。

    包中的成员(如函数)以名称⾸字母⼤⼩写,决定其访问权限:

    • ⾸字母⼤写,可被包外访问(即public
    • ⾸字母⼩写,仅包内成员可以访问(即private

    工程管理

    为了更好的管理项目中的文件,GO 要求将文件都要放在相应的目录中,具体规定了以下目录:

    • src 目录:以代码包的形式组织并保存 GO 源码文件(比如 .go 文件、.c 文件、.h 文件、.s 文件等)
    • pkg 目录:用于存放经由 go install 命令构建安装后的代码包(包含 GO 库源码文件)的 ".a" 归档文件。
    • bin 目录:与 pkg 目录类似,在通过 go install 命令完成安装后,保存由 GO 命令源码文件生成的可执行文件。

    以上目录称为工作区(Workspace),工作区其实就是一个对应于特定工程的目录。

    src 目录用于包含所有的源代码,是 GO 命令行工具一个强制的规则;而 pkg 和 bin 则无需手动创建,GO 命令行工具在构建过程中会自动创建这些目录。

    变量

    变量声明

    • 变量名必须以字母或下划线开头,后面可以跟任意数量的字母、数字或下划线。
    • 变量的三种声明&初始化方式如下:

    // 方式一:先声明(有默认值),后赋值
    var a int
    a = 10
    var b, c string
    b = "b"
    c = "c"
    
    // 方式二:声明+赋值
    var a int = 10
    
    // 方式三:自动推导类型(注意:这种方式只能在函数内使用)
    a := 10
    b, c := 11, 12
    b, c = c, b  // 值交换
    
    // 匿名变量
    _, i, _, j = 1, 2, 3, 4
    

    格式化输出

    格式含义
    %%一个 % 字面量
    %b一个二进制整数值(基数为 2),或者是一个(高级的)用科学计数法表示的指数为 2 的浮点数
    %c字符型。可以把输入的数字按照 ASCII 码相应转换为对应的字符
    %d一个十进制数值(基数为 10)
    %f以标准记数法表示的浮点数或者复数值
    %o一个以八进制表示的数字(基数为8)
    %p以十六进制(基数为 16)表示的一个值的地址,前缀为 0x,字母使用小写的 a-f 表示
    %q使用 GO 语法以及必须时使用转义,以双引号括起来的字符串或者字节切片 []byte,或者是以单引号括起来的数字
    %s字符串。输出字符串中的字符直至字符串中的空字符(字符串以 '\0' 结尾,这个 '\0' 即空字符)
    %t以 true 或者 false 输出的布尔值
    %T使用 GO 语法输出的值的类型
    %x以十六进制表示的整型值(基数为十六),数字 a-f 使用小写表示
    %X以十六进制表示的整型值(基数为十六),数字 A-F 使用小写表示

    基本数据类型

    类型名称长度零值(默认值)说明
    bool布尔类型1false其值不为真即为假,不可以用数字代表 true 或 false
    byte字节型10uint8 的别名
    int, uint整型-0有符号 32 位或无符号 64 位
    int8整型10-128 ~ 127
    uint8整型100 ~ 255
    int16整型20-32768 ~ 32767
    uint16整型200 ~ 65535
    int32整型40-2147483648 到 2147483647
    rune整型40int32 的别名
    uint32整型400 到 4294967295(42 亿)
    int64整型80-9223372036854775808到 92233720368547758070
    uint64整型80到 18446744073709551615(1844 京)
    float32浮点型40.0小数位精确到 7 位
    float64浮点型80.0小数位精确到 15 位
    string字符串-""utf-8 字符串

    值的字面量(literal)是指代码中值的文字表示。一个值可能存在多种字面量表示。

    表示基本类型值的文本称为基本字面量。基本字面量也被称为字面量常量或未命名常量。

    示例:

    func main() {
        var ch byte = 97  // 声明字符类型
        fmt.Printf("ch=%c", ch)  //  输出 a
    }
    

    这里定义了 ch 是一个字符类型,赋值却是一个整数 97,打印的结果是小写字符 'a'。

    原因是:计算机不能直接存储字符类型,只能转成数字存储,那为什么小写字符 'a' 对应的整数是 97 呢?因为计算机是根据 ASCII 码来存储的。

    强制类型转换

    package main
    
    import "fmt"
    
    func main() {
    
        chinese := 97
        math := 99
        english := 96
    
        fmt.Printf("总分是 %d,平均分(整数)是 %d, 平均分(浮点数)是 %f", chinese+math+english, (chinese+math+english)/3, float32(chinese+math+english)/3)
        // 总分是 292,平均分(整数)是 97, 平均分(浮点数)是 97.333336
    }
    

    注意:

    GO 语言中不允许隐式转换,所有类型转换必须显式声明(强制转换),而且转换只能发生在两种相互兼容的类型之间

        var ch byte = 'c'
        // var a int = ch  // cannot use ch (type byte) as type int in assignment
        var b int = int(ch)  // 数据类型名(待转换的值)
    

    • int 转 float 强制转换:多小数
    • float 转 int 强制转换:丢精度

    接收键盘输入

    package main
    
    import fmt
    
    func main() {
        var age int
        fmt.Println("请输入年龄:")
        fmt.Scanf("%d", &age)  // 将接收的值赋给age变量
        fmt.Printf("age=%d", age)
    }
    

    常量

    常量声明

    func main() {
        // 变量:程序运行期间,值可以改变,声明使用var
        // 常量:程序运行期间,值不可以改变,声明使用const
        const a int = 11
        // a = 12  // error:常量不可以修改
        
        const b = 12 // 自动推导类型(常量不可以使用:=)
    }
    

    iota 枚举

    iota 常量生成器:用于生成一组递增的整型常量,减去了每行都要写一遍初始化表达式的繁琐。

    func main() {
    
        // 在一个 const 声明语句中,在第一个声明的常量所在的行,iota 将会被置为 0,然后在每一个有常量声明的行递增 1
        const (
            a = iota  // 0
            b = iota  // 1
            c = iota  // 2
        )
    
        const d = iota // iota 遇到const,会被置为 0
    
        // 可以只写一个iota
        const (
            e = iota  // 0
            f // 1
            g
        )
    
        // 同一行值一样
        const (
            h = iota  // 0
            i, j, k = iota, iota, iota  // 1
            l = iota  // 2
        )
    
    }
    

    运算符

    算术运算符

    运算符术语
    +加(既可以完成两个数字相加,又可以连接两个字符串)
    -
    *
    /
    %取模(取余)
    ++后自增(GO 语言中没有前自增)
    --后自减(GO 语言中没有前自减)

    赋值运算符

    运算符说明示例
    =普通赋值c = a + b 将 a + b 表达式结果赋值给 c
    +=相加后再赋值c += a 等价于 c = c + a
    -=相减后再赋值c -= a 等价于 c = c - a
    *=相乘后再赋值c *= a 等价于 c = c * a
    /=相除后再赋值c /= a 等价于 c = c / a
    %=求余后再赋值c %= a 等价于 c = c % a

    关系运算符

    运算符术语示例结果
    ==相等于4 == 3false
    !=不等于4 != 3true
    <小于4 < 3false
    >大于4 > 3true
    <=小于等于4 <= 3false
    >=大于等于4 >= 1true

    逻辑运算符

    运算符术语示例结果
    !!a如果 a 为假,则 !a 为真
    如果 a 为真,则 !a 为假
    &&a && b如果 a 和 b 都为真,则结果为真,否则为假
    ||a || b如果 a 和 b 有一个为真,则结果为真,二者都为假时,结果为假

    条件语句

    if 语句

    package main
    
    import "fmt"
    
    func main() {
    
        var score int
        fmt.Println("请输入成绩:")
        fmt.Scanf("%d", &score)
    
        // if 语句支持一个初始化语句+判断条件
        if good_score := 90; score >= good_score {
            fmt.Println("优秀")
        } else if soso_score := 60; score >= soso_score {
            fmt.Println("及格")
        } else {
            fmt.Println("需要努力")
        }
    }
    

    switch 语句

    注意:case 后面默认自带 break,如果想执行完成某个 case 后继续执行后面的 case,可以使用 fallthrough 关键字。

    func main() {
    
        bonus := 5000
        var score string
        finish := true
        fmt.Println("请输入年终评级:")
        switch fmt.Scanf("%s", &score); score {
        case "A":
            bonus += 1000
        case "B":
            bonus += 5000
        case "C":
        case "D":
            bonus -= 1000
        default:
            finish = false
            fmt.Println("输入有误,请输入正确的评级")
        }
        if finish {
            fmt.Printf("您的年终奖为:%d", bonus)
        }
    
    }
    

    循环语句

    GO 中的 3 种循环方式:

    package main
    
    import "fmt"
    
    func main() {
    
        // 第1种方式
        for i := 0; i < 5; i++ {
            fmt.Printf("i=%d\n", i)
        }
    
        // 第2种方式:类似while循环
        num := 1
        for num < 5 {
            fmt.Printf("num=%d\n", num)
            num++
        }
    
        // 第3种方式
        for {
            fmt.Println("死循环")
        }
    }
    

    函数

    函数定义

    函数就是将一堆代码进行封装,以便重用的一种机制。

    func 函数名(){
        函数体
    }
    

    参数列表

    import "fmt"
    
    func MyFunc(a int, b int, args ...int) {  // 注意:不定长参数必须放在参数列表最后
        fmt.Println("定长参数为:", a, b)
        for i, data := range args {  // 若不需要编号,则可使用 for _, data := range args
            fmt.Println("编号为:", i)
            fmt.Println("数据为:", data)
        }
    }
    
    func main() {
        MyFunc(1, 2, 3, 4, 5)
    }
    

    打印结果:

    定长参数为: 1 2
    编号为: 0
    数据为: 3
    编号为: 1
    数据为: 4
    编号为: 2
    数据为: 5

    函数返回值

    // 定义返回值类型
    func Add(a int, b int) int {
        return a + b
    }
    
    // 给返回值命名
    func Sub(a int, b int) (sub int) {
        sub = a - b
        return sub  // 也可以只写 return
    }
    
    // 返回多个值
    func Sub(a, b, c int) {
        a, b, c = 1, 2, 3
        return a, b, c  // 也可以只写 return
    }
    

    函数类型

    在 GO 语言中还有另外一种定义使用函数的方式,就是函数类型。

    所谓的函数类型,就是将函数作为一种类型可以用来定义变量,基本使用如下:

    func Test(a, b int) int {
        return a + b
    }
    
    // 定义函数类型:即需要传递两个整型参数,有一个整型返回值的函数类型
    type FuncType func(a int, b int) int  // type关键字后面跟着类型的名字(FunType)
    
    func main() {
        var result FuncType  // 类型是FuncType类型,即函数类型
        result = Test
        s := result(1, 2)
        fmt.Printf("s=%d", s)
    }
    

    匿名函数

    所谓匿名函数就是没有名字的函数。匿名函数最主要的功能就是实现了闭包。

    package main
    
    import "fmt"
    
    func main() {
        num := 9
    
        // 使用方式一:定义匿名函数并赋值给变量
        f1 := func() {
            // 在匿名函数中可以直接访问main()中定义的局部变量
            // 并且在匿名函数中对变量的值进行了修改,最终会影响到整个main()函数中定义的变量值
            num++
            fmt.Println("匿名函数:", num)
        }
        f1()                        // 10
        fmt.Println("main函数:", num) // 10
    
        // 使用方式二:通过函数类型
        type FuncType func() // 没有参数,没有返回值
        var f2 FuncType = f1
        f2()
    
        // 使用方式三:直接调用
        func(a, b int) {
            fmt.Println("a + b =", a+b)
        }(3, 6)
    
        // 有参有返回值的匿名函数
        min, max := func(a, b int) (min, max int) {
            if a > b {
                return b, a
            } else {
                return a, b
            }
        }(12, 13)
        fmt.Printf("min=%d, max=%d\n", min, max)
    }
    

    递归函数

    示例:阶乘

    func Test(num int) int {
        if num == 1 {
            return 1
        }
        return num * Test(num-1)
    }
    
    func main() {
        var num int
        fmt.Println("请输入需要阶乘的数:")
        fmt.Scanf("%d", &num)
        fmt.Printf("%d的阶乘结果为:%d", num, Test(num))
    }
    

    以上就是一文详解Golang中的基础语法的详细内容,更多关于Golang基础语法的资料请关注本网站其它相关文章!

    您可能感兴趣的文章:

    • Go语言基础语法和基本数据类型知识巩固
    • Go语言入门之基础语法和常用特性解析
    • Go语言基础语法之结构体及方法详解
    • go语言基础语法示例
    • Go语言入门教程之基础语法快速入门
    • Go基础语法的使用