Go-基本语法(变量、常量、枚举、switch、for、函数、指针)

一、变量定义

package main

import "fmt"

func variable()  {
    // 使用var定义变量名称及类型【不常用】
    var a int = 8
    var b bool
    var c int
    fmt.Println( a,b,c) // 8 false 0

    // 通过var批量定义变量名称及值,不定义类型,Go会自动识别变量类型【不常用】
    var d,e,f = 36, "abc", "false"
    fmt.Println(d,e,f) // 36 abc false

    // 初始化变量值方式定义变量【常用】
    g,h,i := 666,"test_888",0.56
    // 如果需要重新对某个变量赋值时,需要保持数据类型与该变量初始化时的类型相同,否则会编译不通过
    h = "test_999"
    fmt.Println(g,h,i)
}

// 在函数外面定义变量,就不能用 := 了,只能用var = 方式
var j = 6
var k,l,m = 888,"test_111","true"

// 在函数外面批量定义变量
var (
    n = 3
    o = "this is o"
    p = "this is p"
)

func main() {
    variable()
    fmt.Println(j,k,l,m)
    fmt.Println(n,o,p)
}

 

二、Go的内建变量类型

bool、string

(u)int、 (u)int8、(u)int16、(u)int32、(u)int64、uintptr

byte、rune

float32、float64、complex64、complex128

 

三、常量定义

package main

import "fmt"

// 注意,定义常量时可以指定常量类型,也可以不指定常量类型让Go自动识别

// 函数外面定义常量,所有函数都可以用
const myName = "haveyb"
const sex int = 1

// 函数内部定义常量,只有函数内部可以用
func constMethod() {
    const fileName = "abc.png"
    const a, b = 3, "this is a string"
    // 也可以用括号形式定义常量
    const (
        d = 666
        e string = "this is e_777"
        f = "aaa"
        g int = 999
    )
    fmt.Println(fileName, a, b, d, e, f, g) 
}

func main() {
    constMethod()
    fmt.Println(myName, sex)
}

值得注意的是,在其他语言中,常量定义时通常会将常量名全部大写,但是在Go中,首字母大小写是有含义的,分别表示public和private

 

四、枚举类型

package main

import "fmt"

// 定义枚举
func enumMethod() {
    const (
        a = 1
        b = 2
        c = 3
        d = 4
    )
    fmt.Println(a,b,c,d)
}

// 使用iota定义自动枚举, 使用iota默认第一个元素是0,你可以在此基础上进行扩展运算,比如1 + iota,那元素值就从01234变成了12345
func enumCommonMethod() {
    const (
        C = iota
        PHP
        Python
        Java
        Golang
    ) 
    fmt.Println(C,PHP,Python,Java,Golang)
}

// 使用iota定义表达式枚举
func enumSpecialMethod() {
    const (
        B = 1 << (10 * iota)
        KB
        MB
        GB
        TB
        PB
    )
    fmt.Println(B,KB,MB,GB,TB,PB)
}

func main() {
    enumMethod() // 1 2 3 4
    enumCommonMethod() // 0 1 2 3 4
    enumSpecialMethod() // 1 1024 1048576 1073741824 1099511627776 1125899906842624
}

 

五、switch语句

第一种定值方式:

func eval(a int, b int, op string) int {
    var result int
    switch op {
        case "+":
            result = a + b
        case "-":
            result = a - b
        case "*":
            result = a * b
        case "/":
            result = a / b
        default:
            panic("unsupported operator:" + op)
    }
    return result
}

第二种表达式方式:

func mark(score int) string {
    grade := ""
    switch {
        case score < 60:
            grade = "不及格"
        case score < 70:
            grade = "及格"
        case score < 80:
            grade = "良好"
        case score <= 100:
            grade = "优秀"
    }
    return grade
}

func main() {
    fmt.Println(mark(95))
}

 

六、for循环

1、简单的for循环

func test() int{
    sum := 0
    for i := 1; i <= 100; i++ {
        sum += i
    }
    return sum
}

func main() {
    fmt.Println(test())
}

2、省略初始值

func convertToBin(n int) string {
    result := ""
    for ; n > 0; n /= 2 {
        lsb := n % 2
        result = strconv.Itoa(lsb) + result
    }
    return result
}

func main() {
    fmt.Println(
        convertToBin(3), // 11
        convertToBin(5), // 101
        convertToBin(10), // 1010
    )
}

3、死循环

func forever() {
    for {
        fmt.Println("aaa")
    }
}

func main() {
    forever()
}

 

七、函数

返回1个值
func eval(a int, b int, op string) int {
    var result int
    switch op {
        case "+":
            result = a + b
        case "-":
            result = a - b
        case "*":
            result = a * b
        case "/":
            result = a / b
        default:
            panic("unsupported operator:" + op)
    }
    return result
}
返回多个值
func div(a, b int) (int, int) {
    return a /b, a % b
}

func main() {
    fmt.Println(div(15, 2)) // 7 1
}
返回多个值的另一种写法
func div(a, b int) (q int, r int) {
    return a /b, a % b
}

func main() {
    q, r := div(15, 2)
    fmt.Println(q, r) // 7 1
}

注意:多返回值在Go中,一般用于第二个参数返回错误,否则基本都是返回一个值

如何在自己定义的函数中返回错误
func div(a, b int) (q int, err error) {
    return a /b, fmt.Errorf("this is a error message example")
}
如何接收函数返回的错误信息
func div(a, b int) (q int, err error) {
    return a /b, fmt.Errorf("this is a error message example")
}

func main() {
    res, err := div(15, 2)
    if err != nil {
        fmt.Println("Error:", err) // Error: this is a error message example
    } else {
        fmt.Println(res) // 7
    }
}
另一种接收函数错误信息的方式
func div(a, b int) (q int, err error) {
    return a /b, fmt.Errorf("this is a error message example")
}

func main() {
    if res, err := div(15, 2); err != nil {
        fmt.Println("Error:", err) // Error: this is a error message example
    } else {
        fmt.Println(res) // 7
    }
}
如何只接收返回值,不接收函数返回的错误信息
func div(a, b int) (q int, err error) {
    return a /b, fmt.Errorf("this is a error message example")
}

func main() {
    res, _ := div(15, 2)
    fmt.Println(res) // 7
}
函数语法注意点,可能后面会遇到:

一个函数可以返回多个值

函数也可以作为函数的参数

Go的函数定义中没有默认参数值这个概念

 

八、指针

package main

import "fmt"

func test() {
    // 定义一个变量
    var a = 2
    // 将变量pa的值定义为变量a的指针地址
    var pa = &a
    // 输出变量a,结果为2
    fmt.Println(a)
    // 输出变量pa,结果为0xc000018070,是一个指针地址
    fmt.Println(pa)
    // 输出*pa,*pa表示从指针地址处拿到对应的值,结果为2
    fmt.Println(*pa)
    // 如果这时改变*pa的值,也就相当于改变了地址0xc000018070对应的值,也就改变了变量a的值
    fmt.Println(a, pa, *pa) // 2 0xc000018070 2
}

func main() {
    test()
}

注意,Go语言中没有引用传递的概念,只有值传递和指针的概念,*a就表示变量a的指针